@@ -1,5 +1,11 @@
|
|||||||
+++
|
+++
|
||||||
date = '{{ .Date }}'
|
|
||||||
draft = true
|
|
||||||
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||||
|
date = "{{ .Date }}"
|
||||||
|
draft = false
|
||||||
|
summary = ""
|
||||||
|
tags = []
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = ""
|
||||||
|
caption = ""
|
||||||
+++
|
+++
|
||||||
|
10
archetypes/photos.md
Normal file
10
archetypes/photos.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||||
|
date = "{{ .Date }}"
|
||||||
|
draft = false
|
||||||
|
tags = []
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = ""
|
||||||
|
exif = true
|
||||||
|
+++
|
5
content/photos/_index.md
Normal file
5
content/photos/_index.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
+++
|
||||||
|
title = "Posts"
|
||||||
|
details = false
|
||||||
|
type = "gallery"
|
||||||
|
+++
|
BIN
content/photos/bridge/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/bridge/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/bridge/index.md
Normal file
10
content/photos/bridge/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Bridge"
|
||||||
|
date = 2025-04-11T17:45:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Street", "Sunset", "Silhouettes"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/buile-hill-fireworks/0.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/buile-hill-fireworks/0.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/photos/buile-hill-fireworks/1.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/buile-hill-fireworks/1.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/photos/buile-hill-fireworks/2.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/buile-hill-fireworks/2.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/photos/buile-hill-fireworks/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/buile-hill-fireworks/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
16
content/photos/buile-hill-fireworks/index.md
Normal file
16
content/photos/buile-hill-fireworks/index.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
+++
|
||||||
|
title = "Buile Hill Fireworks"
|
||||||
|
date = 2024-11-02T18:38:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Fireworks", "Night", "Collection"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
||||||
|
|
||||||
|
{{< exif-image 0.jpg >}}
|
||||||
|
|
||||||
|
{{< exif-image 1.jpg >}}
|
||||||
|
|
||||||
|
{{< exif-image 2.jpg >}}
|
BIN
content/photos/empire-exchange/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/empire-exchange/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/empire-exchange/index.md
Normal file
10
content/photos/empire-exchange/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Empire Exchange"
|
||||||
|
date = 2024-10-13T12:18:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Street", "Storefront"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/focus-on-sight/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/focus-on-sight/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/focus-on-sight/index.md
Normal file
10
content/photos/focus-on-sight/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Focus on Sight"
|
||||||
|
date = 2024-10-17T12:19:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Murals"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/fogbound/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/fogbound/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/fogbound/index.md
Normal file
10
content/photos/fogbound/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Fogbound"
|
||||||
|
date = 2024-10-30T11:32:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Architecture", "Fog"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/futuristic-space-funk/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/futuristic-space-funk/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/futuristic-space-funk/index.md
Normal file
10
content/photos/futuristic-space-funk/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Futuristic Space Funk"
|
||||||
|
date = 2024-10-22T11:33:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Murals"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/rush-hour/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/rush-hour/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/rush-hour/index.md
Normal file
10
content/photos/rush-hour/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Rush Hour"
|
||||||
|
date = 2025-04-09T19:00:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Street", "Sunset", "Silhouettes"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/sticker-city/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/sticker-city/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/sticker-city/index.md
Normal file
10
content/photos/sticker-city/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Sticker City"
|
||||||
|
date = 2024-10-22T11:37:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Graffiti", "Street"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/suspended/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/suspended/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/suspended/index.md
Normal file
10
content/photos/suspended/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Suspended"
|
||||||
|
date = 2024-10-13T12:55:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Street", "Architecture"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/the-campus/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/the-campus/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/the-campus/index.md
Normal file
10
content/photos/the-campus/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "The Campus"
|
||||||
|
date = 2024-10-17T12:53:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Architecture", "Street"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/the-cook/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/the-cook/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/the-cook/index.md
Normal file
10
content/photos/the-cook/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "The Cook"
|
||||||
|
date = 2024-12-19T19:14:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Candid", "Street", "Night"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/the-engineering-building/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/the-engineering-building/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/the-engineering-building/index.md
Normal file
10
content/photos/the-engineering-building/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "The Engineering Building"
|
||||||
|
date = 2024-10-17T12:36:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Architecture"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/the-protest/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/the-protest/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/the-protest/index.md
Normal file
10
content/photos/the-protest/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "The Protest"
|
||||||
|
date = 2024-11-16T15:28:00Z
|
||||||
|
draft = true
|
||||||
|
tags = ["Protest", "Street"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/the-stairwell/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/the-stairwell/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/the-stairwell/index.md
Normal file
10
content/photos/the-stairwell/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "The Stairwell"
|
||||||
|
date = 2024-12-19T19:04:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Abstract", "Night", "Silhouettes"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/the-watcher/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/the-watcher/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/the-watcher/index.md
Normal file
10
content/photos/the-watcher/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "The Watcher"
|
||||||
|
date = 2024-11-26T19:00:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Candid", "Street", "Night"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/the-window/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/the-window/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/the-window/index.md
Normal file
10
content/photos/the-window/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "The Window"
|
||||||
|
date = 2024-11-26T18:30:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Night", "Abstract", "Silhouettes"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/two-photographers-walk-into-a-frame/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/two-photographers-walk-into-a-frame/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/two-photographers-walk-into-a-frame/index.md
Normal file
10
content/photos/two-photographers-walk-into-a-frame/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Two Photographers Walk into a Frame"
|
||||||
|
date = 2025-01-07T18:36:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Selfie", "Night", "Reflections"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/whitworth/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/whitworth/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/whitworth/index.md
Normal file
10
content/photos/whitworth/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Whitworth"
|
||||||
|
date = 2024-10-17T13:14:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Street", "Architecture"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
BIN
content/photos/window-selfie/hero.jpg
(Stored with Git LFS)
Normal file
BIN
content/photos/window-selfie/hero.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
10
content/photos/window-selfie/index.md
Normal file
10
content/photos/window-selfie/index.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
+++
|
||||||
|
title = "Window Selfie"
|
||||||
|
date = 2024-10-22T11:41:00Z
|
||||||
|
draft = false
|
||||||
|
tags = ["Selfie", "Reflections"]
|
||||||
|
|
||||||
|
[hero]
|
||||||
|
src = "hero.jpg"
|
||||||
|
exif = true
|
||||||
|
+++
|
@@ -105,7 +105,7 @@ For my system I have 3 drives in total formatted as `ext4`, excluding the boot d
|
|||||||
- WD Red 4TB 5400 RPM HDD - `/mnt/disk2` - Part of storage pool
|
- WD Red 4TB 5400 RPM HDD - `/mnt/disk2` - Part of storage pool
|
||||||
- WD RED 4TB 5400 RPM HDD - `/mnt/parity1` - SnapRAID parity, you must use your largest drive for this
|
- WD RED 4TB 5400 RPM HDD - `/mnt/parity1` - SnapRAID parity, you must use your largest drive for this
|
||||||
|
|
||||||
The three main storage drives are then *pooled* into a new directory called `/mnt/storage` where all my files can be accessed from. `/mnt/storage` contains the following subdirectories:
|
The three main storage drives are then _pooled_ into a new directory called `/mnt/storage` where all my files can be accessed from. `/mnt/storage` contains the following subdirectories:
|
||||||
|
|
||||||
- `/public`: Public folder accessible by all users
|
- `/public`: Public folder accessible by all users
|
||||||
- `/public/media`: Media storage
|
- `/public/media`: Media storage
|
||||||
@@ -175,7 +175,6 @@ Keep in mind that using SnapRAID has a couple of caveats:
|
|||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ yay -S snapraid
|
$ yay -S snapraid
|
||||||
```
|
```
|
||||||
@@ -293,6 +292,6 @@ Just by installing and configuring these two tools, we have managed to satisfy t
|
|||||||
- Give your server a recognizable [hostname](https://wiki.archlinux.org/title/Network_configuration#Set_the_hostname) (in my case that's jupiter)
|
- Give your server a recognizable [hostname](https://wiki.archlinux.org/title/Network_configuration#Set_the_hostname) (in my case that's jupiter)
|
||||||
- Set up an SMTP client like [msmtp](https://wiki.archlinux.org/title/msmtp) so that your server can send you e-mail alerts
|
- Set up an SMTP client like [msmtp](https://wiki.archlinux.org/title/msmtp) so that your server can send you e-mail alerts
|
||||||
- Set up [S.M.A.R.T.](https://wiki.archlinux.org/title/S.M.A.R.T.) monitoring for your drives so that you get an early warning if one of your drives is about to fail.
|
- Set up [S.M.A.R.T.](https://wiki.archlinux.org/title/S.M.A.R.T.) monitoring for your drives so that you get an early warning if one of your drives is about to fail.
|
||||||
- Remember the rule known as *Schrödinger's Backup*: The condition of any backup is unknown until a restore is attempted. Therefore I recommend setting up another [backup solution](https://wiki.archlinux.org/title/System_backup) other than SnapRAID, just in case.
|
- Remember the rule known as _Schrödinger's Backup_: The condition of any backup is unknown until a restore is attempted. Therefore I recommend setting up another [backup solution](https://wiki.archlinux.org/title/System_backup) other than SnapRAID, just in case.
|
||||||
|
|
||||||
In the next part, we are going to be setting up Docker and Portainer for container management, Watchtower for automatic container updates, and OpenVPN for remote server management.
|
In the next part, we are going to be setting up Docker and Portainer for container management, Watchtower for automatic container updates, and OpenVPN for remote server management.
|
||||||
|
@@ -73,14 +73,14 @@ $ docker run -d --name=portainer \
|
|||||||
|
|
||||||
Here's a brief walkthrough of what each option does:
|
Here's a brief walkthrough of what each option does:
|
||||||
|
|
||||||
- `-d`: Run container in the background (detached)
|
- `-d`: Run container in the background (detached)
|
||||||
- `--name=portainer`: The name of the container
|
- `--name=portainer`: The name of the container
|
||||||
- `-e PGID=1000 and -e PUID=1000`: Set environmental variables PGID and PUID to 1000 (your user id, run id to check it)
|
- `-e PGID=1000 and -e PUID=1000`: Set environmental variables PGID and PUID to 1000 (your user id, run id to check it)
|
||||||
- `-p 8000:8000`: Expose port 8000 on the host and bind it to port 8000 in the container
|
- `-p 8000:8000`: Expose port 8000 on the host and bind it to port 8000 in the container
|
||||||
- `-p 9000:9000`: Same as above
|
- `-p 9000:9000`: Same as above
|
||||||
- `--restart=unless-stopped`: Automatically restart the container if it crashes or when the server boots
|
- `--restart=unless-stopped`: Automatically restart the container if it crashes or when the server boots
|
||||||
- `-v a:b`: Bind directory a on the host to directory b in the container
|
- `-v a:b`: Bind directory a on the host to directory b in the container
|
||||||
- `-v /var/run/docker.sock:/var/run/docker.sock`: Give Portainer access to the host's Docker socket
|
- `-v /var/run/docker.sock:/var/run/docker.sock`: Give Portainer access to the host's Docker socket
|
||||||
|
|
||||||
After running the command, you can access the web UI using a browser at `[local_server_ip]:9000`. In my case, that would be `192.168.1.254:9000`.
|
After running the command, you can access the web UI using a browser at `[local_server_ip]:9000`. In my case, that would be `192.168.1.254:9000`.
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ $ sudo setfacl -R -d -m g::rwx public
|
|||||||
$ sudo setfacl -R -d -m o::rwx public
|
$ sudo setfacl -R -d -m o::rwx public
|
||||||
```
|
```
|
||||||
|
|
||||||
Next, open Portainer, go to the *stacks* tab, and add a new stack named `samba`. In the `docker-compose` field, paste the following, and modify it to your liking:
|
Next, open Portainer, go to the _stacks_ tab, and add a new stack named `samba`. In the `docker-compose` field, paste the following, and modify it to your liking:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '3.9'
|
version: '3.9'
|
||||||
@@ -164,7 +164,7 @@ services:stacks*
|
|||||||
tty: true
|
tty: true
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information on what each option does, you can check the project's [repository](https://github.com/dperson/samba#configuration). After you are satisfied with your settings, click *deploy the stack*, wait a couple of seconds, and try accessing your new file share from a different computer.
|
For more information on what each option does, you can check the project's [repository](https://github.com/dperson/samba#configuration). After you are satisfied with your settings, click _deploy the stack_, wait a couple of seconds, and try accessing your new file share from a different computer.
|
||||||
|
|
||||||
## Final Thoughts
|
## Final Thoughts
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ By default, most routers use [DHCP](https://en.wikipedia.org/wiki/Dynamic_Host_C
|
|||||||
|
|
||||||
First, we need to find our server's MAC address. Open a terminal and run `ifconfig -a`. The network interface we care about should have a line starting with `ether`, `HWaddr`, or `lladdr`. If you have multiple network interfaces (both Ethernet and WiFI for example), you can run `ip route | grep default` to see which one you are using.
|
First, we need to find our server's MAC address. Open a terminal and run `ifconfig -a`. The network interface we care about should have a line starting with `ether`, `HWaddr`, or `lladdr`. If you have multiple network interfaces (both Ethernet and WiFI for example), you can run `ip route | grep default` to see which one you are using.
|
||||||
|
|
||||||
Then, open a browser and go to your router's settings by typing the address of its default gateway (the same address that you get when running `ip route | grep default`). You should have a section named *DHCP*, *Static leases* or something similar. There, you are going to add a new entry, set its IP to whatever you like (in my case `192.168.1.254`) and fill in the above MAC address.
|
Then, open a browser and go to your router's settings by typing the address of its default gateway (the same address that you get when running `ip route | grep default`). You should have a section named _DHCP_, _Static leases_ or something similar. There, you are going to add a new entry, set its IP to whatever you like (in my case `192.168.1.254`) and fill in the above MAC address.
|
||||||
|
|
||||||
You might need to restart your server and/or router, but if everything went well, you should now be able to see the line `inet 192.168.1.254` next to the network interface when running `ifconfig -a`.
|
You might need to restart your server and/or router, but if everything went well, you should now be able to see the line `inet 192.168.1.254` next to the network interface when running `ifconfig -a`.
|
||||||
|
|
||||||
@@ -66,32 +66,32 @@ You first need to create a Cloudflare API key:
|
|||||||
2. Click Create Token
|
2. Click Create Token
|
||||||
3. Provide the token with a name, for example, `cloudflare-ddns`
|
3. Provide the token with a name, for example, `cloudflare-ddns`
|
||||||
4. Grant the following permissions:
|
4. Grant the following permissions:
|
||||||
- Zone - Zone Settings - Read
|
- Zone - Zone Settings - Read
|
||||||
- Zone - Zone - Read
|
- Zone - Zone - Read
|
||||||
- Zone - DNS - Edit
|
- Zone - DNS - Edit
|
||||||
5. Set the zone resources to:
|
5. Set the zone resources to:
|
||||||
- Include - All zones
|
- Include - All zones
|
||||||
6. Complete the wizard and copy the generated token into the `API_KEY` variable for the container. Make sure to note this down somewhere since you won't be able to access it afterwards.
|
6. Complete the wizard and copy the generated token into the `API_KEY` variable for the container. Make sure to note this down somewhere since you won't be able to access it afterwards.
|
||||||
|
|
||||||
After getting your API key, go to your Portainer instance, open the *stacks* tab, and add a new stack named `routing`. In the `docker-compose` field paste the following and customize to match your API key and domain:
|
After getting your API key, go to your Portainer instance, open the _stacks_ tab, and add a new stack named `routing`. In the `docker-compose` field paste the following and customize to match your API key and domain:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '3.9'
|
version: "3.9"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
cloudflare_ddns:
|
cloudflare_ddns:
|
||||||
image: oznu/cloudflare-ddns
|
image: oznu/cloudflare-ddns
|
||||||
container_name: cloudflare_ddns
|
container_name: cloudflare_ddns
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- API_KEY=[your-api-key]
|
- API_KEY=[your-api-key]
|
||||||
- ZONE=example.com
|
- ZONE=example.com
|
||||||
- SUBDOMAIN=ddns
|
- SUBDOMAIN=ddns
|
||||||
- PROXIED=false
|
- PROXIED=false
|
||||||
network_mode: bridge
|
network_mode: bridge
|
||||||
```
|
```
|
||||||
|
|
||||||
Click *deploy the stack* and you should notice that a new A record has appeared on the DNS tab of your Cloudflare dashboard.
|
Click _deploy the stack_ and you should notice that a new A record has appeared on the DNS tab of your Cloudflare dashboard.
|
||||||
|
|
||||||
I have also added a couple of CNAME records pointing to the original A record specifically for SSH and VPN services: `ssh.example.com` and `vpn.example.com`.
|
I have also added a couple of CNAME records pointing to the original A record specifically for SSH and VPN services: `ssh.example.com` and `vpn.example.com`.
|
||||||
|
|
||||||
@@ -118,28 +118,28 @@ $ docker run -v /mnt/storage/configs/openvpn:/etc/openvpn --rm -e PUID=1000 -e P
|
|||||||
After running these commands, go to Potainer and deploy a new `vpn` stack:
|
After running these commands, go to Potainer and deploy a new `vpn` stack:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '3.9'
|
version: "3.9"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
vpn:
|
vpn:
|
||||||
image: kylemanna/openvpn
|
image: kylemanna/openvpn
|
||||||
container_name: openvpn
|
container_name: openvpn
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- '/mnt/storage/configs/openvpn:/etc/openvpn'
|
- "/mnt/storage/configs/openvpn:/etc/openvpn"
|
||||||
environment:
|
environment:
|
||||||
- PUID=1000
|
- PUID=1000
|
||||||
- PGID=1000
|
- PGID=1000
|
||||||
ports:
|
ports:
|
||||||
- '1194:1194/udp'
|
- "1194:1194/udp"
|
||||||
networks:
|
networks:
|
||||||
- vpn
|
- vpn
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
vpn:
|
vpn:
|
||||||
name: vpn
|
name: vpn
|
||||||
```
|
```
|
||||||
|
|
||||||
If everything went well, you should be able to download an OpenVPN client from one of these sources and import your certificate.
|
If everything went well, you should be able to download an OpenVPN client from one of these sources and import your certificate.
|
||||||
@@ -278,45 +278,44 @@ $ docker network create proxy
|
|||||||
Finally, open the `routing` stack you created earlier in Portainer and edit it like so:
|
Finally, open the `routing` stack you created earlier in Portainer and edit it like so:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '3.9'
|
version: "3.9"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
nginx-proxy-manager:
|
nginx-proxy-manager:
|
||||||
image: jlesage/nginx-proxy-manager
|
image: jlesage/nginx-proxy-manager
|
||||||
container_name: nginx_proxy_manager
|
container_name: nginx_proxy_manager
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- USER_ID=1000
|
- USER_ID=1000
|
||||||
- GROUP_ID=1000
|
- GROUP_ID=1000
|
||||||
- UMASK=002
|
- UMASK=002
|
||||||
- TZ=Europe/Athens
|
- TZ=Europe/Athens
|
||||||
- DISABLE_IPV6=1
|
- DISABLE_IPV6=1
|
||||||
- KEEP_APP_RUNNING=1
|
- KEEP_APP_RUNNING=1
|
||||||
volumes:
|
volumes:
|
||||||
- '/mnt/storage/configs/routing/nginx:/config'
|
- "/mnt/storage/configs/routing/nginx:/config"
|
||||||
- '/mnt/storage/configs/routing/nginx/nginx.conf:/etc/nginx/nginx.conf'
|
- "/mnt/storage/configs/routing/nginx/nginx.conf:/etc/nginx/nginx.conf"
|
||||||
- '/mnt/storage:/static:ro'
|
- "/mnt/storage:/static:ro"
|
||||||
ports:
|
ports:
|
||||||
- '80:8080'
|
- "80:8080"
|
||||||
- '81:8181'
|
- "81:8181"
|
||||||
- '443:4443'
|
- "443:4443"
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
- proxy
|
||||||
|
|
||||||
whoami:
|
whoami:
|
||||||
image: containous/whoami
|
image: containous/whoami
|
||||||
container_name: whoami
|
container_name: whoami
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
- proxy
|
||||||
|
|
||||||
cloudflare_ddns:
|
cloudflare_ddns: [...]
|
||||||
[...]
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
proxy:
|
proxy:
|
||||||
external: true
|
external: true
|
||||||
name: proxy
|
name: proxy
|
||||||
```
|
```
|
||||||
|
|
||||||
After deploying the stack, you can open a browser and go to `[your-server-ip]:81` to access NPM's web UI, or `[your-server-ip]:80` to test your installation. However, you still won't be able to actually use the proxy.
|
After deploying the stack, you can open a browser and go to `[your-server-ip]:81` to access NPM's web UI, or `[your-server-ip]:80` to test your installation. However, you still won't be able to actually use the proxy.
|
||||||
@@ -344,31 +343,27 @@ Then, follow the instructions on your terminal and save the `cert.pem` file at `
|
|||||||
Finally, edit the `routing` stack again and add the following:
|
Finally, edit the `routing` stack again and add the following:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '3.9'
|
version: "3.9"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
nginx-proxy-manager:
|
nginx-proxy-manager: [...]
|
||||||
[...]
|
|
||||||
|
|
||||||
whoami:
|
whoami: [...]
|
||||||
[...]
|
|
||||||
|
|
||||||
cloudflare_ddns:
|
cloudflare_ddns: [...]
|
||||||
[...]
|
|
||||||
|
|
||||||
cloudflare_argo_tunnel:
|
cloudflare_argo_tunnel:
|
||||||
image: cloudflare/cloudflared
|
image: cloudflare/cloudflared
|
||||||
container_name: cloudflare_tunnel
|
container_name: cloudflare_tunnel
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- '/mnt/storage/configs/routing/cloudflared:/etc/cloudflared'
|
- "/mnt/storage/configs/routing/cloudflared:/etc/cloudflared"
|
||||||
networks:
|
networks:
|
||||||
- proxy
|
- proxy
|
||||||
command: tunnel --no-autoupdate --origincert /etc/cloudflared/cert.pem --hostname example.com --no-tls-verify --origin-server-name *.example.com --url https://nginx-proxy-manager:4443
|
command: tunnel --no-autoupdate --origincert /etc/cloudflared/cert.pem --hostname example.com --no-tls-verify --origin-server-name *.example.com --url https://nginx-proxy-manager:4443
|
||||||
user: '1000:1000'
|
user: "1000:1000"
|
||||||
|
|
||||||
networks:
|
networks: [...]
|
||||||
[...]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
After deploying, you should notice a new AAAA record on your Cloudflare dashboard. If you want to use any other subdomain, you simply need to add a CNAME alias pointing to that record.
|
After deploying, you should notice a new AAAA record on your Cloudflare dashboard. If you want to use any other subdomain, you simply need to add a CNAME alias pointing to that record.
|
||||||
@@ -379,7 +374,6 @@ To test if everything is working correctly, add a new CNAME alias for `whoami.ex
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
proxy_set_header Host $server;
|
proxy_set_header Host $server;
|
||||||
proxy_set_header X-Forwarded-Proto $forward_scheme;
|
proxy_set_header X-Forwarded-Proto $forward_scheme;
|
||||||
@@ -395,7 +389,7 @@ Wait a couple of minutes for the changes to propagate and you should be able to
|
|||||||
|
|
||||||
The primary reason why SSL is used is to keep sensitive information sent across the Internet encrypted so that only the intended recipient can access it. One of the main selling points of NPM is automatic SSL certificate management.
|
The primary reason why SSL is used is to keep sensitive information sent across the Internet encrypted so that only the intended recipient can access it. One of the main selling points of NPM is automatic SSL certificate management.
|
||||||
|
|
||||||
In order to create a wildcard certificate for all of your subdomains, you can follow [this](https://www.reddit.com/r/unRAID/comments/kniuok/howto_add_a_wildcard_certificate_in_nginx_proxy/) guide by [u/Sunsparc](https://www.reddit.com/user/Sunsparc/) on Reddit. After creating your certificate, you should always select it, as well as turn on *Force SSL* and *HTTP/2 Support* on any proxy host you create.
|
In order to create a wildcard certificate for all of your subdomains, you can follow [this](https://www.reddit.com/r/unRAID/comments/kniuok/howto_add_a_wildcard_certificate_in_nginx_proxy/) guide by [u/Sunsparc](https://www.reddit.com/user/Sunsparc/) on Reddit. After creating your certificate, you should always select it, as well as turn on _Force SSL_ and _HTTP/2 Support_ on any proxy host you create.
|
||||||
|
|
||||||
## Final Thoughts
|
## Final Thoughts
|
||||||
|
|
||||||
|
@@ -84,45 +84,45 @@ After installing the VirtIO drivers, boot back into Linux and create a new VM in
|
|||||||
|
|
||||||
1. Select "Manual Install" and make sure the architecture is set to "x86_64"
|
1. Select "Manual Install" and make sure the architecture is set to "x86_64"
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
2. Set the Operating System to "Microsoft Windows 10".
|
2. Set the Operating System to "Microsoft Windows 10".
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
3. Allocate as much memory as you need but make sure to leave some for the host as well. You can see how much memory the host is currently using by running `free -m`. Changing the CPU options doesn't really matter since we'll manually change them later.
|
3. Allocate as much memory as you need but make sure to leave some for the host as well. You can see how much memory the host is currently using by running `free -m`. Changing the CPU options doesn't really matter since we'll manually change them later.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
4. Do not enable storage for this virtual machine for now. We'll do that during the customization.
|
4. Do not enable storage for this virtual machine for now. We'll do that during the customization.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
5. Select "Customize configuration before install" and make sure that "Virtual network 'default': NAT" is chosen.
|
5. Select "Customize configuration before install" and make sure that "Virtual network 'default': NAT" is chosen.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
A new window should pop up. This is where you can customize your virtual machine. Before booting it, you should change a couple of options:
|
A new window should pop up. This is where you can customize your virtual machine. Before booting it, you should change a couple of options:
|
||||||
|
|
||||||
Under "Overview", Set the Chipset to "Q35" and the Firmware to "UEFI x86_64: /usr/share/edk2-ovmf/x64/OVMF_CODE.fd". Make sure to click "Apply" before switching pages.
|
Under "Overview", Set the Chipset to "Q35" and the Firmware to "UEFI x86_64: /usr/share/edk2-ovmf/x64/OVMF_CODE.fd". Make sure to click "Apply" before switching pages.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Under "CPUs", deselect "Copy host CPU configuration" and pick `host-passthrough`. You should also select "Manually set CPU topology" and set 1 Socket, 6 Cores, and 2 Threads (12 total virtual cores), leaving 4 for the host. If you have a different CPU, you should make sure to change these options to fit your configuration.
|
Under "CPUs", deselect "Copy host CPU configuration" and pick `host-passthrough`. You should also select "Manually set CPU topology" and set 1 Socket, 6 Cores, and 2 Threads (12 total virtual cores), leaving 4 for the host. If you have a different CPU, you should make sure to change these options to fit your configuration.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Click "Add Hardware > Storage" and add the drive that contains Windows. Set "Bus type" to "VirtIO" and "Cache mode" to "none" for better performance.
|
Click "Add Hardware > Storage" and add the drive that contains Windows. Set "Bus type" to "VirtIO" and "Cache mode" to "none" for better performance.
|
||||||
|
|
||||||
> [!warning]
|
> [!warning]
|
||||||
> Make sure that the drive contains the Windows Bootloader. If it doesn't, you can resize the Windows partition, boot from a rescue USB, and create a Bootloader using BCDBOOT.
|
> Make sure that the drive contains the Windows Bootloader. If it doesn't, you can resize the Windows partition, boot from a rescue USB, and create a Bootloader using BCDBOOT.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Set the Network Device and Video Device models to "VirtIO".
|
Set the Network Device and Video Device models to "VirtIO".
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
Finally, click "Begin Installation". You might have to manually add a Boot Entry to the UEFI by pressing the Escape key while the VM is booting, going to "Boot Maintenance Manager > Boot Options > Add Boot Option > Windows Disk > EFI > Microsoft > Boot > bootmgfw.efi".
|
Finally, click "Begin Installation". You might have to manually add a Boot Entry to the UEFI by pressing the Escape key while the VM is booting, going to "Boot Maintenance Manager > Boot Options > Add Boot Option > Windows Disk > EFI > Microsoft > Boot > bootmgfw.efi".
|
||||||
|
|
||||||
@@ -182,6 +182,7 @@ IOMMU Group 8 00:18.7 Host bridge [0600]: Advanced Micro Devices, Inc. [AMD] Dev
|
|||||||
IOMMU Group 9 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104M [GeForce RTX 3070 Mobile / Max-Q] [10de:24dd] (rev a1)
|
IOMMU Group 9 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104M [GeForce RTX 3070 Mobile / Max-Q] [10de:24dd] (rev a1)
|
||||||
IOMMU Group 9 01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)
|
IOMMU Group 9 01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)
|
||||||
```
|
```
|
||||||
|
|
||||||
What we mainly care about are the GPU groups, specifically:
|
What we mainly care about are the GPU groups, specifically:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -284,7 +285,6 @@ IOMMU Group 9 00:14.3 ISA bridge [0601]: Advanced Micro Devices, Inc. [AMD] FCH
|
|||||||
|
|
||||||
## Creating the Hook Scripts
|
## Creating the Hook Scripts
|
||||||
|
|
||||||
|
|
||||||
Before doing any passthrough, we need to create the scripts that will allocate the necessary resources to the VM before it boots and de-allocate them after it shuts down. To do that, we are going to be using [libvirt hooks](https://libvirt.org/hooks.html) and The Passthrough Post's [hook helper](https://passthroughpo.st/simple-per-vm-libvirt-hooks-with-the-vfio-tools-hook-helper/). You can find all the needed scripts in this project's [git repository](https://git.karaolidis.com/karaolidis/legion-7-vfio).
|
Before doing any passthrough, we need to create the scripts that will allocate the necessary resources to the VM before it boots and de-allocate them after it shuts down. To do that, we are going to be using [libvirt hooks](https://libvirt.org/hooks.html) and The Passthrough Post's [hook helper](https://passthroughpo.st/simple-per-vm-libvirt-hooks-with-the-vfio-tools-hook-helper/). You can find all the needed scripts in this project's [git repository](https://git.karaolidis.com/karaolidis/legion-7-vfio).
|
||||||
|
|
||||||
> [!warning]
|
> [!warning]
|
||||||
|
@@ -31,20 +31,21 @@ With the help of Paragon's new [NTFS3 driver](https://www.kernel.org/doc/html/la
|
|||||||
1. Boot using the Arch Install ISO.
|
1. Boot using the Arch Install ISO.
|
||||||
|
|
||||||
2. Format the target drive. In my case, that's `/dev/sda`. It needs to have a GPT partition table and 2 partitions in total:
|
2. Format the target drive. In my case, that's `/dev/sda`. It needs to have a GPT partition table and 2 partitions in total:
|
||||||
- 1GB EFI Filesystem
|
|
||||||
- The rest of the drive (leave it unallocated for now)
|
|
||||||
|
|
||||||

|
- 1GB EFI Filesystem
|
||||||
|
- The rest of the drive (leave it unallocated for now)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
3. Shut down your system and boot using the Windows ISO.
|
3. Shut down your system and boot using the Windows ISO.
|
||||||
|
|
||||||
4. Make sure to select "Custom: Install Windows only (advanced)".
|
4. Make sure to select "Custom: Install Windows only (advanced)".
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
5. Select the Unallocated Space we created earlier and finish the installation.
|
5. Select the Unallocated Space we created earlier and finish the installation.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
6. Once the installation is complete, shut the system down and boot into the Arch ISO once again.
|
6. Once the installation is complete, shut the system down and boot into the Arch ISO once again.
|
||||||
|
|
||||||
@@ -52,19 +53,19 @@ With the help of Paragon's new [NTFS3 driver](https://www.kernel.org/doc/html/la
|
|||||||
|
|
||||||
8. Run the `archinstall` installation script.
|
8. Run the `archinstall` installation script.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
9. When asked about which drives to configure, make sure to not select anything.
|
9. When asked about which drives to configure, make sure to not select anything.
|
||||||
|
|
||||||
10. I also decided to use GRUB as my bootloader since I am more familiar with it, but you can use whatever you like.
|
10. I also decided to use GRUB as my bootloader since I am more familiar with it, but you can use whatever you like.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
11. The install script will fail during GRUB's installation, so we must continue manually.
|
11. The install script will fail during GRUB's installation, so we must continue manually.
|
||||||
|
|
||||||
12. Change root into the installation folder and install GRUB.
|
12. Change root into the installation folder and install GRUB.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
13. Add the windows bootloader as a custom GRUB entry by editing `/etc/grub.d/40_custom`. Make sure to replace `{UUID}` with your disk's UUID. You can get it by running `blkid /dev/sda1`.
|
13. Add the windows bootloader as a custom GRUB entry by editing `/etc/grub.d/40_custom`. Make sure to replace `{UUID}` with your disk's UUID. You can get it by running `blkid /dev/sda1`.
|
||||||
|
|
||||||
|
@@ -29,8 +29,8 @@ name = "Source Code"
|
|||||||
url = "https://git.karaolidis.com/karaolidis/blog"
|
url = "https://git.karaolidis.com/karaolidis/blog"
|
||||||
|
|
||||||
[taxonomies]
|
[taxonomies]
|
||||||
tag = 'tags'
|
tag = 'tags'
|
||||||
|
|
||||||
[markup]
|
[markup]
|
||||||
[markup.highlight]
|
[markup.highlight]
|
||||||
noClasses = false
|
noClasses = false
|
||||||
|
Submodule themes/caldwell updated: 9905066046...d9a3c4b4a1
Reference in New Issue
Block a user