first commit

This commit is contained in:
Boris
2024-01-15 20:14:10 +00:00
commit 8c81ee28b7
3106 changed files with 474415 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Contact Me</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="author" content="George Wilkinson">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="default-style" content="./src/styles/style.css">
<link rel="stylesheet" href="./src/styles/index.css" content="text/css">
<link rel="stylesheet" href="./src/styles/contact.css" content="text/css">
</head>
<body>
<!-- Main Content-->
<div id="main">
<!-- Top Bar -->
<div id="top-bar">
<!-- Nav Bar -->
<div id="toggle-navbar">
<input type="checkbox">
<div class="hamburger-division"></div>
<div class="hamburger-division"></div>
<div class="hamburger-division"></div>
<ul>
<li><a href="./index.html">Home<div></div></a></li>
<li><a href="./projects.html">Projects<div></div></a></li>
<li><a href="./contact.html">Contact<div></div></a></li>
</ul>
</div>
<!-- Title Header -->
<section id="title-header">
<header>
<h1>George Wilkinson</h1>
<h3>Contact Me</h3>
</header>
</section>
</div>
<!-- Content Start -->
<div id="content">
<!-- About Me Card -->
<div class="card" id="contacts">
<section class="card-header">
<header><h2>Contact Links</h2></header>
</section>
<div class="card-content">
<ul id="contact-flex">
<li><a href="https://www.linkedin.com/in/george-wilkinson-509661249/">LinkedIn</a></li>
<li class="flex-divider"></li>
<li><a href="mailto:G.Wilkinson2@edu.salford.ac.uk">E-mail</a></li>
<li class="flex-divider"></li>
<li><a href="https://discord.com/invite/SaPudKa">Discord: Boris#0355</a></li>
</ul>
</div>
<div class="card-footer">
</div>
</div>
<!-- Card 2 -->
<div class="card" id="message">
<section class="card-header">
<header><h2>Leave a Message</h2></header>
</section>
<div class="card-content">
<form action="mailto:G.Wilkinson2@edu.salford.ac.uk" method="POST" enctype="text/plain">
<input type="text" id="name" name="Name" placeholder="Full Name" minlength="2">
<input type="email" id="email" name="Email" placeholder="E-mail Address" minlength="4">
<textarea id="message-content" name="Message Content"></textarea>
<input type="submit" id="submit" value="Submit">
</form>
</div>
<div class="card-footer">
</div>
</div>
</div>
</div>
<footer>
<p>By George Wilkinson</p>
<p>Date Modified: Mon 4th Dec</p>
</footer>
</body>
</html>

View File

@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>George's Portfolio</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="author" content="George Wilkinson">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="default-style" content="./src/styles/style.css">
<meta http-equiv="Content-Security-Policy" content="default-src 'self';">
<link rel="stylesheet" href="./src/styles/index.css" content="text/css">
</head>
<body>
<!-- Main Content-->
<div id="main">
<!-- Top Bar -->
<div id="top-bar">
<!-- Nav Bar -->
<div id="toggle-navbar">
<input type="checkbox" id="hamburger-box">
<div class="hamburger-division"></div>
<div class="hamburger-division"></div>
<div class="hamburger-division"></div>
<ul>
<li><a href="./index.html">Home<div></div></a></li>
<li><a href="./projects.html">Projects<div></div></a></li>
<li><a href="./contact.html">Contact<div></div></a></li>
</ul>
</div>
<!-- Title Header -->
<section id="title-header">
<header>
<h1>George Wilkinson</h1>
</header>
</section>
</div>
<!-- Content Start -->
<div id="content">
<!-- About Me Card -->
<div class="card" id="about">
<section class="card-header">
<header><h2>About Me</h2></header>
</section>
<div class="card-content">
<p>Computer Science with Cyber Security Student, at the <a href="https://salford.ac.uk">University of Salford</a> </p>
</div>
<footer class="card-footer">
<ul>
<li><a href="https://www.linkedin.com/in/george-wilkinson-509661249/">LinkedIn</a></li>
<li><a href="mailto:G.Wilkinson@edu.salford.ac.uk">E-mail</a></li>
<li><a href="./contact.html">More</a></li>
</ul>
</footer>
</div>
<!-- Card 2 -->
<div class="card" id="project-ov">
<section class="card-header">
<header><h2>Current Projects</h2></header>
</section>
<div class="card-content">
<ul>
<li>Using Proxmox to create an efficient Virtual Environment</li>
<li>Dockerised NGINX WebServer running under Ubuntu in Proxmox</li>
<li>Virtualised Home Assistant Automation</li>
<li>Using Machine Learning with Frigate to enable home CCTV</li>
</ul>
</div>
<div class="card-footer">
<ul>
<li><a href="./projects.html">More Detail</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- Content End -->
<footer>
<p>By George Wilkinson</p>
<p>Date Modified: Mon 4th Dec</p>
</footer>
</body>
</html>

