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,102 @@
<!DOCTYPE html>
<html>
<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/main.css" content="text/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></div>
<div></div>
<div></div>
<ul>
<a href="./index.html"><li>Home</li><div></div></a>
<a href="./projects.html"><li>Projects</li><div></div></a>
<a href="./contact.html"><li>Contact</li><div></div></a>
</ul>
</div>
<!-- Content of Top Bar -->
<div id="top-content">
<!-- Title Header -->
<div id="title-header">
<header>
<h1>George Wilkinson</h1>
<h2>Contact Me</h2>
</header>
</div>
</div>
</div>
<!-- Content Start -->
<div id="content">
<!-- About Me Card -->
<div class="card" id="contacts">
<div class="card-header">
<header><h2>Contact Links</h2></header>
</div>
<div class="card-content">
<ul id="contact-flex">
<a href="https://www.linkedin.com/in/george-wilkinson-509661249/"><li>LinkedIn</li></a>
<div class="flex-divider"></div>
<a href="mailto:G.Wilkinson2@edu.salford.ac.uk"><li>E-mail</li></a>
<div class="flex-divider"></div>
<a href="https://discord.com/invite/SaPudKa"><li>Discord: Boris#0355</li></a>
<a href=""><li></li></a>
</ul>
</div>
<div class="card-footer">
</div>
</div>
<!-- Card 2 -->
<div class="card" id="message">
<div class="card-header">
<header><h2>Leave a Message</h2></header>
</div>
<div class="card-content">
<form method="POST">
<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>
</div>
<!-- Content End -->
</body>
<footer>
<p>By George Wilkinson</p>
<p>Date Modified: Mon 6th Oct</p>
</footer>
</html>

View File

@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html>
<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/main.css" content="text/css">
<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">
<div></div>
<div></div>
<div></div>
<ul>
<a href="./index.html"><li>Home</li><div></div></a>
<a href="./projects.html"><li>Projects</li><div></div></a>
<a href="./contact.html"><li>Contact</li><div></div></a>
</ul>
</div>
<!-- Content of Top Bar -->
<div id="top-content">
<!-- Title Header -->
<div id="title-header">
<header><h1>George Wilkinson</h1></header>
</div>
</div>
</div>
<!-- Content Start -->
<div id="content">
<!-- About Me Card -->
<div class="card" id="about">
<div class="card-header">
<header><h2>About Me</h2></header>
</div>
<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>
<div 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>
</div>
</div>
<!-- Card 2 -->
<div class="card" id="project-ov">
<div class="card-header">
<header><h2>Current Projects</h2></header>
</div>
<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>
</div>
<!-- Content End -->
</body>
<footer>
<p>By George Wilkinson</p>
<p>Date Modified: Mon 6th Oct</p>
</footer>
</html>

View File