View File

@@ -0,0 +1,226 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Projects</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="author" content="George Wilkinson">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="default-style" content="./src/styles/style.css">
<link rel="stylesheet" href="./src/styles/index.css" content="text/css">
<link rel="stylesheet" href="./src/styles/projects.css" content="text/css">
</head>
<body>
<!-- Main Content-->
<div id="main">
<!-- Top Bar -->
<div id="top-bar">
<!-- Nav Bar -->
<div id="toggle-navbar">
<input type="checkbox">
<div class="hamburger-division"></div>
<div class="hamburger-division"></div>
<div class="hamburger-division"></div>
<ul>
<li><a href="./index.html">Home<div></div></a></li>
<li><a href="./projects.html">Projects<div></div></a></li>
<li><a href="./contact.html">Contact<div></div></a></li>
</ul>
</div>
<!-- Content of Top Bar -->
<div id="top-content">
<!-- Title Header -->
<section id="title-header">
<header>
<h1>George Wilkinson</h1>
<h3>Projects</h3>
</header>
</section>
</div>
</div>
<!-- Content Start -->
<div id="content">
<!-- Card Divider / Header -->
<div class="card-divider" id="prox-header">
<h2>Main Proxmox Hypervisor Node</h2>
</div>
<!-- Card 1 Start -->
<div class="card" id="prox-build">
<section class="card-header">
<header>
<h3>Building</h3>
</header>
</section>
<div class="card-content">
<p>
My main proxmox node is currently my largest project to date. I needed bulk network storage and local hypervisor compute
that was low power, cost effective, and quiet. I chose to build on a consumer platform with an enterprise chassis,
so I would have the best of both worlds for efficiency, form factor and cooling. Built on the last generation of
the AM4 platform, I was able to build the compute end of the project for about £320. This included a
<a href="https://www.amd.com/en/products/apu/amd-ryzen-7-5700g">Ryzen 5700G</a>,
<a href="https://www.asrock.com/mb/AMD/B550%20Pro4/index.asp">ASRock B550</a>,
<a href="https://www.corsair.com/uk/en/c/memory/ddr4-ram">2x32GB + 2x16GB Corsair DDR4</a> and a
<a href="https://noctua.at/en/nh-l9a-am4">Noctua L9a</a>. For the chassis, I ended up using a
<a href="https://www.supermicro.com/products/chassis/2U/?chs=825">SuperMicro CSE-825</a>, which is
compatible with full-size ATX consumer board sizes, and has 8x3.5" hot-swap drive bays. The final piece of the project
was storage - I needed a large amount of redundant storage with fast reads, something that isn't usually cheap. I
managed to pick up 10 4TB
<a href="https://documents.westerndigital.com/content/dam/doc-library/en_us/assets/public/western-digital/product/data-center-drives/ultrastar-sata-series/data-sheet-ultrastar-7k4000.pdf">HGST SAS drives</a>
from an e-waste company with around 50k hours on each drive. Since my chassis can hold 8 at a time, this leaves me
with 2 cold spares if any choose to fail. At the same time I bought a 2 port Mini-SAS 8087
<a href="https://docs.broadcom.com/doc/12353331">LSI 9207-8i PCIe HBA</a> to connect the chassis backplane to my motherboard. On top
of this hardware, I of course chose to use <a href="https://proxmox.com">Proxmox</a>, as it is a FOSS
operating system and supports ZFS natively, unlike some alternatives like <a href="https://www.vmware.com/uk/products/esxi-and-esx.html">EXSi</a>.
</p>
</div>
<div class="card-footer" style="flex-direction: column;">
<figure>
<a target="_blank" href="./src/images/proxmox-01.jpg"><img src="./src/images/proxmox-01.jpg" alt="Server Internals"></a>
<figcaption>fig 1. Completed Build in the rack</figcaption>
</figure>
</div>
</div>
<!-- Card 1 End -->
<!-- Card 2 Start -->
<div class="card" id="prox-storage">
<section class="card-header">
<header><h2>Storage</h2></header>
</section>
<div class="card-content">
<p>Set up in a ZFS Striped Mirror array, I achieve 16TB of usable space out of 32TB, with 1-4 drive failure depending
on which drive fails. 50% usable space is quite the loss, but all the negatives of decreased space are made up by
the massive random IO/s increases, giving me much higher performance for cloud storage and app performance. To give some
reference, the highest speed I have seen is 1.6GB/s (12800Mbps), around 180x the average residential UK download speed
( according to Virgin Media: <a href="https://www.virginmedia.com/blog/broadband/average-broadband-speed">Here</a> ).
</p>
</div>
<div class="card-footer">
<figure>
<a target="_blank" href="./src/images/proxmox-02.jpg"><img src="./src/images/proxmox-02.jpg" alt="Proxmox Host Array"></a>
<a target="_blank" href="./src/images/proxmox-03.jpg"><img src="./src/images/proxmox-03.jpg" alt="Proxmox Host Storage"></a>
<figcaption>fig 2. ZFS Striped Mirror Array. fig 3. Storage Displayed in Panel.</figcaption>
</figure>
</div>
</div>
<!-- Card 2 End -->
<!-- Card 3 Start -->
<div class="card" id="prox-features">
<section class="card-header">
<header><h2>VM List</h2></header>
</section>
<div class="card-content">
<ul id="vm-list">
<li>
<div class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-01" >
<label for="vm-01">OpenMediaVault ( OMV )</label>
<div class="collapse-list-content">
<h5>4CPU, 8GB RAM</h5>
<p>Under OMV, I import a virtual disk for network attached storage. This is used by other servers and clients
in my house, and in some cases outside of my house. This is due to Proxmox having a less than ideal solution
to network sharing, and can cause instability. OMV has a clean network GUI where I can configure network shares
and expand their size on the fly, which is useful in a dynamic environment like this.
</p>
</div>
</div>
</li>
<li>
<div class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-02" >
<label for="vm-02">Ubuntu Server ( Docker )</label>
<div class="collapse-list-content">
<h5>4CPU, 30GB RAM</h5>
<p>Under this Ubuntu VM, I run a single node Docker stack for ~50 containers, including</p>
<ul id="container-list">
<li>NGINX WebServer & Proxy Manager<br>For hosting web applications through a reverse proxy at a datacentre.</li>
<li>Authentik<br>Provides Proxy, OAuth2 and LDAP configuration for web applications.</li>
<li>Gitea<br>Hosts a personal Git repository for projects.</li>
<li>Grafana & InfluxDB<br>Provides real-time monitoring and logging of device metrics.</li>
<li>Immich<br>Google Photos alternative, entirely self-hosted and open source.</li>
<li>IPv6NAT<br>Provides an address translation service to allow for a fully IPv6 docker stack.</li>
<li>VaultWarden<br>Fully self-hosted, lightweight password manager.</li>
</ul>
</div>
</div>
</li>
<li>
<div class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-03" >
<label for="vm-03">Home Assistant OS</label>
<div class="collapse-list-content">
<h5>2CPU, 4GB RAM</h5>
<p>With HaOS, I have set up integrations with several IoT devices on my network, such as TP-Link Tapo bulbs, light strips, etc.
I am also working on integration with Grafana, Frigate & CCTV cameras to provide a centralised app to control & monitor
smart home devices. I used to run Home Assistant dockerised on my Docker VM, but I found the VM was much better supported
and stable.
</p>
</div>
</div>
</li>
<li>
<div class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-04" >
<label for="vm-04">Proxmox Backup Server ( PBS ) ( In Progress )</label>
<div class="collapse-list-content">
<h5>1CPU, 4GB RAM</h5>
<p>While I already backup my Virtual Machines to an external server, using some storage on a friend's Proxmox node,
using PBS locally, I can backup & snapshot my Virtual Machines to a different drive on my machine. This isn't ideal from
a 3-2-1 perspective but having frequent local rolling backups can be incredibly useful if anything were to go wrong inside
the VM itself. I am currently working on implementing a good local storage solution to store my images, so for now it is
turned off.
</p>
</div>
</div>
</li>
<li>
<div class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-05" >
<label for="vm-05">Windows Server 2019</label>
<div class="collapse-list-content">
<h5>4CPU, 4GB RAM</h5>
<p>
Using an evaluation release of Windows Server, I use this to perform any operations / run any programs needed on this node
that cannot be done on linux. This is rare, but useful when required. I have also used this in the past to have a graphical
Windows environment outside of my network to configure network settings, since my Proxmox panel is behind a reverse proxy.
</p>
</div>
</div>
</li>
</ul>
</div>
<div class="card-footer">
<figure>
<a target="_blank" href="./src/images/proxmox-04.jpg"><img src="./src/images/proxmox-04.jpg" alt="Proxmox Host Panel"></a>
<figcaption>fig 4. VM List & Host Summary in Panel.</figcaption>
</figure>
</div>
</div>
<!-- Card 3 End -->
</div>
<!-- Content End -->
</div>
<footer>
<p>By George Wilkinson</p>
<p>Date Modified: Mon 4th Dec</p>
</footer>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,71 @@
@media ( prefers-color-scheme: dark ) {
input, textarea {
background-color: #2e3440;
color: #eceff4;
border: 2px solid #3b425266;
box-shadow: 0 2px 5px 0 #2e3440;
}
#submit:hover {
background-color: #4c566a;
}
.flex-divider {
background-color: #eceff4;
}
}
@media ( prefers-color-scheme: light ) {
input, textarea {
background-color: #d8dee9;
color: black;
border: 2px solid #7f899d;
box-shadow: 0 1px 2px 0 #545d6f;
}
#submit:hover {
background-color: #eeeeff;
}
.flex-divider {
background-color: black;
}
}
#contact-flex {
text-align: center;
padding: 0 10px 0 10px;
list-style-type: none;
}
#contact-flex li {
list-style-type: none;
text-decoration: none;
}
.flex-divider {
width: 60%;
height: 1px;
margin: 5% auto 5% auto;
}
.card-content input, .card-content textarea {
align-content: center;
max-width: 80%;
min-width: 80%;
margin: auto;
border-radius: 0.7em;
padding: 0 0.5em;
height: fit-content;
}
#submit {
width: fit-content !important;
}
#submit:hover {
transform: scale(1.05) !important;
transition: transform 0.75s cubic-bezier(0.1,-0.2,0.05,1.2);
transition-duration: 0.75s;
}
form {
display: flex;
flex-direction: column;
gap: 0.5em;
}

View File

@@ -0,0 +1,352 @@
:root {
color-scheme: light;
font-family:'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
}
html, body {
min-height: 100% !important;
width: 100%;
position: absolute;
margin: 0;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #4c566a;
color: #eceff4;
}
* :link {
color: #aab;
}
#toggle-navbar a, .card, .card-divider, .collapse-list label {
border: 2px solid #3b425266;
background-color: #434c5e;
box-shadow: 0 2px 5px 0 #2e3440;
}
#toggle-navbar a:hover {
background-color: #4c566a;
}
a, a:link, a:visited, a:focus {
color: #ddddff;
}
#toggle-navbar a:link, a:visited, a:focus {
color: white;
}
#toggle-navbar div {
background: #88c0d0;
}
ul a div {
background-color: #2e3440;
}
#toggle-navbar a ~ div {
box-shadow: 0 0 5px 5px #434c5e;
}
.collapse-list label:hover,
.collapse-list label:focus {
background: #4c566a;
}
}
@media (prefers-color-scheme: light) {
body {
background-color: #e5e9f0;
color: #2e3440;
}
* :link {
color: #5e81ac;
}
#toggle-navbar a, .card, .card-divider, .collapse-list label {
border: 2px solid #7f899d;
background-color: #d8dee9;
box-shadow: 0 1px 2px 0 #545d6f;
}
#toggle-navbar a:hover {
background-color: #eeeeff;
}
a, a:link, a:visited, a:focus {
color: #111133;
}
#toggle-navbar a:link, a:visited, a:focus {
color: black;
}
#toggle-navbar div {
background: #5e81ac;
}
#toggle-navbar a ~ div {
box-shadow: none !important;
}
.collapse-list label:hover,
.collapse-list label:focus {
background: #eeeeff;
}
}
footer {
height: 3em;
width: 100%;
font-size: 75%;
position: absolute;
bottom: 0px;
left: 0px;
display: flex;
gap: 2em;
margin: 3px 10px;
}
footer p {
display: inline;
}
.card {
border-radius: 1rem;
padding: 2%;
margin: 0.5em;
height: fit-content;
}
.card header {
display: inline-block;
margin: 1em auto;
width: 100%;
}
.card header h2 {
margin: auto;
width: fit-content;
text-align: center;
}
.card footer {
font-size: 1rem;
}
#main {
width: 100%;
margin: 0;
display: block;
height: 100%;
}
#top-bar {
display: block;
width: 100%;
margin: 10px auto;
position: relative;
top: 0px;
height: 25%
}
#content {
display: flex;
flex-wrap: wrap;
row-gap: 10px;
column-gap: 2em;
justify-content: center;
height: 75%;
overflow: auto;
margin-top: 5vh;
padding-bottom: 40px;
}
#title-header {
display: block;
margin: auto;
margin-top: 6vh;
}
header {
text-align: center;
}
header h1 {
display: block;
margin: 0px;
}
#toggle-navbar {
display: block;
position: relative;
height: auto;
z-index: 1;
margin: auto;
margin-top: 5vw;
width: 90%;
}
#toggle-navbar a:hover > div {
transform: scaleX(2.5);
transform-origin: 0% 0%;
transition: transform 1s ease;
transition-duration: 1s;
}
#toggle-navbar a:hover {
transform: scale(1.03) !important;
transition: transform 0.5s cubic-bezier(0.1,-0.2,0.05,1.2);
transition-duration: 0.5s;
}
#toggle-navbar li {
outline: none;
transition: color 0.3s ease;
display: flex;
flex-direction: column;
gap: 0px;
padding: 6px;
height: fit-content;
line-height: 2rem;
width: 75%;
margin-top: 5px;
text-align: center;
overflow: hidden;
}
#toggle-navbar input {
display: block;
width: 40px;
height: 32px;
position: absolute;
margin-bottom: 5px;
cursor: pointer;
opacity: 0;
z-index: 2;
}
#toggle-navbar div {
display: block;
width: 33px;
height: 4px;
margin-left: 5px;
position: relative;
border-radius: 3px;
z-index: 1;
}
.hamburger-division {
margin-bottom: 5px;
}
#toggle-navbar a ~ div {
max-width: 90% !important;
min-width: 10% !important;
bottom: 5px;
left: -1px;
}
#toggle-navbar ul {
display: flex;
flex-direction: row;
gap: 0.8em;
position: relative;
width: 100%;
margin: 10px auto;
padding: 0;
list-style-type: none;
transform-origin: 0% 0%;
transform: translate(0, -400%);
transition: transform 0.5s cubic-bezier(0.77,-0.2,0.02,1.2);
}
#toggle-navbar a
{
width: 100%;
border-radius: 0.5em;
text-decoration: none;
}
#toggle-navbar input:checked ~ ul
{
transform: none;
}
#toggle-navbar a:active {
cursor: default;
}
.card-divider {
border-radius: 1rem;
display: block;
padding: 1% 1% 1% 5%;
max-width: 80vw;
margin: 0.5em;
min-width: 80%;
line-height: 2rem;
max-height: 10rem;
}
.card-content {
height: 65%;
}
.card-footer {
position: relative;
justify-content: space-between;
display: flex;
flex-direction: row;
bottom: 0px;
margin: auto;
min-height: 10%;
}
.card-footer ul {
margin: auto;
display: flex;
gap: 1em;
padding: 0;
list-style-type: none;
}
.card-footer li, .card-footer a {
text-decoration: none;
}
.card:hover {
transform: scale(1.01);
transition-duration: 0.2s;
transform-box: border-box;
}
/* Desktop */
@media screen and (min-width: 1024px) {
.card {
min-width: 20vw;
max-width: 20vw;
}
#toggle-navbar li {
width: 10vw;
}
}
/* For Tablet View */
@media screen and (min-width: 768px) and (max-width: 1024px) {
.card {
min-width: 50vw;
max-width: 50vw;
}
}
/* Mobile Portrait */
@media screen and (max-width: 480px) and (orientation: portrait) {
.card {
min-width: 85vw;
max-width: 85vw;
}
#toggle-navbar a {
font-size: 3.5vw;
}
}
/* Mobile Landscape */
@media screen and (max-width: 1024px) and (orientation: landscape) {
.card {
min-width: 50vw;
max-width: 50vw;
}
#top-bar {
height: 10%;
}
#content {
height: 90%;
}
}

View File

@@ -0,0 +1,67 @@
.card {
max-width: 40vw !important;
}
#card-content {
display: flex;
gap: 1em;
}
img {
max-width: 100%;
height: auto;
border-radius: 1rem;
margin: auto;
}
figure {
width: 100%;
margin: auto;
margin-top: 1em;
}
figcaption {
margin: auto;
font-size: 0.75rem;
width: fit-content;
}
#vm-list {
text-decoration: none;
list-style-type: none;
padding: 0;
}
.collapse-list > input[type="checkbox"] {
position: absolute;
left: -100vw;
}
.collapse-list .collapse-list-content {
overflow-y: hidden;
height: 0;
}
.collapse-list > input[type="checkbox"]:checked ~ .collapse-list-content {
height: auto;
overflow: visible;
}
.collapse-list {
margin-bottom: 1em;
}
.collapse-list label {
cursor: pointer;
font-weight: normal;
padding: 15px;
margin: 0;
font-size: 1.125em;
line-height: 1.2em;
border-radius: 1rem;
display: block;
}
#container-list li {
padding-bottom: 1em;
}