@@ -0,0 +1,221 @@
<!DOCTYPE html>
<html>
<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/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></div>
<div></div>
<div></div>
<ul>
<a href="./index.html"><li>Home</li><div></div></a>
<a href="./projects.html"><li>Projects</li><div></div></a>
<a href="./contact.html"><li>Contact</li><div></div></a>
</ul>
</div>
<!-- Content of Top Bar -->
<div id="top-content">
<!-- Title Header -->
<div id="title-header">
<header>
<h1>George Wilkinson</h1>
<h2>Projects</h2>
</header>
</div>
</div>
</div>
<!-- Content Start -->
<div id="content">
<div class="card-divider" id="prox-header">
<h2>Main Proxmox Hypervisor Node</h2>
</div>
<div class="card" id="prox-build">
<div class="card-header">
<header>
<h3>Building</h3>
</header>
</div>
<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>
<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>
<div class="card" id="prox-storage">
<div class="card-header">
<header><h2>Storage</h2></header>
</div>
<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 3 -->
<div class="card" id="prox-features">
<div class="card-header">
<header><h2>VM List</h2></header>
</div>
<div class="card-content">
<p>
<ul id="vm-list">
<li><section class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-01" />
<label for="vm-01">OpenMediaVault ( OMV )</label>
<section 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>
</section>
</section></li>
<li><section class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-02" />
<label for="vm-02">Ubuntu Server ( Docker )</label>
<section 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
<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>
</p>
</section>
</section></li>
<li><section class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-03" />
<label for="vm-03">Home Assistant OS</label>
<section 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>
</section>
</section></li>
<li><section class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-04" />
<label for="vm-04">Proxmox Backup Server ( PBS ) ( In Progress )</label>
<section 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>
</section>
</section></li>
<li><section class="collapse-list">
<input type="checkbox" name="collapse-list-item" id="vm-05" />
<label for="vm-05">Windows Server 2019</label>
<section 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>
</section>
</section></li>
</ul>
</p>
</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>
</div>
</div>
</div>
<!-- Content End -->
</body>
<footer>
<p>By George Wilkinson</p>
<p>Date Modified: Fri 24th Nov</p>
</footer>
</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,73 @@
@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: #2e3440;
color: #eceff4;
border: 2px solid #3b425266;
box-shadow: 0 2px 5px 0 #2e3440;
}
#submit:hover {
background-color: #4c566a;
}
.flex-divider {
background-color: #2e3440;
}
}
#contact-flex {
text-align: center;
padding: 0 10px 0 10px;
}
#contact-flex a {
text-decoration: none;
list-style-type: none;
}
.flex-divider {
width: 60%;
height: 1px;
margin: 5% auto 5% auto;
}
input, textarea {
align-content: center;
width: 80%;
max-width: 80%;
min-width: 80%;
margin: auto;
border-radius: 0.7em;
padding: 0 0.5em;
height: fit-content;
}
#submit {
width: fit-content !important;
min-width: none;
max-width: none;
}
#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,324 @@
:root {
color-scheme: light;
font-family:'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #4c566a;
color: #eceff4;
}
* :link {
color: #aab;
}
#toggle-navbar li, .card, .card-divider, .collapse-list label {
border: 2px solid #3b425266;
background-color: #434c5e;
box-shadow: 0 2px 5px 0 #2e3440;
}
#toggle-navbar li:hover {
background-color: #4c566a;
}
#toggle-navbar a:link, a:visited, a:focus {
color: white;
}
#toggle-navbar div {
background: #88c0d0;
}
ul li div {
background-color: #2e3440;
}
#toggle-navbar li ~ 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 li, .card, .card-divider, .collapse-list label {
border: 2px solid #4c566a;
background-color: #d8dee9;
box-shadow: 0 2px 5px 0 #434c5e;
}
#toggle-navbar li:hover {
background-color: #eeeeff;
}
#toggle-navbar a:link, a:visited, a:focus {
color: black;
}
#toggle-navbar div {
background: #5e81ac;
}
#toggle-navbar li ~ div {
box-shadow: none !important;
}
.collapse-list label:hover,
.collapse-list label:focus {
background: #eeeeff;
}
}
body {
width: 100%;
height: auto;
overflow: scroll;
margin: 0;
}
#main {
width: 100%;
margin: 0;
display: flex;
flex-direction: column;
row-gap: 10vh;
height: 100%;
margin-top: 5vh;
}
#top-bar {
height: fit-content;
max-height: 20%;
align-items: center;
display: flex;
gap: 2vw;
flex-direction: column;
flex-wrap: nowrap;
width: 100%;
margin: auto;
position: relative;
top: 0px;
min-height: 15vh;
max-height: 25vh;
}
#title-header {
display: inline;
margin: auto;
}
header {
text-align: center;
}
header h1 {
display: block;
font-size: 4vh;
margin: 0px;
}
#top-content {
display: flex;
flex-wrap: wrap;
gap: -1em;
padding: 0;
margin: 0;
}
#toggle-navbar {
display: inline;
position: relative;
height: auto;
z-index: 1;
margin-right: auto;
margin-left: 5vw;
width: fit-content;
}
#toggle-navbar li:hover ~ div {
transform: scaleX(250%);
transform-origin: 0% 0%;
transition: transform 1s cubic-bezier(0.1,-0.1,0.02,1.8);
transition-duration: 1s;
}
#toggle-navbar li: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 a {
outline: none;
transition: color 0.3s ease;
display: flex;
flex-direction: column;
gap: 0px;
padding: 4px;
height: fit-content;
line-height: 3rem;
text-decoration: none;
width: fit-content;
margin: 15px 0 15px 0;
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-bottom: 5px;
margin-left: 5px;
position: relative;
border-radius: 3px;
z-index: 1;
}
#toggle-navbar li ~ div {
max-width: 90% !important;
min-width: 10% !important;
bottom: 5px;
left: -1px;
}
#toggle-navbar ul {
display: flex;
flex-direction: row;
gap: 1.1em;
position: relative;
margin-top: 1.5em;
padding: 0;
list-style-type: none;
transform-origin: 0% 0%;
transform: translate(0, -600%);
transition: transform 0.5s cubic-bezier(0.77,-0.2,0.02,1.2);
}
#toggle-navbar li
{
padding: 10px 0;
font-size: 2.25vh;
width: 10vh;
border-radius: 0.5em;
padding: 0.4vh 1.1vw 0.4vh 1.1vw;
}
#toggle-navbar input:checked ~ ul
{
transform: none;
}
#toggle-navbar a:active {
cursor: default;
}
footer {
height: 3em;
width: 100%;
font-size: 75%;
width: 100%;
position: fixed;
bottom: 0px;
left: 0px;
display: flex;
gap: 2em;
margin: 3px 10px;
}
footer p {
display: inline;
}
#content {
display: flex;
flex-wrap: wrap;
row-gap: 10px;
column-gap: 2em;
justify-content: center;
height: fit-content;
}
#content h2 {
text-align: start;
}
.card-divider {
border-radius: 1rem;
display: block;
padding: 1% 1% 1% 1%;
max-width: 80%;
margin: 0.5em;
min-width: 80%;
line-height: 1rem;
}
.card {
border-radius: 1rem;
display: block;
padding: 2% 2% 2% 2%;
max-width: 15vw;
flex-basis: 50%;
margin: 0.5em;
min-width: 15em;
height: fit-content;
}
.card > * {
flex: 1 1 auto;
}
.card header {
display: inline-block;
margin: 1em auto;
width: 100%;
}
.card header h2 {
margin: auto;
width: fit-content;
text-align: center;
}
.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;
}

View File

@@ -0,0 +1,71 @@
.card {
max-width: 40vw !important;
}
#card-content {
display: flex;
gap: 1em;
}
img {
max-width: 100%;
height: auto;
border-radius: 1rem;
}
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;
transition: height 0.3s ease;
}
.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;
}
.collapse-list p:last-child {
margin-bottom: 0;
}
#container-list li {
padding-bottom: 1em;
}