Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3529834d95 | ||
|
|
fd21bd2f83 | ||
|
|
2c28b27e82 | ||
|
|
d22711484b | ||
|
|
bfdef4c47a | ||
|
|
6129fd31d1 | ||
|
|
d839908521 | ||
|
|
c640801e23 | ||
|
|
9e3f116f55 | ||
|
|
a59c6c7d4a | ||
|
|
7f0c36fddf | ||
|
|
3e421f5478 | ||
|
|
ad86a1f3ce | ||
|
|
d2b6fbec5e | ||
|
|
a53a424399 | ||
|
|
77b87485b0 | ||
|
|
a63454ed53 | ||
|
|
104efa534c | ||
|
|
eaabf7db68 | ||
|
|
c1f6cff105 | ||
|
|
5d872ab3c6 | ||
|
|
8cfc044087 | ||
|
|
d08e86d04f | ||
|
|
4722c5c1a8 | ||
|
|
876d0a6ff5 | ||
|
|
6eaf8a5c94 | ||
|
|
45bca17862 | ||
|
|
66d51c4010 | ||
|
|
da67053e3b |
@@ -16,19 +16,19 @@ This repository contains everything you need to edit pages, apply your changes,
|
|||||||
|
|
||||||
Install dependencies:
|
Install dependencies:
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development Environment (port 3000)
|
## Development Environment (port 3000)
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generate Static Pages
|
## Generate Static Pages
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
npm run generate
|
npm run generate
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -38,6 +38,6 @@ The HTML files will be generated in the `.output/public` folder and are ready to
|
|||||||
|
|
||||||
If you'd like to immediately see the result of your static site build, you can launch a preview server:
|
If you'd like to immediately see the result of your static site build, you can launch a preview server:
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
npm run preview
|
npm run preview
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ export default defineAppConfig({
|
|||||||
|
|
||||||
docus: {
|
docus: {
|
||||||
title: 'Docudjeex',
|
title: 'Docudjeex',
|
||||||
description: 'La doc de mes expériences',
|
description: 'Homelab documentation',
|
||||||
url: 'http://docus.dev',
|
url: 'https://docu.djeex.fr',
|
||||||
image: '/img/social.png',
|
image: '/img/social.png',
|
||||||
socials: {
|
socials: {
|
||||||
github:'',
|
github:'',
|
||||||
|
|||||||
@@ -69,3 +69,19 @@ p img {
|
|||||||
padding-bottom: 80px !important;
|
padding-bottom: 80px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.prose-code.highlight-sh code .line {
|
||||||
|
padding-inline-start: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose-code.highlight-sh code .line:before {
|
||||||
|
display:none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose-code.highlight-bash code .line {
|
||||||
|
padding-inline-start: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose-code.highlight-bash code .line:before {
|
||||||
|
display:none !important;
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Home
|
title: Home
|
||||||
|
description: Homelab documentation by Djeex — self-hosting guides for Debian, Docker, networking, storage, and more.
|
||||||
navigation: false
|
navigation: false
|
||||||
layout: page
|
layout: page
|
||||||
main:
|
main:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
icon: lucide:home
|
icon: lucide:home
|
||||||
title: Welcome
|
title: Welcome
|
||||||
|
description: Introduction to Docudjeex — a personal homelab documentation site covering self-hosted services, Debian, and Docker infrastructure.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -9,7 +10,7 @@ main:
|
|||||||
# docu[·]{style="color: #1ad6ff"}what?
|
# docu[·]{style="color: #1ad6ff"}what?
|
||||||
|
|
||||||
__Docu[·]{style="color: #1ad6ff"}djeex__ is a site containing the documentation of my personal servers, originally created to easily keep track of my configurations and commands.
|
__Docu[·]{style="color: #1ad6ff"}djeex__ is a site containing the documentation of my personal servers, originally created to easily keep track of my configurations and commands.
|
||||||
My infrastructure is built around the Debian 12 + Docker combo, making exporting and deployment simpler.
|
My infrastructure is built around the Debian 13 + Docker combo, making exporting and deployment simpler.
|
||||||
Special thanks to __Nipah__, __Xenio__, and others for their patience and support. Most of this content comes directly from them.
|
Special thanks to __Nipah__, __Xenio__, and others for their patience and support. Most of this content comes directly from them.
|
||||||
|
|
||||||
## About the documentation
|
## About the documentation
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: NAT & DHCP
|
title: NAT & DHCP
|
||||||
|
description: Learn how NAT, port forwarding, and DHCP work on a home router. Configure fixed IP leases and understand how to expose local services.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -26,7 +27,7 @@ When it receives data through a port, your router forwards that data to the mach
|
|||||||
|
|
||||||
Your router has over 65,000 ports available.
|
Your router has over 65,000 ports available.
|
||||||
|
|
||||||
Some programs and applications are designed to use specific ports. For example, when your network sends data from an HTML page, the router receives it through port 80 (non-secure) or port 443 (secure via SSL).
|
Some programs and applications are designed to use specific ports. For example, when your network sends data from an HTML page, the router receives it through port 80 (non-secure) or port `443` (secure via SSL).
|
||||||
|
|
||||||
So, your router acts as a data dispatcher between the internet and your local machines.
|
So, your router acts as a data dispatcher between the internet and your local machines.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: DNS Zone
|
title: DNS Zone
|
||||||
|
description: Understand how DNS works, how to read and edit a DNS zone, and how to configure domain names for your self-hosted services.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Samba
|
title: Samba
|
||||||
|
description: Set up Samba on Debian to share folders over your local network and access them from Windows, macOS, or Linux.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -29,14 +30,14 @@ There are many tutorials for setting up Samba on Windows or on NAS systems like
|
|||||||
|
|
||||||
### Install Samba Server
|
### Install Samba Server
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo apt update && sudo apt upgrade
|
sudo apt update && sudo apt upgrade
|
||||||
sudo apt install samba smbclient cifs-utils
|
sudo apt install samba smbclient cifs-utils
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create the `/video` Folder
|
### Create the `/video` Folder
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mkdir /video
|
sudo mkdir /video
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -44,10 +45,11 @@ sudo mkdir /video
|
|||||||
|
|
||||||
Now, edit the file `/etc/samba/smb.conf`.
|
Now, edit the file `/etc/samba/smb.conf`.
|
||||||
|
|
||||||
✨ **Tip:** You can use [File Browser](/serveex/files/file-browser) to navigate and edit your files instead of using terminal commands.
|
::alert{type="success"}
|
||||||
\::
|
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit your files instead of using terminal commands.
|
||||||
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vim /etc/samba/smb.conf
|
sudo vim /etc/samba/smb.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -75,47 +77,47 @@ Since we're using a secured share, we need to create a user and group to access
|
|||||||
|
|
||||||
Create the group:
|
Create the group:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo groupadd smbshare
|
sudo groupadd smbshare
|
||||||
```
|
```
|
||||||
|
|
||||||
Give the group control over the `/video` folder:
|
Give the group control over the `/video` folder:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo chgrp -R smbshare /video
|
sudo chgrp -R smbshare /video
|
||||||
```
|
```
|
||||||
|
|
||||||
Set inherited permissions:
|
Set inherited permissions:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo chmod 2775 /video
|
sudo chmod 2775 /video
|
||||||
```
|
```
|
||||||
|
|
||||||
Now add a no-login user — this user cannot log into the server but can access Samba.
|
Now add a no-login user — this user cannot log into the server but can access Samba.
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo useradd -M -s /sbin/nologin sambauser
|
sudo useradd -M -s /sbin/nologin sambauser
|
||||||
```
|
```
|
||||||
|
|
||||||
Add the user to the `smbshare` group:
|
Add the user to the `smbshare` group:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo usermod -aG smbshare sambauser
|
sudo usermod -aG smbshare sambauser
|
||||||
```
|
```
|
||||||
|
|
||||||
Set a Samba password:
|
Set a Samba password:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo smbpasswd -a sambauser
|
sudo smbpasswd -a sambauser
|
||||||
```
|
```
|
||||||
|
|
||||||
Enable the Samba account:
|
Enable the Samba account:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo smbpasswd -e sambauser
|
sudo smbpasswd -e sambauser
|
||||||
```
|
```
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo ufw allow from remote-ip to any app Samba
|
sudo ufw allow from remote-ip to any app Samba
|
||||||
::
|
::
|
||||||
```
|
```
|
||||||
@@ -128,7 +130,7 @@ sudo ufw allow from remote-ip to any app Samba
|
|||||||
|
|
||||||
### Install Required Packages
|
### Install Required Packages
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo apt update && sudo apt upgrade
|
sudo apt update && sudo apt upgrade
|
||||||
sudo apt install cifs-utils
|
sudo apt install cifs-utils
|
||||||
```
|
```
|
||||||
@@ -137,7 +139,7 @@ sudo apt install cifs-utils
|
|||||||
|
|
||||||
We will create a folder on our local machine where the remote `/video` folder will be mounted — e.g., `/mnt/video`.
|
We will create a folder on our local machine where the remote `/video` folder will be mounted — e.g., `/mnt/video`.
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mkdir /mnt/video
|
sudo mkdir /mnt/video
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -147,7 +149,7 @@ To avoid typing our username and password every time, create a `.credentials` fi
|
|||||||
|
|
||||||
Create it in the `/smb` folder:
|
Create it in the `/smb` folder:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mkdir /smb
|
sudo mkdir /smb
|
||||||
sudo vi /smb/.credentials
|
sudo vi /smb/.credentials
|
||||||
```
|
```
|
||||||
@@ -166,7 +168,7 @@ Press `Esc`, then `:x` and `Enter` to save and exit.
|
|||||||
|
|
||||||
Set proper file permissions:
|
Set proper file permissions:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo chmod 600 /smb/.credentials
|
sudo chmod 600 /smb/.credentials
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -174,7 +176,7 @@ sudo chmod 600 /smb/.credentials
|
|||||||
|
|
||||||
Now mount the folder:
|
Now mount the folder:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mount -t cifs -o credentials=/smb/.credentials //remote-ip/video /mnt/video
|
sudo mount -t cifs -o credentials=/smb/.credentials //remote-ip/video /mnt/video
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -182,7 +184,7 @@ Replace `remote-ip` with your `remote-machine`'s IP address.
|
|||||||
|
|
||||||
Verify the mount:
|
Verify the mount:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mount -t cifs
|
sudo mount -t cifs
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -196,25 +198,25 @@ By default, shares aren't auto-mounted after reboot. To automate this, edit the
|
|||||||
|
|
||||||
First, back it up:
|
First, back it up:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo cp /etc/fstab /etc/fstab.bak
|
sudo cp /etc/fstab /etc/fstab.bak
|
||||||
```
|
```
|
||||||
|
|
||||||
Then add the mount configuration line:
|
Then add the mount configuration line:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo echo //remote-ip/video /mnt/video cifs _netdev,nofail,credentials=/smb/.credentials,x-systemd.automount,x-systemd.device-timeout=15 0 0 >> /etc/fstab
|
sudo echo //remote-ip/video /mnt/video cifs _netdev,nofail,credentials=/smb/.credentials,x-systemd.automount,x-systemd.device-timeout=15 0 0 >> /etc/fstab
|
||||||
```
|
```
|
||||||
|
|
||||||
Reboot the machine:
|
Reboot the machine:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo reboot
|
sudo reboot
|
||||||
```
|
```
|
||||||
|
|
||||||
After rebooting, verify the mount:
|
After rebooting, verify the mount:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mount -t cifs
|
sudo mount -t cifs
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -222,6 +224,6 @@ And done!
|
|||||||
|
|
||||||
### Unmount the Shared Folder
|
### Unmount the Shared Folder
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo umount -t cifs /mnt/video
|
sudo umount -t cifs /mnt/video
|
||||||
```
|
```
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: RAID
|
title: RAID
|
||||||
|
description: Understand RAID concepts — hardware vs software, RAID levels, and how to set up redundant disk arrays for your homelab.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -74,9 +75,7 @@ Use RAID 0 when you prioritize performance and are not concerned about data loss
|
|||||||
Use RAID 1 for strong redundancy. Each disk contains all data, so performance remains unaffected during a failure. Once failed disks are replaced, data is quickly restored. However, usable storage is limited to one disk’s capacity, making it an expensive solution.
|
Use RAID 1 for strong redundancy. Each disk contains all data, so performance remains unaffected during a failure. Once failed disks are replaced, data is quickly restored. However, usable storage is limited to one disk’s capacity, making it an expensive solution.
|
||||||
|
|
||||||
::alert{type="success"}
|
::alert{type="success"}
|
||||||
:::list{type="success"}
|
✨ __Tip:__ You can combine RAID 1 with other RAID types to create mirrored arrays.
|
||||||
- __Tip:__ You can combine RAID 1 with other RAID types to create mirrored arrays.
|
|
||||||
:::
|
|
||||||
::
|
::
|
||||||
|
|
||||||
### RAID 5
|
### RAID 5
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: ZFS
|
title: ZFS
|
||||||
|
description: Introduction to ZFS — a combined file system and volume manager with snapshots, checksums, and built-in redundancy for reliable homelab storage.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: The Basics
|
||||||
|
description: Overview of server hardware fundamentals — CPUs, RAM, storage, and form factors to understand before building your homelab.
|
||||||
|
main:
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
# Server Basics
|
||||||
|
|
||||||
|
::alert{type="info"}
|
||||||
|
🎯 __Objectives:__
|
||||||
|
- Understand the fundamentals of server hardware
|
||||||
|
::
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
A __server__ is essentially a computer dedicated to specific tasks, designed to remain accessible at all times. Structurally, it's not much different from a regular computer. Depending on its intended use, some components may vary. This article serves as a reference to help you understand the essential components of a server and how their roles adapt based on your needs.
|
||||||
|
|
||||||
|
## Motherboard
|
||||||
|
---
|
||||||
|
The __motherboard__ is the foundation of your machine. It's the component that connects all others together. It enables communication between components and interaction with peripherals (keyboard, mouse, etc.). Choose it based on your I/O (Input/Output) needs like USB ports, network ports, speed, etc., and ensure compatibility with the components you plan to install.
|
||||||
|
|
||||||
|
Key components connected to the motherboard:
|
||||||
|
- CPU
|
||||||
|
- RAM
|
||||||
|
- Storage (HDD and/or SSD)
|
||||||
|
- Optional dedicated GPU
|
||||||
|
|
||||||
|
Common consumer motherboard formats:
|
||||||
|
- E-ATX: largest
|
||||||
|
- ATX: standard
|
||||||
|
- Micro-ATX: smaller
|
||||||
|
- Mini-ITX: smallest
|
||||||
|
|
||||||
|
Larger boards generally offer more ports and features. Pre-built systems might use proprietary formats.
|
||||||
|
|
||||||
|
## CPU
|
||||||
|
---
|
||||||
|
<div style="display: flex; align-items: center;">
|
||||||
|
<img src="/img/global/cpu.svg" alt="Image" style="max-width: 25%; max-height:230px; margin-right: 20px;">
|
||||||
|
<p>The <strong>CPU</strong> (Central Processing Unit) is the computer's calculator. It processes most software tasks. Modern CPUs have multiple cores, often with virtual threads, to better handle workloads. They need to be cooled using either an active cooler (with a fan) or a passive one (fanless), depending on power consumption (watts). Choose your CPU based on how you plan to use the server.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
::alert{type="warning"}
|
||||||
|
:::list{type="warning"}
|
||||||
|
- __Caution:__ Ensure third-party coolers are compatible with the CPU socket and always apply thermal paste before installing the cooler.
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
Consider:
|
||||||
|
- Number of cores (more cores = better multitasking)
|
||||||
|
- Clock speed in GHz
|
||||||
|
- Power consumption in Watts
|
||||||
|
|
||||||
|
For low-power home servers or NAS (non-intensive computing), consider Intel N100/150 (4 cores) or N305/N355 (8 cores)—efficient and low power (ideal for 24/7 uptime).
|
||||||
|
|
||||||
|
## RAM
|
||||||
|
---
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="/img/global/ram.svg" alt="Image" style="max-width: 65%;">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
__RAM__ (Random Access Memory) is fast, temporary memory used by the CPU (and iGPU if applicable) for quick access during execution. It clears periodically and when the machine powers down. Better RAM = better CPU performance.
|
||||||
|
|
||||||
|
Comes as sticks installed on the motherboard. Varies by format and generation (currently DDR5).
|
||||||
|
|
||||||
|
## GPU
|
||||||
|
---
|
||||||
|
|
||||||
|
The __GPU__ (Graphics Processing Unit) handles graphical, video, and sometimes AI-related processing. Its main theoretical use is to display the image on your screen. In servers, it's useful for media centers (e.g. [Plex](/serveex/media/plex)) and for accelerating AI tasks like facial recognition or photo indexing (e.g. [Immich](/serveex/cloud/immich)).
|
||||||
|
|
||||||
|
Depending on the required performance, one can choose between a dedicated GPU with its own VRAM (a graphics card connected to a PCIe slot on the motherboard), or an iGPU—an integrated GPU built into the CPU (such as the N100/N150 or N305/N355), which uses the system’s shared RAM.
|
||||||
|
|
||||||
|
### HDD(s)
|
||||||
|
---
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="/img/global/hdd.svg" alt="Image" style="max-width: 50%; margin-right: 20px;">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
An __HDD__ (Hard Disk Drive), or hard drive, is a component used to store data. It was once the standard storage device in computers. HDDs consist of one or more stacked platters and read/write heads—somewhat like a vinyl record player.
|
||||||
|
|
||||||
|
Today, HDDs can store enormous amounts of data (up to 30TB, or 30,000 gigabytes, for consumer models), but their read and write speeds are limited due to their mechanical nature. They are also bulky and heavy.
|
||||||
|
|
||||||
|
Generally, HDDs are best suited for storing data that doesn’t require frequent access or fast write speeds, such as media files (videos, photos), cloud drives, or archived data. They perform well in these scenarios and, most importantly, are significantly cheaper than SSDs for the same amount of storage.
|
||||||
|
|
||||||
|
::alert{type="success"}
|
||||||
|
✨ __Tip:__ Use multiple HDDs in [RAID](/general/storage/raid) to enhance performance and redundancy.
|
||||||
|
::
|
||||||
|
|
||||||
|
Comes in 3.5" and 2.5" formats; servers usually favor the more reliable 3.5".
|
||||||
|
|
||||||
|
### SSD(s)
|
||||||
|
---
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="/img/global/nvme.svg" alt="Image" style="max-width: 50%; margin-right: 20px;">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
An __SSD__ (Solid State Drive) is a small circuit board with memory chips soldered onto it, used to store information. Unlike RAM, these chips retain data even when not powered, meaning the information is preserved after a reboot. SSDs are generally used as the main storage medium for your server.
|
||||||
|
|
||||||
|
Unlike HDDs, SSDs have no moving parts, are highly compact, and most importantly, are extremely fast—offering speeds of several gigabytes per second for high-performance models.
|
||||||
|
|
||||||
|
SSDs come in various formats, but today the preferred choice is the M.2 NVMe version, as it is the smallest, fastest, and has become the standard on modern motherboards.
|
||||||
|
|
||||||
|
However, SSDs are significantly more expensive than hard drives for the same storage capacity. Typically, the operating system (OS) is installed on the SSD to ensure fast performance. In a server environment, it's also ideal to store [Docker containers](/serveex/core/docker) and databases on the SSD. More broadly, any data that needs to be accessed frequently and quickly—such as websites, applications, or processing workloads—should be stored on an SSD.
|
||||||
|
|
||||||
|
### Network Card
|
||||||
|
---
|
||||||
|
|
||||||
|
A __network card__ allows your machine to communicate with your network (including the internet). It consists of a controller chip and one or more network ports. These ports—often Ethernet ports—can come in different physical formats and support various data transfer standards:
|
||||||
|
|
||||||
|
- __RJ45 Gigabit Ethernet (10/100/1000):__ The standard RJ45 connector, supporting speeds from 10 Mbps (0.125 MB/s) up to 1000 Mbps (125 MB/s).
|
||||||
|
- __RJ45 2.5G:__ Same connector type, supporting up to 2.5 Gbps (2,500 Mbps or 312.5 MB/s).
|
||||||
|
- __RJ45 5G:__ Same connector, supporting up to 5 Gbps (625 MB/s).
|
||||||
|
- __RJ45 10G Base-T:__ Same RJ45 format, supporting up to 10 Gbps (1.25 GB/s).
|
||||||
|
- __SFP 1G:__ SFP port, commonly used for fiber optic connections, supporting speeds up to 1 Gbps.
|
||||||
|
- __SFP+ 10G:__ An enhanced version of the SFP port, also used for fiber optics, supporting up to 10 Gbps.
|
||||||
|
|
||||||
|
::alert{type="warning"}
|
||||||
|
:::list{type="warning"}
|
||||||
|
- __Caution:__ Match network gear (router, switch, cables) to your desired speed. For most uses, CAT5E cables are enough; use CAT6A beyond 10 Gbps. Fiber requires additional care (simplex, duplex, transceivers...).
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
The network card is usually built directly into the motherboard, but you can also use dedicated network cards, for example via USB or a PCIe expansion slot.
|
||||||
|
|
||||||
|
In general, for a server setup, it's recommended to have at least two Ethernet ports to ensure redundancy in case one connection fails.
|
||||||
|
|
||||||
|
### Input/Output Ports
|
||||||
|
---
|
||||||
|
|
||||||
|
__I/O__ ports allow communication with external devices (displays, keyboard, mouse, network...). Motherboards typically offer:
|
||||||
|
- Ethernet ports
|
||||||
|
- USB ports (varied types/speeds)
|
||||||
|
- Video ports
|
||||||
|
- Audio jacks
|
||||||
|
|
||||||
|
Choose a motherboard and expansions based on your I/O needs.
|
||||||
|
|
||||||
|
### Power Supply
|
||||||
|
---
|
||||||
|
|
||||||
|
The __power supply unit__ (PSU) is the component that provides electrical power to your machine’s components. It connects to the wall via a power cord and has several output cables that plug into the motherboard and various peripherals, such as hard drives or dedicated graphics cards.
|
||||||
|
|
||||||
|
A power supply is defined by several key characteristics:
|
||||||
|
|
||||||
|
- Wattage (its total power output),
|
||||||
|
- Modularity (whether the cables are fixed or detachable),
|
||||||
|
- Efficiency (measured as a percentage). For example, a 500W PSU with 80% efficiency will actually draw 625W from the wall to deliver 500W to the system.
|
||||||
|
|
||||||
|
Another important factor is the form factor. There are several standard sizes, from ATX L (for larger cases) to SFX (for compact builds). There are also specialized models for rack-mounted servers, which are typically flat and space-efficient.
|
||||||
|
|
||||||
|
To choose the right PSU, a common rule of thumb is to estimate your system’s power needs based on usage, and then double that value. This is because most power supplies operate at optimal efficiency around 50% of their maximum load.
|
||||||
|
|
||||||
|
### Case
|
||||||
|
---
|
||||||
|
|
||||||
|
<div style="display: flex; align-items: center;">
|
||||||
|
<img src="/img/global/case.svg" alt="Image" style="max-width: 25%; max-height:230px; margin-right: 20px;">
|
||||||
|
<p>The <strong>case</strong> is also an essential component of your machine. It plays a key role in cooling, through its fans and airflow design, and it determines the form factor compatibility for your motherboard, power supply, and any dedicated GPU you may install.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Additionally, the case dictates how many HDDs you can install and what formats they support. Some cases are rack-mountable, meaning they can be installed in server racks (server cabinets).
|
||||||
|
|
||||||
|
Choose your case carefully based on your specific needs and the hardware you plan to use.
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: Network
|
||||||
|
description: Overview of networking hardware for homelabs — switches, NICs, cables, and how to connect your servers efficiently.
|
||||||
|
main:
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
# Network
|
||||||
|
|
||||||
|
::alert{type="info"}
|
||||||
|
🎯 __Objectives:__
|
||||||
|
- Understand the basics of networking hardware
|
||||||
|
::
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
A computer network cannot exist without the hardware required to build it. Hardware determines the size of the network, communication speeds, and its overall performance. In this article, we will focus on the simplest types of networks, typically found in home environments.
|
||||||
|
|
||||||
|
## The Router
|
||||||
|
---
|
||||||
|
The __router__ is the central hub of your network. It directs __packets__—the blocks of data that travel across your network—from the sender to the appropriate recipient. It manages the routing of data both within your local network and to/from external networks. In short, it enables devices to communicate with each other and with the internet.
|
||||||
|
|
||||||
|
Everyone has a router at home—it's the __internet box__ provided by your ISP (Internet Service Provider).
|
||||||
|
|
||||||
|
In general, a router consists of:
|
||||||
|
- a WAN (Wide Area Network) port that receives data from the internet (or from a higher-level network). For example, it could be a port for a fiber optic connection from your ISP, or an SFP+/RJ45 port for a third-party router.
|
||||||
|
- a switch, i.e., a hub with several __LAN__ (Local Area Network) ports allowing multiple devices to connect to your network. These ports can be RJ45 or SFP/SFP+.
|
||||||
|
- sometimes a built-in WiFi transmitter/receiver.
|
||||||
|
|
||||||
|
A router may also include _firewall_ capabilities, allowing you to restrict traffic from specific devices, as well as _[NAT (Network Address Translation)](/general/networking/nat)_ for port forwarding. It generally includes a _[DHCP (Dynamic Host Configuration Protocol)](/general/networking/nat#dhcp)_ server to automatically assign _IP addresses_ to devices connected to the network.
|
||||||
|
|
||||||
|
The router directly affects communication speeds between devices. The WAN port limits the maximum internet speed you can receive from your ISP. For example, if your subscription offers 5 Gb/s, you’ll need a WAN port that supports at least 5 Gb/s. Likewise, internal device-to-device communication is limited by the speed of the switch. If your devices communicate at 5 Gb/s, the router’s switch must have 5 Gb/s ports. If you're using WiFi 7 equipment and want to enjoy its full speed, your router must support it as well. If you’re using a separate WiFi access point, make sure its network port matches or exceeds the speed of the WiFi it broadcasts—and that the router supports it too.
|
||||||
|
|
||||||
|
Internet speed, number of devices, WiFi speed, and internal network speed—these are the four key factors to consider when choosing an internet box or buying your own router.
|
||||||
|
|
||||||
|
::alert{type="success"}
|
||||||
|
✨ __Tip:__
|
||||||
|
You can easily use a third-party router to manage your network if your ISP’s internet box supports _bridge mode_. In France, only the provider Free offers this option. It is technically possible with other providers that do not support bridge mode, but it can be quite difficult and may prevent you from using all the features a third-party router provides.
|
||||||
|
::
|
||||||
|
|
||||||
|
## The Switch
|
||||||
|
---
|
||||||
|
|
||||||
|
The __switch__, or network switch, is a device that allows multiple devices to connect to the network. It acts as a literal hub, connecting directly to the router or to another switch upstream. It helps avoid overloading the switch ports on your router or relocating devices to another room without running a cable from each one back to the router. Another common use case is to segment multiple networks that are managed by the same router.
|
||||||
|
|
||||||
|
There are generally two types of switches:
|
||||||
|
- **Unmanaged switches**, the most common. These are plug-and-play: you just plug them in and everything works automatically.
|
||||||
|
- **Managed switches**. These offer a configuration interface (via command line or web UI), allowing you to fine-tune routing rules under the control of the router. They are powerful for creating virtual networks between your devices, but usually require more setup time and are less convenient than simple unmanaged switches.
|
||||||
|
|
||||||
|
::alert{type="warning"}
|
||||||
|
:::list{type="warning"}
|
||||||
|
- __Warning:__ Make sure to use a switch with ports that match the speeds supported by your network devices.
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
## Cables
|
||||||
|
---
|
||||||
|
|
||||||
|
Cables are essential components of your network. Depending on their type and category, they can limit the bandwidth between devices, so they must be chosen to match your network's specifications. They also need to be compatible with your devices' ports.
|
||||||
|
|
||||||
|
Here’s a quick reference of the most common cable and port standards:
|
||||||
|
|
||||||
|
- **RJ45 Gigabit Ethernet 10/100/1000**: The standard RJ45 connector, supporting speeds from 10 Mbps (0.125 MB/s) to 1000 Mbps (125 MB/s)
|
||||||
|
- **RJ45 2.5G**: Same connector, supporting speeds up to 2.5 Gbps (312.5 MB/s)
|
||||||
|
- **RJ45 5G**: Same connector, supporting speeds up to 5 Gbps (625 MB/s)
|
||||||
|
- **RJ45 10GBase-T**: Same connector, supporting speeds up to 10 Gbps (1.25 GB/s)
|
||||||
|
- **SFP 1G**: SFP port, typically used for fiber optics, supporting up to 1 Gbps
|
||||||
|
- **SFP+ 10G**: Enhanced SFP port, also for fiber, supporting up to 10 Gbps
|
||||||
|
|
||||||
|
### Ethernet Cables
|
||||||
|
|
||||||
|
These copper cables usually use the standard `RJ45` connector. It's the most common network connector found on routers and switches.
|
||||||
|
|
||||||
|
Ethernet cables are divided into categories that define their maximum speed based on distance:
|
||||||
|
|
||||||
|
| Speed | Cable Type | Max Distance |
|
||||||
|
|-----------|------------|--------------|
|
||||||
|
| 10 Gb/s | CAT 6A | 100 m |
|
||||||
|
| | CAT 6 | 55 m |
|
||||||
|
| | CAT 5e | 30 m |
|
||||||
|
| 5 Gb/s | CAT 6 | 100 m |
|
||||||
|
| | CAT 5e | 30 m |
|
||||||
|
| 2.5 Gb/s | CAT 5e | 100 m |
|
||||||
|
| 1 Gb/s | CAT 5e | 100 m |
|
||||||
|
| 100 Mb/s | CAT 5 | 100 m |
|
||||||
|
|
||||||
|
Some of these cables are flat, round, shielded (requiring grounding), etc. Choose based on your setup. What matters is that, for example, if you want to connect a device with a 2.5 Gb/s RJ45 port to a 2.5 Gb/s router, you’ll need at least a `CAT 5e` cable.
|
||||||
|
|
||||||
|
On the other hand, if your device is limited to 100 Mb/s, a simple `CAT 5` cable will suffice.
|
||||||
|
|
||||||
|
Nowadays, in new buildings, it is standard practice to install `CAT 6A` cables inside walls. This way, wall ports are ready to support 10 Gb/s over 100 meters.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Optical Cables
|
||||||
|
|
||||||
|
Very thin but fragile, optical cables are increasingly appearing in home networks. It often starts with the fiber cable connecting your ISP’s outlet to your box/router. They have several advantages:
|
||||||
|
- Extremely compact
|
||||||
|
- Zero electrical consumption (unlike copper, which loses energy as heat)
|
||||||
|
- No electromagnetic radiation (no shielding needed, no signal interference)
|
||||||
|
- Very high speeds over long distances
|
||||||
|
|
||||||
|
For local networking, it's important to understand that several types of fiber cables exist. Their performance depends on both distance and compatibility with the appropriate `transceiver`. Fiber cables connect to your devices' SFP+ ports via a small device called a transceiver, which converts electrical signals to light (and vice versa).
|
||||||
|
|
||||||
|
For local networks, the recommended standard is a **multimode OM3 fiber with LC connectors**, paired with a **10G LC SFP+ transceiver**. This setup allows 10 Gb/s connections and is compatible with most devices featuring SFP+ ports.
|
||||||
|
|
||||||
|
::alert{type="warning"}
|
||||||
|
:::list{type="warning"}
|
||||||
|
- __Warning:__ Make sure to use transceivers that are compatible with your devices (routers, switches, or other hardware). There is no universal standard yet, and manufacturers usually specify which brands are supported.
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DAC Cables
|
||||||
|
|
||||||
|
These are copper cables with integrated `transceivers`. They allow two SFP/SFP+ ports to communicate over short distances without using fragile fiber or RJ45 adapters. However, they consume more energy due to natural copper loss, which is non-negligible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### SFP+ Transceivers
|
||||||
|
|
||||||
|
These let you connect different types of cables to your SFP/SFP+ ports. Variants are available for:
|
||||||
|
- Fiber optic
|
||||||
|
- DAC
|
||||||
|
- RJ45
|
||||||
|
|
||||||
|
::alert{type="warning"}
|
||||||
|
:::list{type="warning"}
|
||||||
|
- RJ45 transceivers consume a lot of energy due to copper signal loss and can generate significant heat. Low-power models (under 2W) exist and are generally rated for longer cables (e.g., 80m instead of 30m). Surprisingly, these are preferred over short-distance models because they generate less heat and consume less energy—making them more compatible with sensitive devices. Using the wrong type can cause network degradation or even outages.
|
||||||
|
:::
|
||||||
|
::
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: The ProloNAS
|
||||||
|
description: Build a capable home server on a budget using an Intel N100 mini PC — a practical guide to getting started with self-hosting for under $130.
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
|
||||||
|
# The ProloNAS
|
||||||
|
|
||||||
|
When you decide to dive into the adventure of running your own home server, the same questions usually come up: _“Where should I start?”_, _“Isn’t it expensive?”_. And often, people either give up or end up buying a proprietary NAS that they’ll throw away a year later once they realize it only brings headaches and wasted money.
|
||||||
|
|
||||||
|
A server isn’t a piece of furniture. It’s simply any computer capable of running Linux.That’s why mini PCs powered by **Intel N100** processors are so popular: for around $100–130 on Chinese platforms, you can get a machine that runs **24/7** for years, capable of handling everything you’d expect from a home server or personal cloud without sacrificing performance.
|
||||||
|
|
||||||
|
It’s **objectively inexpensive**, and anyone with a bit of curiosity can get started.
|
||||||
|
|
||||||
|
A mini PC for $100 + a USB dock for $50 that holds multiple hard drives = a complete platform for $150, versus **$350–1200** for branded NAS systems.
|
||||||
|
|
||||||
|
That’s all a **ProloNAS** is. It’s then up to you to scale your storage capacity according to your needs.
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## Example Hardware
|
||||||
|
|
||||||
|
- Mini PC — **Note: choose 16 GB / 512 GB**: [Aliexpress](https://fr.aliexpress.com/item/1005008477986765.html)
|
||||||
|
- DAS (Direct Attached Storage) — **Note: select “EU plug”**: [Aliexpress](https://fr.aliexpress.com/item/1005007933987260.html)
|
||||||
|
- More refined alternative with a fan: [Amazon](https://www.amazon.fr/Boîtier-Disque-Ventilateur-Supportant-Capacité/dp/B0DD3GSSCX)
|
||||||
|
|
||||||
|
> *These are not affiliate links — buy wherever you prefer.*
|
||||||
|
|
||||||
|
|
||||||
|
## Why a NAS?
|
||||||
|
|
||||||
|
A **NAS** (Network Attached Storage) is a machine centered around storage, designed to be shared over a network.The idea is to have a **reliable and secure** storage space that serves as the backbone for your personal services and apps such as a self-hosted cloud like [Nextcloud](/serveex/cloud/nextcloud), a photo sync tool like [Immich](/serveex/cloud/immich), or a media server like [Plex](/serveex/media/plex). You can also store camera footage, backups, or even development projects on it.
|
||||||
|
|
||||||
|
### But why not just use a mini PC with an external hard drive?
|
||||||
|
|
||||||
|
Sure, a simple mini PC with 1–2 TB of storage will do for most people.And your movie collection might fit on an external drive of a few extra terabytes. But that’s **neither reliable nor scalable** a single shock or hardware failure could permanently destroy your data.
|
||||||
|
|
||||||
|
A real NAS is built around **storage reliability**. It uses redundancy strategies like [RAID](/general/storage/raid) to protect against drive failure, and snapshot systems like [ZFS](/general/storage/zfs) to guard against corruption.
|
||||||
|
|
||||||
|
In short, a NAS lets you **host everything yourself** that you currently entrust to third parties while maintaining control, reliability, and data safety.
|
||||||
|
|
||||||
|
|
||||||
|
## The Problem with Consumer NAS Systems
|
||||||
|
|
||||||
|
Many brands offer “ready-to-use” NAS platforms: Synology, QNAP, Ugreen, and others. They promise simplicity and sleek web interfaces, but the reality is quite different.
|
||||||
|
|
||||||
|
### First, the price.
|
||||||
|
|
||||||
|
$350 is the starting price for a 2-bay NAS (without drives) from Synology. For that, you get a 2019 processor, no SSD slot for the OS, and a measly 2 GB of RAM.
|
||||||
|
|
||||||
|
Now, compare that to the **ProloNAS**: an N100 (4 cores), 16 GB RAM, a 512 GB SSD for $100–130, plus a 4-bay DAS for $55. That’s **half the price** of a 2-bay Synology, and **a quarter of the price** of a 4-bay one.
|
||||||
|
|
||||||
|
### Locked-Down Operating Systems
|
||||||
|
|
||||||
|
“Yeah, but at least with a Synology, you plug it in and everything just works.”
|
||||||
|
|
||||||
|
One year.
|
||||||
|
That’s how long it took before I threw away my Synology and realized I should have started with a **ProloNAS** (which later became a full-fledged server).
|
||||||
|
|
||||||
|
Manufacturers ship heavily customized Linux-based OSes: ancient kernels, limited app repositories, and complete dependence on their proprietary tools. As a result, you can’t fully tailor your NAS to your needs, and many Docker containers simply won’t run because the kernel is too old.
|
||||||
|
|
||||||
|
### Total Vendor Lock-In
|
||||||
|
|
||||||
|
“I’m fine with the built-in apps.”
|
||||||
|
Yeah, I thought so too… until my needs exploded: media center, password manager, Git hosting, strong authentication, web hosting, and more.
|
||||||
|
|
||||||
|
Why stay stuck with half-baked proprietary tools when you can rely on **open-source projects** that are regularly updated and interoperable?
|
||||||
|
|
||||||
|
And what happens when the manufacturer decides to drop support or limit hardware compatibility? It’s already happened, Synology made certain drives **incompatible** unless they were “certified” by them. They even **disabled hardware transcoding** on their NAS units: [see here](https://www.cachem.fr/synology-desactive-transcodage-materiel-nas/).
|
||||||
|
|
||||||
|
In short, you have **no control** over a product that isn’t open, nor truly yours.
|
||||||
|
|
||||||
|
## OK, but how do I turn my Mini PC Serveex into a ProloNAS?
|
||||||
|
|
||||||
|
As mentioned earlier: by adding a **DAS (drive hub)** and setting up a redundant storage system with [RAID](/general/storage/raid) and [ZFS](/general/storage/zfs), you can transform your mini PC into a robust and scalable NAS.
|
||||||
|
|
||||||
|
Enjoy !
|
||||||
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
---
|
|
||||||
navigation: true
|
|
||||||
title: The Basics
|
|
||||||
main:
|
|
||||||
fluid: false
|
|
||||||
---
|
|
||||||
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
|
||||||
# Server Basics
|
|
||||||
|
|
||||||
::alert{type="info"}
|
|
||||||
🎯 __Objectives:__
|
|
||||||
- Understand the fundamentals of server hardware
|
|
||||||
::
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
A server is essentially a computer dedicated to specific tasks, designed to remain accessible at all times. Structurally, it's not much different from a regular computer. Depending on its intended use, some components may vary. This article serves as a reference to help you understand the essential components of a server and how their roles adapt based on your needs.
|
|
||||||
|
|
||||||
## Motherboard
|
|
||||||
---
|
|
||||||
The motherboard is the foundation of your machine. It's the component that connects all others together. It enables communication between components and interaction with peripherals (keyboard, mouse, etc.). Choose it based on your I/O (Input/Output) needs like USB ports, network ports, speed, etc., and ensure compatibility with the components you plan to install.
|
|
||||||
|
|
||||||
Key components connected to the motherboard:
|
|
||||||
- CPU
|
|
||||||
- RAM
|
|
||||||
- Storage (HDD and/or SSD)
|
|
||||||
- Optional dedicated GPU
|
|
||||||
|
|
||||||
Common consumer motherboard formats:
|
|
||||||
- E-ATX: largest
|
|
||||||
- ATX: standard
|
|
||||||
- Micro-ATX: smaller
|
|
||||||
- Mini-ITX: smallest
|
|
||||||
|
|
||||||
Larger boards generally offer more ports and features. Pre-built systems might use proprietary formats.
|
|
||||||
|
|
||||||
## CPU
|
|
||||||
---
|
|
||||||
<div style="display: flex; align-items: center;">
|
|
||||||
<img src="/img/global/cpu.svg" alt="Image" style="max-width: 25%; max-height:230px; margin-right: 20px;">
|
|
||||||
<p>The CPU (Central Processing Unit) is the computer's calculator. It processes most software tasks. Modern CPUs have multiple cores, often with virtual threads, to better handle workloads. They need to be cooled using either an active cooler (with a fan) or a passive one (fanless), depending on power consumption (watts). Choose your CPU based on how you plan to use the server.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
::alert{type="warning"}
|
|
||||||
:::list{type="warning"}
|
|
||||||
- __Caution:__ Ensure third-party coolers are compatible with the CPU socket and always apply thermal paste before installing the cooler.
|
|
||||||
:::
|
|
||||||
::
|
|
||||||
|
|
||||||
Consider:
|
|
||||||
- Number of cores (more cores = better multitasking)
|
|
||||||
- Clock speed in GHz
|
|
||||||
- Power consumption in Watts
|
|
||||||
|
|
||||||
For low-power home servers or NAS (non-intensive computing), consider Intel N100/150 (4 cores) or N305/N355 (8 cores)—efficient and low power (ideal for 24/7 uptime).
|
|
||||||
|
|
||||||
## RAM
|
|
||||||
---
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img src="/img/global/ram.svg" alt="Image" style="max-width: 65%;">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
RAM (Random Access Memory) is fast, temporary memory used by the CPU (and iGPU if applicable) for quick access during execution. It clears periodically and when the machine powers down. Better RAM = better CPU performance.
|
|
||||||
|
|
||||||
Comes as sticks installed on the motherboard. Varies by format and generation (currently DDR5).
|
|
||||||
|
|
||||||
## GPU
|
|
||||||
---
|
|
||||||
|
|
||||||
The GPU (Graphics Processing Unit) handles graphical, video, and sometimes AI-related processing. In servers, it's useful for media centers (e.g. [Plex](/serveex/media/plex)) and for accelerating AI tasks like facial recognition or photo indexing (e.g. [Immich](/serveex/cloud/immich)).
|
|
||||||
|
|
||||||
Choose between:
|
|
||||||
- Dedicated GPU with VRAM (via PCIe)
|
|
||||||
- iGPU (integrated GPU within the CPU like the N100/N305 series)
|
|
||||||
|
|
||||||
### HDD(s)
|
|
||||||
---
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img src="/img/global/hdd.svg" alt="Image" style="max-width: 50%; margin-right: 20px;">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
An HDD (Hard Disk Drive) is a traditional data storage device using spinning platters and read/write heads. Though slower due to its mechanical nature, it offers huge capacity (up to 30TB). It's ideal for media files, cloud storage, and archives—where high speed isn't critical.
|
|
||||||
|
|
||||||
::alert{type="success"}
|
|
||||||
:::list{type="success"}
|
|
||||||
- __Tip:__ Use multiple HDDs in [RAID](/general/storage/raid) to enhance performance and redundancy.
|
|
||||||
:::
|
|
||||||
::
|
|
||||||
|
|
||||||
Comes in 3.5" and 2.5" formats; servers usually favor the more reliable 3.5".
|
|
||||||
|
|
||||||
### SSD(s)
|
|
||||||
---
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img src="/img/global/nvme.svg" alt="Image" style="max-width: 50%; margin-right: 20px;">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
An SSD (Solid State Drive) stores data on memory chips. Unlike RAM, SSDs retain data without power. They’re small, fast (several GB/s), and reliable with no moving parts.
|
|
||||||
|
|
||||||
Preferred format: M.2 NVMe—smallest and fastest, now standard.
|
|
||||||
|
|
||||||
More expensive than HDDs, but essential for:
|
|
||||||
- Operating system
|
|
||||||
- Containers like [Docker](/serveex/core/docker)
|
|
||||||
- Databases
|
|
||||||
- Any fast-access data (apps, websites, etc.)
|
|
||||||
|
|
||||||
### Network Card
|
|
||||||
---
|
|
||||||
|
|
||||||
Connects your server to a network (and internet). Has a controller chip and one or more ports, such as:
|
|
||||||
- RJ45 Gigabit Ethernet (10/100/1000 Mbps = 125 MB/s)
|
|
||||||
- RJ45 2.5G (312.5 MB/s)
|
|
||||||
- RJ45 5G (625 MB/s)
|
|
||||||
- RJ45 10G Base-T (1.25 GB/s)
|
|
||||||
- SFP 1G (fiber, 1 Gbps)
|
|
||||||
- SFP+ 10G (fiber, 10 Gbps)
|
|
||||||
|
|
||||||
::alert{type="warning"}
|
|
||||||
:::list{type="warning"}
|
|
||||||
- __Caution:__ Match network gear (router, switch, cables) to your desired speed. For most uses, CAT5E cables are enough; use CAT6A beyond 10 Gbps. Fiber requires additional care (simplex, duplex, transceivers...).
|
|
||||||
:::
|
|
||||||
::
|
|
||||||
|
|
||||||
Most motherboards include a built-in NIC. However, add-on network cards (USB or PCIe) can offer redundancy or better performance.
|
|
||||||
|
|
||||||
### Input/Output Ports
|
|
||||||
---
|
|
||||||
|
|
||||||
I/O ports allow communication with external devices (displays, keyboard, mouse, network...). Motherboards typically offer:
|
|
||||||
- Ethernet ports
|
|
||||||
- USB ports (varied types/speeds)
|
|
||||||
- Video ports
|
|
||||||
- Audio jacks
|
|
||||||
|
|
||||||
Choose a motherboard and expansions based on your I/O needs.
|
|
||||||
|
|
||||||
### Power Supply
|
|
||||||
---
|
|
||||||
|
|
||||||
The power supply delivers electricity to your components. It connects to wall power and uses various connectors for motherboard, drives, GPU, etc.
|
|
||||||
|
|
||||||
Key specs:
|
|
||||||
- Wattage (e.g., 500W)
|
|
||||||
- Modularity (fixed vs detachable cables)
|
|
||||||
- Efficiency (e.g., 80% = 625W drawn for 500W output)
|
|
||||||
|
|
||||||
Formats vary (ATX L to SFX). Rack server PSUs are flatter and specialized.
|
|
||||||
|
|
||||||
Rule of thumb: estimate your system's wattage needs and double it, since optimal PSU efficiency is around 50% load.
|
|
||||||
|
|
||||||
### Case
|
|
||||||
---
|
|
||||||
|
|
||||||
<div style="display: flex; align-items: center;">
|
|
||||||
<img src="/img/global/case.svg" alt="Image" style="max-width: 25%; max-height:230px; margin-right: 20px;">
|
|
||||||
<p>The case affects cooling, airflow, and compatibility (motherboard, PSU, GPU). It also determines HDD/SSD support and layout. Rackmount cases fit into server cabinets. Choose your case based on hardware needs and space constraints.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
icon: lucide:bookmark
|
icon: lucide:bookmark
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Introduction
|
title: Introduction
|
||||||
|
description: Introduction to Serveex — a personal homelab project to self-host everyday services using Debian and Docker, replacing Google, Apple, and Netflix.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -41,7 +42,7 @@ The Core of the Server
|
|||||||
#title
|
#title
|
||||||
__Operating System__
|
__Operating System__
|
||||||
#description
|
#description
|
||||||
[Install and configure Debian 12](/serveex/core/installation)
|
[Install and configure Debian 13](/serveex/core/installation)
|
||||||
::
|
::
|
||||||
|
|
||||||
::card{icon=logos:docker-icon}
|
::card{icon=logos:docker-icon}
|
||||||
|
|||||||
@@ -1,34 +1,35 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Debian 12
|
title: Debian 13
|
||||||
|
description: Step-by-step guide to install Debian 13 on a home server and set up SSH access, essential packages, and a ready-to-use base system.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
# Debian 12
|
# Debian 13
|
||||||
::alert{type="info"}
|
::alert{type="info"}
|
||||||
🎯 __Goal:__ Install Debian 12 and the main dependencies to have a ready-to-use OS, accessible via SSH.
|
🎯 __Goal:__ Install Debian 13 and the main dependencies to have a ready-to-use OS, accessible via SSH.
|
||||||
::
|
::
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
---
|
---
|
||||||
1. [BIOS Setup](https://www.debian.org/releases/stable/i386/ch03s06.fr.html#bios-setup)
|
1. [BIOS Setup]((https://www.debian.org/releases/stable/i386/ch03s06.en.html#bios-setup)
|
||||||
2. [Download Debian Image](https://www.debian.org/download.fr.html)
|
2. [Download Debian Image](https://www.debian.org/download.en.html)
|
||||||
3. [Create Bootable USB (Rufus)](https://dev.to/devops2808/how-to-create-bootable-usb-installer-for-debian-12-4f66)
|
3. [Create Bootable USB (Rufus)](https://dev.to/devops2808/how-to-create-bootable-usb-installer-for-debian-12-4f66)
|
||||||
4. [Install Debian and Set Up SSH](https://www.howtoforge.com/tutorial/debian-minimal-server/)
|
4. [Install Debian and Set Up SSH](https://www.howtoforge.com/tutorial/debian-minimal-server/)
|
||||||
5. Install sudo and add a user to the sudo group for administrative privileges.
|
5. Install sudo and add a user to the sudo group for administrative privileges.
|
||||||
Log in as root:
|
Log in as root:
|
||||||
```shell
|
```sh
|
||||||
su -
|
su -
|
||||||
```
|
```
|
||||||
Enter your password, then type:
|
Enter your password, then type:
|
||||||
```shell
|
```sh
|
||||||
apt install sudo
|
apt install sudo
|
||||||
```
|
```
|
||||||
Add the user to the sudo group:
|
Add the user to the sudo group:
|
||||||
```shell
|
```sh
|
||||||
adduser <username> sudo
|
adduser <username> sudo
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -42,10 +43,10 @@ main:
|
|||||||
## Must-Have CLI Apps
|
## Must-Have CLI Apps
|
||||||
---
|
---
|
||||||
Some essential apps you’ll likely need at some point, so might as well install them early:
|
Some essential apps you’ll likely need at some point, so might as well install them early:
|
||||||
```shell
|
```sh
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt upgrade
|
sudo apt upgrade
|
||||||
sudo apt install vim btop ranger git duf neofetch samba cifs-utils tree unzip ufw
|
sudo apt install vim btop ranger git duf neofetch samba cifs-utils tree unzip
|
||||||
```
|
```
|
||||||
|
|
||||||
Additionally:
|
Additionally:
|
||||||
@@ -65,7 +66,7 @@ Additionally:
|
|||||||
|
|
||||||
### File Transfer via rsync
|
### File Transfer via rsync
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo rsync -avhHSP /source /destination
|
sudo rsync -avhHSP /source /destination
|
||||||
```
|
```
|
||||||
::alert{type="info" icon="exclamation-circle"}
|
::alert{type="info" icon="exclamation-circle"}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Docker
|
title: Docker
|
||||||
|
description: Install Docker and Dockge on Debian to deploy and manage self-hosted services with simple container stacks.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -22,7 +23,7 @@ Docker, to install deployable services in seconds and manage them with just a fe
|
|||||||
---
|
---
|
||||||
Add the Docker repositories and GPG key:
|
Add the Docker repositories and GPG key:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
# Add Docker's official GPG key:
|
# Add Docker's official GPG key:
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install ca-certificates curl
|
sudo apt-get install ca-certificates curl
|
||||||
@@ -37,19 +38,19 @@ sudo apt-get update
|
|||||||
|
|
||||||
Install the packages:
|
Install the packages:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
```
|
```
|
||||||
|
|
||||||
That's it!
|
That's it!
|
||||||
|
|
||||||
**More options:** [Install Docker for Debian 12](https://docs.docker.com/engine/install/debian/)
|
**More options:** [Install Docker for Debian 13](https://docs.docker.com/engine/install/debian/)
|
||||||
|
|
||||||
::alert{type="info" icon="exclamation-circle"}
|
::alert{type="info" icon="exclamation-circle"}
|
||||||
:::list{type="info"}
|
:::list{type="info"}
|
||||||
- From here on, we assume the stacks are installed in the `/docker` folder, created using the command:
|
- From here on, we assume the stacks are installed in the `/docker` folder, created using the command:
|
||||||
:::
|
:::
|
||||||
```shell
|
```sh
|
||||||
sudo mkdir /docker
|
sudo mkdir /docker
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ That's it!
|
|||||||
|
|
||||||
File structure we will create:
|
File structure we will create:
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── dockge
|
└── dockge
|
||||||
@@ -72,14 +73,14 @@ root
|
|||||||
|
|
||||||
Create the stack folder:
|
Create the stack folder:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
cd /docker
|
cd /docker
|
||||||
sudo mkdir dockge
|
sudo mkdir dockge
|
||||||
```
|
```
|
||||||
|
|
||||||
Then create the `compose.yml` file in this folder using `vim`:
|
Then create the `compose.yml` file in this folder using `vim`:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
cd /docker/dockge
|
cd /docker/dockge
|
||||||
sudo vi compose.yml
|
sudo vi compose.yml
|
||||||
```
|
```
|
||||||
@@ -107,7 +108,7 @@ Press `Esc` and type `:x` to save and exit.
|
|||||||
|
|
||||||
To launch the container:
|
To launch the container:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
cd /docker/dockge
|
cd /docker/dockge
|
||||||
sudo docker compose up -d
|
sudo docker compose up -d
|
||||||
```
|
```
|
||||||
@@ -118,7 +119,7 @@ More info on [Dockge and how to use it](https://github.com/louislam/dockge)
|
|||||||
|
|
||||||
And there you go — Docker and a tool to easily manage your containers are ready!
|
And there you go — Docker and a tool to easily manage your containers are ready!
|
||||||
|
|
||||||
## [Watchtower](https://github.com/containrrr/watchtower?tab=readme-ov-file), to auto-update containers
|
## [Watchtower](https://watchtower.nickfedor.com/), to auto-update containers
|
||||||
---
|
---
|
||||||
Watchtower is a container that checks for updates and pulls new images automatically, just by adding a label in your containers’ `compose.yml` files.
|
Watchtower is a container that checks for updates and pulls new images automatically, just by adding a label in your containers’ `compose.yml` files.
|
||||||
|
|
||||||
@@ -134,7 +135,7 @@ Watchtower is a container that checks for updates and pulls new images automatic
|
|||||||
services:
|
services:
|
||||||
watchtower:
|
watchtower:
|
||||||
container_name: watchtower
|
container_name: watchtower
|
||||||
image: containrrr/watchtower:latest
|
image: ghcr.io/nicholas-fedor/watchtower:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: SWAG
|
title: SWAG
|
||||||
|
description: Set up SWAG as a reverse proxy with automatic SSL, expose your services securely, and configure geo-blocking on your homelab.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -41,7 +42,7 @@ Below is an example exposing Dockge. We will install SWAG along with the dbip mo
|
|||||||
|
|
||||||
File structure to be modified:
|
File structure to be modified:
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── swag
|
└── swag
|
||||||
@@ -133,7 +134,7 @@ In CLI, go to the dns-conf folder and edit the `ovh.ini` file:
|
|||||||
You can use [File Browser](/serveex/files/file-browser) to browse and edit files instead of using terminal commands.
|
You can use [File Browser](/serveex/files/file-browser) to browse and edit files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/dns-conf/ovh.ini
|
sudo vi /docker/swag/config/dns-conf/ovh.ini
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -163,7 +164,7 @@ Save and exit the file.
|
|||||||
|
|
||||||
Now configure swag to access DBIP, the geolocation-based access control module. Open the `nginx.conf` file:
|
Now configure swag to access DBIP, the geolocation-based access control module. Open the `nginx.conf` file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/nginx.conf
|
sudo vi /docker/swag/config/nginx/nginx.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -193,7 +194,7 @@ This configuration can be enabled or disabled per service (see the Dockge exampl
|
|||||||
|
|
||||||
Open `dbip.conf`:
|
Open `dbip.conf`:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/dbip.conf
|
sudo vi /docker/swag/config/nginx/dbip.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -278,7 +279,7 @@ Now it's time to expose Dockge on the internet so you can access and manage your
|
|||||||
|
|
||||||
Open the `dockge.subdomain.conf` file:
|
Open the `dockge.subdomain.conf` file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/dockge.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/dockge.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -363,7 +364,7 @@ Wait a moment, then visit `https://dockge.mydomain.com` in your browser — you
|
|||||||
---
|
---
|
||||||
SWAG includes templates for most known services, named `servicename.subdomain.conf.sample`. Just create the subdomain in your registrar's DNS zone (like OVH), point it to your main domain via a CNAME, then copy and rename the sample file:
|
SWAG includes templates for most known services, named `servicename.subdomain.conf.sample`. Just create the subdomain in your registrar's DNS zone (like OVH), point it to your main domain via a CNAME, then copy and rename the sample file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
cd /docker/swag/config/proxy-confs
|
cd /docker/swag/config/proxy-confs
|
||||||
sudo cp servicename.subdomain.conf.sample servicename.subdomain.conf
|
sudo cp servicename.subdomain.conf.sample servicename.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Wireguard
|
title: Wireguard
|
||||||
|
description: Install and configure WireGuard VPN to securely access your homelab from anywhere and connect all your devices to your private network.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -47,23 +48,23 @@ You *can* allow VPN clients to share access to their local networks, but we won
|
|||||||
|
|
||||||
So only VPN-connected devices can communicate with each other on the VPN, not with other local devices outside the VPN.
|
So only VPN-connected devices can communicate with each other on the VPN, not with other local devices outside the VPN.
|
||||||
|
|
||||||
## Server Side
|
## Server Setup
|
||||||
---
|
---
|
||||||
::alert{type="info"}
|
::alert{type="info"}
|
||||||
📋 __Checklist:__
|
📋 **Pre-flight Checklist:**
|
||||||
- Ensure port `51820 UDP` is available and properly forwarded through your router to the server (`Source 51820 UDP -> Destination 51820 UDP -> Server`).
|
- Ensure port `51820 UDP` is free on your server and correctly forwarded from your router (`51820 UDP -> Server`).
|
||||||
- Ensure port `51821 TCP` is available for the web UI.
|
- Ensure port `51821 TCP` is free for the web UI.
|
||||||
::
|
::
|
||||||
|
|
||||||
::alert{type="warning"}
|
::alert{type="warning"}
|
||||||
:::list{type="warning"}
|
:::list{type="warning"}
|
||||||
- __Warning:__ This guide uses version `14` of [wg-easy](https://wg-easy.github.io/wg-easy/latest/). Version `15` introduces breaking changes incompatible with this configuration.
|
- __Warning__: If your IP is not static, use a Dynamic DNS service ([DynDNS](https://en.wikipedia.org/wiki/Dynamic_DNS)). If your ISP uses [CGNAT](https://en.wikipedia.org/wiki/Carrier-grade_NAT), you’ll need to use an external VPS and connect your local server as a client.
|
||||||
:::
|
:::
|
||||||
::
|
::
|
||||||
|
|
||||||
Folder structure:
|
### Folder Structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── wg-easy
|
└── wg-easy
|
||||||
@@ -73,106 +74,100 @@ root
|
|||||||
└── .env
|
└── .env
|
||||||
```
|
```
|
||||||
|
|
||||||
The container runs in `HOST` mode, meaning it uses the host’s network stack directly.
|
Open Dockge, click **Compose**, and name the stack `wg_easy`.
|
||||||
|
|
||||||
Open Dockge, click `compose`, and name the stack `wg_easy`.
|
Copy the following configuration:
|
||||||
|
|
||||||
Paste the following configuration:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
services:
|
services:
|
||||||
wg-easy:
|
wg-easy:
|
||||||
network_mode: host
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
environment:
|
||||||
- LANG=en
|
- INSECURE=true
|
||||||
- WG_HOST=${HOST}
|
image: ghcr.io/wg-easy/wg-easy:15
|
||||||
- PASSWORD_HASH=${PW}
|
|
||||||
- WG_DEFAULT_ADDRESS=${ADDRESS}
|
|
||||||
- WG_HIDE_KEYS=never
|
|
||||||
- WG_ALLOWED_IPS=${IPS}
|
|
||||||
- WG_DEFAULT_DNS=
|
|
||||||
- UI_TRAFFIC_STATS=true
|
|
||||||
- UI_CHART_TYPE=1
|
|
||||||
image: ghcr.io/wg-easy/wg-easy:14
|
|
||||||
container_name: wg-easy
|
container_name: wg-easy
|
||||||
|
networks:
|
||||||
|
wg:
|
||||||
|
ipv4_address: 10.42.42.42
|
||||||
|
ipv6_address: fdcc:ad94:bacf:61a3::2a
|
||||||
volumes:
|
volumes:
|
||||||
- /docker/wg_easy/config/etc_wireguard:/etc/wireguard
|
- ./etc_wireguard:/etc/wireguard
|
||||||
|
- /lib/modules:/lib/modules:ro
|
||||||
|
ports:
|
||||||
|
- "51820:51820/udp"
|
||||||
|
- "51821:51821/tcp"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
- SYS_MODULE
|
- SYS_MODULE
|
||||||
|
sysctls:
|
||||||
|
- net.ipv4.ip_forward=1
|
||||||
|
- net.ipv4.conf.all.src_valid_mark=1
|
||||||
|
- net.ipv6.conf.all.disable_ipv6=0
|
||||||
|
- net.ipv6.conf.all.forwarding=1
|
||||||
|
- net.ipv6.conf.default.forwarding=1
|
||||||
|
|
||||||
|
networks:
|
||||||
|
wg:
|
||||||
|
driver: bridge
|
||||||
|
enable_ipv6: true
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: 10.42.42.0/24
|
||||||
|
- subnet: fdcc:ad94:bacf:61a3::/64
|
||||||
```
|
```
|
||||||
|
|
||||||
::alert{type="success"}
|
::alert{type="success"}
|
||||||
✨ __Tip:__
|
✨ **Tip:**
|
||||||
- You can also specify your own wireguard port with `WG_PORT`
|
- You can customize WireGuard and web UI ports.
|
||||||
- Add the Watchtower label to enable automatic updates
|
- Add a Watchtower label for automatic updates:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services
|
services:
|
||||||
wg-easy:
|
wg-easy:
|
||||||
#...
|
# ...
|
||||||
labels:
|
labels:
|
||||||
- com.centurylinklabs.watchtower.enable=true
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
```
|
```
|
||||||
::
|
::
|
||||||
|
|
||||||
In `.env`:
|
Deploy the stack and access the local web UI at `http://server-ip:51821`.
|
||||||
|
|
||||||
```properties
|
|
||||||
HOST=
|
|
||||||
PW=
|
|
||||||
ADDRESS=
|
|
||||||
IPS=
|
|
||||||
```
|
|
||||||
|
|
||||||
| Variable | Description | Example |
|
|
||||||
|--------------|-------------|---------|
|
|
||||||
| `HOST` | IP of public access of your host (router ISP's IP if it's at home) | `80.75.137.27` |
|
|
||||||
| `PW` | Bcrypt password hash, [generate here](https://bcrypt-generator.com/). **NOTE:** Double the `$` characters | `$$2a$$12$$FF6T4QqSP9Ho` |
|
|
||||||
| `ADDRESS` | VPN DHCP address range, the `x` must remain, others can vary | `10.8.0.x` |
|
|
||||||
| `IPS` | IPs routed by clients through the VPN. Use `10.8.0.0/24` to only route VPN traffic. To include local LAN, add `192.168.0.0/16` separated by commas. | `10.8.0.0/24` |
|
|
||||||
|
|
||||||
Deploy the stack.
|
|
||||||
|
|
||||||
### Enable Forwarding on Host
|
|
||||||
|
|
||||||
To allow communication between VPN clients, enable:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo sysctl net.ipv4.ip_forward=1
|
|
||||||
sudo sysctl net.ipv4.conf.all.src_valid_mark=1
|
|
||||||
```
|
|
||||||
|
|
||||||
### Retrieve Configuration Files
|
|
||||||
|
|
||||||
To configure clients, download the config files from the server:
|
|
||||||
|
|
||||||
- Visit `http://your-server-ip:51821`
|
|
||||||
- Create a client
|
|
||||||
- Download the config file
|
|
||||||
- Rename it to `wg0.conf`
|
|
||||||
|
|
||||||
::alert{type="danger"}
|
::alert{type="danger"}
|
||||||
:::list{type="danger"}
|
:::list{type="danger"}
|
||||||
- If it fails, check firewall rules.
|
- If the deployment fails, check your firewall rules.
|
||||||
:::
|
:::
|
||||||
::
|
::
|
||||||
|
|
||||||
## On the Client Server
|
Once connected, follow the web UI instructions to:
|
||||||
|
- Create your admin account and password.
|
||||||
|
- Set the host field (use your public IP or domain name).
|
||||||
|
|
||||||
|
Then go to *Administrator → Admin Panel → Config*:
|
||||||
|
- Change `Allowed IPs` from `0.0.0.0/24` to `10.8.0.0/24` for **split tunneling**.
|
||||||
|
- Remove IPv6 (it often causes unnecessary issues).
|
||||||
|
|
||||||
|
### Retrieve Configuration Files
|
||||||
|
|
||||||
|
To configure clients:
|
||||||
|
1. Access the web UI: `http://server-ip:51821`
|
||||||
|
2. Create a new client
|
||||||
|
3. Edit the client and add `10.8.0.0/24` to `Server Allowed IPs`
|
||||||
|
4. (Optional) Set `Persistent Keep Alive` to `25` if it’s a permanently connected client
|
||||||
|
5. Save, download, and rename the file to `wg0.conf` (or `wg1.conf`, etc.)
|
||||||
|
|
||||||
|
## Client Server Setup
|
||||||
---
|
---
|
||||||
::alert{type="info"}
|
::alert{type="info"}
|
||||||
:::list{type="info"}
|
:::list{type="info"}
|
||||||
- Assumes the client is a Linux server with Docker installed
|
- We assume the client server runs Linux with Docker installed.
|
||||||
:::
|
:::
|
||||||
::
|
::
|
||||||
|
|
||||||
Folder structure:
|
### Folder Structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── wireguard
|
└── wireguard
|
||||||
@@ -181,33 +176,32 @@ root
|
|||||||
└── compose.yaml
|
└── compose.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the folder `/docker/wireguard/config/wg_confs`:
|
Create the folder:
|
||||||
|
|
||||||
::alert{type="success"}
|
```sh
|
||||||
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to browse and edit files without terminal
|
|
||||||
::
|
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo mkdir -p /docker/wireguard/config/wg_confs
|
sudo mkdir -p /docker/wireguard/config/wg_confs
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy the `wg0.conf` file downloaded earlier:
|
::alert{type="success"}
|
||||||
|
✨ **Tip:** You can use [File Browser](/serveex/files/file-browser) instead of the terminal to edit and upload files.
|
||||||
|
::
|
||||||
|
|
||||||
|
Create the `wg0.conf` file:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo vi /docker/wireguard/config/wg_confs/wg0.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Enter insert mode (`i`), paste the downloaded configuration, then save (`Esc` → `:x`).
|
||||||
|
|
||||||
::alert{type="success"}
|
::alert{type="success"}
|
||||||
✨ __Tip:__ Easiest way is to transfer the file via SFTP to `/home/youruser`, then move it:
|
✨ **Alternative method:** Transfer the file via SFTP and move it:
|
||||||
|
```sh
|
||||||
```shell
|
|
||||||
sudo cp ~/wg0.conf /docker/wireguard/config/wg_confs
|
sudo cp ~/wg0.conf /docker/wireguard/config/wg_confs
|
||||||
```
|
```
|
||||||
::
|
::
|
||||||
|
|
||||||
Create `compose.yaml` in `/docker/wireguard`:
|
Create the `compose.yaml` file in `/docker/wireguard`:
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo vi /docker/wireguard/compose.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Press `i` to enter insert mode and paste:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
@@ -217,42 +211,39 @@ services:
|
|||||||
network_mode: host
|
network_mode: host
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
- SYS_MODULE #optional
|
- SYS_MODULE
|
||||||
environment:
|
environment:
|
||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
volumes:
|
volumes:
|
||||||
- /docker/wireguard/config:/config
|
- /docker/wireguard/config:/config
|
||||||
- /lib/modules:/lib/modules #optional
|
- /lib/modules:/lib/modules
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
```
|
```
|
||||||
|
|
||||||
Press `Esc` then type `:x` to save and exit.
|
|
||||||
|
|
||||||
Start the container:
|
Start the container:
|
||||||
|
```sh
|
||||||
```shell
|
|
||||||
cd /docker/wireguard
|
cd /docker/wireguard
|
||||||
sudo docker compose up -d
|
sudo docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
::alert{type="info" icon="exclamation-circle"}
|
::alert{type="info"}
|
||||||
:::list{type="info"}
|
:::list{type="info"}
|
||||||
- Repeat for each client
|
- Repeat this setup for each client.
|
||||||
:::
|
:::
|
||||||
::
|
::
|
||||||
|
|
||||||
## Other Devices
|
## Other Devices
|
||||||
---
|
---
|
||||||
- **Phone:** Install Wireguard and scan the QR code from the web UI (`http://your-server-ip:51821`)
|
- **Mobile:** Install WireGuard and scan the QR code via the web UI (`http://server-ip:51821`)
|
||||||
- **PC:** Install the Wireguard client and import the config file
|
- **Desktop:** Install the WireGuard client and import the downloaded config file.
|
||||||
|
|
||||||
::alert{type="warning"}
|
::alert{type="warning"}
|
||||||
:::list{type="warning"}
|
:::list{type="warning"}
|
||||||
- __Warning:__ If a client device is on the same LAN as the server, edit `wg0.conf` and change the endpoint to the local server IP:
|
- **Note:** If the client machine is on the same local network as the server, edit the `wg0.conf` file to use the local server IP:
|
||||||
`Endpoint = your-server-ip:51820`
|
`Endpoint = server-local-ip:51820`
|
||||||
:::
|
:::
|
||||||
::
|
::
|
||||||
|
|
||||||
And this is the result:
|
And here’s the final setup overview:
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Authentik
|
title: Authentik
|
||||||
|
description: Install Authentik as a self-hosted identity provider — configure MFA and protect your services with SSO and reverse proxy authentication.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -39,7 +40,7 @@ Both modes can be configured on a per-application basis.
|
|||||||
## Installation
|
## Installation
|
||||||
---
|
---
|
||||||
Folder structure:
|
Folder structure:
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── authentik
|
└── authentik
|
||||||
@@ -53,13 +54,13 @@ root
|
|||||||
|
|
||||||
Create the folders:
|
Create the folders:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mkdir -p /docker/authentik/media /docker/authentik/certs /docker/authentik/custom-template /docker/authentik/ssh
|
sudo mkdir -p /docker/authentik/media /docker/authentik/certs /docker/authentik/custom-template /docker/authentik/ssh
|
||||||
```
|
```
|
||||||
|
|
||||||
Navigate to the `authentik` folder and generate a password and secret key to include in the `.env` file:
|
Navigate to the `authentik` folder via `cd /docker/authentik` and generate a password and secret key to include in the `.env` file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo echo "PG_PASS=$(openssl rand 36 | base64)" >> .env
|
sudo echo "PG_PASS=$(openssl rand 36 | base64)" >> .env
|
||||||
sudo echo "AUTHENTIK_SECRET_KEY=$(openssl rand 60 | base64)" >> .env
|
sudo echo "AUTHENTIK_SECRET_KEY=$(openssl rand 60 | base64)" >> .env
|
||||||
```
|
```
|
||||||
@@ -68,12 +69,12 @@ sudo echo "AUTHENTIK_SECRET_KEY=$(openssl rand 60 | base64)" >> .env
|
|||||||
:::list{type="info"}
|
:::list{type="info"}
|
||||||
- To generate the keys, we created the folders ahead of deployment using Dockge. Dockge will prevent you from creating a stack with the same name in these folders unless a `compose.yml` file exists. So, create an empty `compose.yml` so it appears as an inactive stack:
|
- To generate the keys, we created the folders ahead of deployment using Dockge. Dockge will prevent you from creating a stack with the same name in these folders unless a `compose.yml` file exists. So, create an empty `compose.yml` so it appears as an inactive stack:
|
||||||
:::
|
:::
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/authentik/compose.yml
|
sudo vi /docker/authentik/compose.yml
|
||||||
::
|
::
|
||||||
|
|
||||||
Open Dockge and search for "authentik" in the inactive stacks.
|
Open Dockge and search for "authentik" in the inactive stacks.
|
||||||
Name the stack `authentik` and paste the following configuration, replacing `{AUTHENTIK_TAG:-2025.6.3}`{lang=properties} with [the latest version of Authentik](https://goauthentik.io/docs/releases).
|
Name the stack `authentik` and paste the following configuration, replacing `{AUTHENTIK_TAG:-2026.2}`{lang=properties} with [the latest version of Authentik](https://goauthentik.io/docs/releases).
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
@@ -117,7 +118,7 @@ services:
|
|||||||
- redis:/data
|
- redis:/data
|
||||||
|
|
||||||
server:
|
server:
|
||||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.1}
|
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2}
|
||||||
container_name: authentik-server
|
container_name: authentik-server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: server
|
command: server
|
||||||
@@ -141,7 +142,7 @@ services:
|
|||||||
- redis
|
- redis
|
||||||
|
|
||||||
worker:
|
worker:
|
||||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.1}
|
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2}
|
||||||
container_name: authentik-worker
|
container_name: authentik-worker
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: worker
|
command: worker
|
||||||
@@ -205,7 +206,7 @@ Open the `authentik-server.conf` file:
|
|||||||
You can use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
|
You can use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/authentik-server.conf
|
sudo vi /docker/swag/config/nginx/authentik-server.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -220,7 +221,7 @@ If not, press `i` to enter edit mode, make the necessary changes, then save and
|
|||||||
|
|
||||||
Create the `auth.subdomain.conf` file:
|
Create the `auth.subdomain.conf` file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/auth.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/auth.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -335,7 +336,7 @@ Why do this when Dockge already has authentication? Because Dockge uses weak HTT
|
|||||||
|
|
||||||
Edit the file `dockge.mydomain.com`:
|
Edit the file `dockge.mydomain.com`:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/dockge.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/dockge.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -417,7 +418,7 @@ On your remote machine, use [Dockge](/serveex/core/docker/#installer-dockge-pour
|
|||||||
|
|
||||||
If you haven’t installed [Dockge](/serveex/core/docker/#installer-dockge-pour-gérer-et-déployer-les-conteneurs), create a folder `/docker/authentik-outpost`, or directly via command line:
|
If you haven’t installed [Dockge](/serveex/core/docker/#installer-dockge-pour-gérer-et-déployer-les-conteneurs), create a folder `/docker/authentik-outpost`, or directly via command line:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mkdir -P /docker/authentik-outpost
|
sudo mkdir -P /docker/authentik-outpost
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -430,7 +431,7 @@ Create the `compose.yaml` file or paste the configuration directly into Dockge i
|
|||||||
|
|
||||||
Via command line:
|
Via command line:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/authentik-outpost/compose.yaml
|
sudo vi /docker/authentik-outpost/compose.yaml
|
||||||
```
|
```
|
||||||
Enter edit mode by pressing `i` and paste the following configuration, updating the version in `{AUTHENTIK_TAG:proxy:2024.2.3}`{lang=properties} to match your Authentik server version.
|
Enter edit mode by pressing `i` and paste the following configuration, updating the version in `{AUTHENTIK_TAG:proxy:2024.2.3}`{lang=properties} to match your Authentik server version.
|
||||||
@@ -457,7 +458,7 @@ services:
|
|||||||
|
|
||||||
Go to the SWAG stack on the remote machine (or edit directly using Dockge) and add the authentik-outpost network in the configuration file like this (see `networks` section):
|
Go to the SWAG stack on the remote machine (or edit directly using Dockge) and add the authentik-outpost network in the configuration file like this (see `networks` section):
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/compose.yaml
|
sudo vi /docker/swag/compose.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -488,7 +489,7 @@ If using [Dockge](/serveex/core/docker/#installer-dockge-pour-gérer-et-déploye
|
|||||||
|
|
||||||
Otherwise, via terminal:
|
Otherwise, via terminal:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
cd /docker/swag/
|
cd /docker/swag/
|
||||||
sudo docker compose up -d
|
sudo docker compose up -d
|
||||||
```
|
```
|
||||||
@@ -497,7 +498,7 @@ Create (or fill using Dockge) the `.env` file in the `authentik-outpost` directo
|
|||||||
|
|
||||||
Via command line:
|
Via command line:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/authentik-outpost/.env
|
sudo vi /docker/authentik-outpost/.env
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -521,7 +522,7 @@ If using Dockge, deploy the stack.
|
|||||||
|
|
||||||
Otherwise, via terminal:
|
Otherwise, via terminal:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
cd /docker/authentik-outpost/
|
cd /docker/authentik-outpost/
|
||||||
sudo docker compose up -d
|
sudo docker compose up -d
|
||||||
```
|
```
|
||||||
@@ -532,7 +533,7 @@ Now, let’s configure SWAG.
|
|||||||
|
|
||||||
Open the `authentik-server.conf` file:
|
Open the `authentik-server.conf` file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/authentik-server.conf
|
sudo vi /docker/swag/config/nginx/authentik-server.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -551,24 +552,24 @@ Then configure the applications to protect as you did on your main server, wheth
|
|||||||
---
|
---
|
||||||
On the source machine, dump the database:
|
On the source machine, dump the database:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo docker exec authentik-postgres pg_dump -U authentik -F t authentik > /path/to/mydb.tar
|
sudo docker exec authentik-postgres pg_dump -U authentik -F t authentik > /path/to/mydb.tar
|
||||||
```
|
```
|
||||||
|
|
||||||
Then transfer it to the target machine. On the target machine, copy the file into the Docker container:
|
Then transfer it to the target machine. On the target machine, copy the file into the Docker container:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
cp /path/to/mydb.tar authentik-postgres:/path/to/wherever
|
cp /path/to/mydb.tar authentik-postgres:/path/to/wherever
|
||||||
```
|
```
|
||||||
|
|
||||||
(Optional) Purge existing tables:
|
(Optional) Purge existing tables:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo docker exec -i authentik-postgres psql -U authentik -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'authentik' AND pid <> pg_backend_pid();" && sudo docker exec -i authentik-postgres psql -U authentik -d postgres -c "DROP DATABASE IF EXISTS authentik;" && sudo docker exec -i authentik-postgres psql -U authentik -d postgres -c "CREATE DATABASE authentik;"
|
sudo docker exec -i authentik-postgres psql -U authentik -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'authentik' AND pid <> pg_backend_pid();" && sudo docker exec -i authentik-postgres psql -U authentik -d postgres -c "DROP DATABASE IF EXISTS authentik;" && sudo docker exec -i authentik-postgres psql -U authentik -d postgres -c "CREATE DATABASE authentik;"
|
||||||
```
|
```
|
||||||
|
|
||||||
Restore the database:
|
Restore the database:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo docker exec authentik-postgresql pg_restore -U authentik -d authentik /path/to/wherever/mydb.tar
|
sudo docker exec authentik-postgresql pg_restore -U authentik -d authentik /path/to/wherever/mydb.tar
|
||||||
```
|
```
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Cloudflare Zero Trust
|
title: Cloudflare Zero Trust
|
||||||
|
description: Use Cloudflare Tunnels and Zero Trust to expose homelab services without opening ports — configure SWAG and manage multiple tunnels.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -97,7 +98,7 @@ Create a file `tunnelconfig.yml` to reference in your SWAG `compose.yaml`.
|
|||||||
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using the terminal.
|
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using the terminal.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/tunnelconfig.yml
|
sudo vi /docker/swag/config/tunnelconfig.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ Now configure _Cloudflare Real IP_.
|
|||||||
|
|
||||||
Open the `nginx.conf` file:
|
Open the `nginx.conf` file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/nginx.conf
|
sudo vi /docker/swag/config/nginx/nginx.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Uptime-Kuma
|
title: Uptime-Kuma
|
||||||
|
description: Install Uptime-Kuma to monitor your self-hosted services uptime, set up alerts, and optionally protect the dashboard with Authentik.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -22,7 +23,7 @@ main:
|
|||||||
---
|
---
|
||||||
Folder structure
|
Folder structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── uptime-kuma
|
└── uptime-kuma
|
||||||
@@ -36,7 +37,7 @@ Open Dockge, click on `compose`, name the stack `uptime-kuma`, then copy and pas
|
|||||||
---
|
---
|
||||||
services:
|
services:
|
||||||
uptime-kuma:
|
uptime-kuma:
|
||||||
image: louislam/uptime-kuma:1
|
image: louislam/uptime-kuma:2-slim
|
||||||
container_name: uptime-kuma
|
container_name: uptime-kuma
|
||||||
volumes:
|
volumes:
|
||||||
- /docker/uptime-kuma/uptime-kuma-data:/app/data
|
- /docker/uptime-kuma/uptime-kuma-data:/app/data
|
||||||
@@ -84,7 +85,7 @@ In the Swag folders, create the `stats.subdomain.conf` file.
|
|||||||
you can use [File Browser](/serveex/files/file-browser) to browse and edit your files instead of using terminal commands.
|
you can use [File Browser](/serveex/files/file-browser) to browse and edit your files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/stats.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/stats.subdomain.conf
|
||||||
```
|
```
|
||||||
Enter insert mode with `i` and paste the following config:
|
Enter insert mode with `i` and paste the following config:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Dozzle
|
title: Dozzle
|
||||||
|
description: Install Dozzle to monitor Docker container logs in real time from a clean web interface, exposed via SWAG.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -21,7 +22,7 @@ main:
|
|||||||
---
|
---
|
||||||
Folder structure
|
Folder structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── dozzle
|
└── dozzle
|
||||||
@@ -114,7 +115,7 @@ In the Swag folder, create the `dozzle.subdomain.conf` file.
|
|||||||
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to browse and edit files instead of using terminal commands.
|
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to browse and edit files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/dozzle.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/dozzle.subdomain.conf
|
||||||
```
|
```
|
||||||
Enter edit mode by pressing `i` and paste the configuration below:
|
Enter edit mode by pressing `i` and paste the configuration below:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Speedtest Tracker
|
title: Speedtest Tracker
|
||||||
|
description: Install Speedtest Tracker to automatically measure and log your internet connection speed over time, exposed with SWAG.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -27,7 +28,7 @@ main:
|
|||||||
|
|
||||||
File structure:
|
File structure:
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── speedtest-tracker
|
└── speedtest-tracker
|
||||||
@@ -37,7 +38,7 @@ root
|
|||||||
|
|
||||||
In a terminal, generate a key using the following command:
|
In a terminal, generate a key using the following command:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
echo -n 'base64:'; openssl rand -base64 32;
|
echo -n 'base64:'; openssl rand -base64 32;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
container_name: speedtest-tracker
|
container_name: speedtest-tracker
|
||||||
ports:
|
ports:
|
||||||
- ${PORT}$:80
|
- ${PORT}:80
|
||||||
environment:
|
environment:
|
||||||
- PUID=${PUID}
|
- PUID=${PUID}
|
||||||
- PGID=${GUID}
|
- PGID=${GUID}
|
||||||
@@ -67,7 +68,7 @@ services:
|
|||||||
|
|
||||||
Find your `PUID` and `GUID` by running the following command:
|
Find your `PUID` and `GUID` by running the following command:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
id yourusername
|
id yourusername
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ In the `.env` file, set the variable `API_KEY` with the key you generated and ad
|
|||||||
|
|
||||||
```properties
|
```properties
|
||||||
SCHEDULE=15 */6 * * * # every 6 hours
|
SCHEDULE=15 */6 * * * # every 6 hours
|
||||||
KEY=base64:zihejehkj8_nzhY/OjeieR= # your key
|
API_KEY=base64:zihejehkj8_nzhY/OjeieR= # your key
|
||||||
PUID=1000
|
PUID=1000
|
||||||
GUID=1000
|
GUID=1000
|
||||||
PORT=3225 # port to access the web UI
|
PORT=3225 # port to access the web UI
|
||||||
@@ -104,7 +105,7 @@ Now we want to expose Speedtest Tracker to the internet so you can access it rem
|
|||||||
|
|
||||||
Open the `speedtest.subdomain.conf` file:
|
Open the `speedtest.subdomain.conf` file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/speedtest.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/speedtest.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Beszel
|
title: Beszel
|
||||||
|
description: Install Beszel to monitor server CPU, RAM, disk, and network metrics — including remote servers — with a lightweight web dashboard.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -26,7 +27,7 @@ Beszel includes a hub with a web UI and an agent that collects data from your se
|
|||||||
|
|
||||||
Folder structure
|
Folder structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── beszel
|
└── beszel
|
||||||
@@ -191,7 +192,7 @@ In Swag’s config folders, create `beszel.subdomain.conf`.
|
|||||||
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to browse and edit files instead of terminal commands.
|
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to browse and edit files instead of terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/beszel.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/beszel.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: UpSnap
|
title: UpSnap
|
||||||
|
description: Install UpSnap to remotely wake up machines on your local network via Wake-on-LAN, exposed with SWAG.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -22,7 +23,7 @@ main:
|
|||||||
|
|
||||||
Folder structure
|
Folder structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── upsnap
|
└── upsnap
|
||||||
@@ -129,7 +130,7 @@ In the Swag folders, create the file `upsnap.subdomain.conf`.
|
|||||||
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate your files and edit documents instead of using terminal commands.
|
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate your files and edit documents instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/upsnap.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/upsnap.subdomain.conf
|
||||||
```
|
```
|
||||||
Enter edit mode by pressing `i`, and paste the following configuration:
|
Enter edit mode by pressing `i`, and paste the following configuration:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Plex
|
title: Plex
|
||||||
|
description: Install Plex Media Server with Tautulli on your homelab to stream movies and TV shows from anywhere on all your devices.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -34,7 +35,7 @@ We'll also install [Tautulli](https://docs.linuxserver.io/images/docker-tautulli
|
|||||||
## Install Plex
|
## Install Plex
|
||||||
---
|
---
|
||||||
Folder structure:
|
Folder structure:
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
├── docker
|
├── docker
|
||||||
│ ├── plex
|
│ ├── plex
|
||||||
@@ -114,7 +115,7 @@ services:
|
|||||||
|
|
||||||
Find your PUID and GUID by running:
|
Find your PUID and GUID by running:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
id username
|
id username
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -211,7 +212,7 @@ Copy and rename the file `tautulli.subdomain.conf.sample` to `tautulli.subdomain
|
|||||||
✨ **Tip:** Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
|
✨ **Tip:** Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo cp /docker/swag/config/nginx/proxy-confs/tautulli.subdomain.conf.sample /docker/swag/config/nginx/proxy-confs/tautulli.subdomain.conf
|
sudo cp /docker/swag/config/nginx/proxy-confs/tautulli.subdomain.conf.sample /docker/swag/config/nginx/proxy-confs/tautulli.subdomain.conf
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/tautulli.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/tautulli.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Qbittorrent
|
title: Qbittorrent
|
||||||
|
description: Install qBittorrent with Gluetun and ProtonVPN to download torrents securely behind a VPN on your self-hosted server.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -13,7 +14,7 @@ main:
|
|||||||
- Securely connect to the BitTorrent network using Gluetun and Proton VPN
|
- Securely connect to the BitTorrent network using Gluetun and Proton VPN
|
||||||
::
|
::
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
To safely download your favorite media, we'll build a system using:
|
To safely download your favorite media, we'll build a system using:
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ Here’s the system we’ll set up:
|
|||||||
---
|
---
|
||||||
Folder structure
|
Folder structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
├── docker
|
├── docker
|
||||||
│ └── seedbox
|
│ └── seedbox
|
||||||
@@ -59,11 +60,11 @@ Open Dockge, click on `compose`, and name the stack `seedbox`. Paste the followi
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
qbit:
|
qbit:
|
||||||
image: ghcr.io/linuxserver/qbittorrent:latest
|
image: ghcr.io/linuxserver/qbittorrent:libtorrentv1
|
||||||
container_name: qbittorrent
|
container_name: qbittorrent
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
network_mode: service:gluetun
|
network_mode: service:gluetun
|
||||||
mem_limit: 1g
|
mem_limit: 4g
|
||||||
environment:
|
environment:
|
||||||
- DOCKER_MODS=ghcr.io/gabe565/linuxserver-mod-vuetorrent|ghcr.io/t-anc/gsp-qbittorent-gluetun-sync-port-mod:main
|
- DOCKER_MODS=ghcr.io/gabe565/linuxserver-mod-vuetorrent|ghcr.io/t-anc/gsp-qbittorent-gluetun-sync-port-mod:main
|
||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
@@ -80,10 +81,10 @@ services:
|
|||||||
- gluetun
|
- gluetun
|
||||||
|
|
||||||
gluetun:
|
gluetun:
|
||||||
image: qmcgaw/gluetun:v3.40
|
image: qmcgaw/gluetun:v3.41.3
|
||||||
container_name: gluetun
|
container_name: gluetun
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
mem_limit: 1g
|
mem_limit: 4g
|
||||||
volumes:
|
volumes:
|
||||||
- /docker/gluetun/config.toml:/gluetun/auth/config.toml:ro
|
- /docker/gluetun/config.toml:/gluetun/auth/config.toml:ro
|
||||||
devices:
|
devices:
|
||||||
@@ -128,19 +129,19 @@ We now need to allow the mod to fetch info from Gluetun, which only allows encry
|
|||||||
|
|
||||||
Open a terminal to generate the authentication key:
|
Open a terminal to generate the authentication key:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo docker run --rm qmcgaw/gluetun genkey
|
sudo docker run --rm qmcgaw/gluetun genkey
|
||||||
```
|
```
|
||||||
|
|
||||||
Note the key, then create the `/docker/gluetun` folder:
|
Note the key, then create the `/docker/gluetun` folder:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo mkdir /docker/gluetun
|
sudo mkdir /docker/gluetun
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the `config.toml` file:
|
Create the `config.toml` file:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/gluetun/config.toml
|
sudo vi /docker/gluetun/config.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -149,7 +150,7 @@ Press `i` to edit and enter:
|
|||||||
```toml
|
```toml
|
||||||
[[roles]]
|
[[roles]]
|
||||||
name = "t-anc/GSP-Qbittorent-Gluetun-sync-port-mod"
|
name = "t-anc/GSP-Qbittorent-Gluetun-sync-port-mod"
|
||||||
routes = ["GET /v1/openvpn/portforwarded"]
|
routes = ["GET /v1/portforward"]
|
||||||
auth = "apikey"
|
auth = "apikey"
|
||||||
apikey = "your_key_here" # key you just generated
|
apikey = "your_key_here" # key you just generated
|
||||||
```
|
```
|
||||||
@@ -253,7 +254,7 @@ Now create/edit `seedbox.subdomain.conf`.
|
|||||||
✨ __Terminal-free tip:__ use [File Browser](/serveex/files/file-browser) to edit files instead of using the terminal.
|
✨ __Terminal-free tip:__ use [File Browser](/serveex/files/file-browser) to edit files instead of using the terminal.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/seedbox.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/seedbox.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Automation
|
title: Automation
|
||||||
|
description: Automate media downloads with the Servarr stack — Radarr, Sonarr, Bazarr, Prowlarr, and Overseerr for movies and TV shows.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -29,7 +30,7 @@ We’ll start by deploying the stack and then proceed to configure each app and
|
|||||||
|
|
||||||
Folder structure:
|
Folder structure:
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
├── docker
|
├── docker
|
||||||
│ ├── plex
|
│ ├── plex
|
||||||
@@ -160,8 +161,11 @@ services:
|
|||||||
bazarr:
|
bazarr:
|
||||||
image: lscr.io/linuxserver/bazarr:latest
|
image: lscr.io/linuxserver/bazarr:latest
|
||||||
container_name: bazarr
|
container_name: bazarr
|
||||||
environment: null
|
restart: unless-stopped
|
||||||
restart: unless-stopped - PUID=1000 - PGID=1000 - TZ=Europe/Paris
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=Europe/Paris
|
||||||
volumes:
|
volumes:
|
||||||
- /docker/bazarr/config:/config
|
- /docker/bazarr/config:/config
|
||||||
- ${MEDIA_PATH}:/media
|
- ${MEDIA_PATH}:/media
|
||||||
@@ -300,7 +304,7 @@ In *Settings > Apps*, add Radarr and Sonarr with the following details:
|
|||||||
---
|
---
|
||||||
Bazarr is an app that automatically searches for the correct subtitles in your preferred languages for all the movies and TV shows added by Radarr and Sonarr.
|
Bazarr is an app that automatically searches for the correct subtitles in your preferred languages for all the movies and TV shows added by Radarr and Sonarr.
|
||||||
|
|
||||||
Go to `http://yourserverip:9696`.
|
Go to `http://yourserverip:6767`.
|
||||||
|
|
||||||
::alert{type="danger"}
|
::alert{type="danger"}
|
||||||
:::list{type="danger"}
|
:::list{type="danger"}
|
||||||
@@ -430,7 +434,7 @@ Create and edit the file `films.subdomain.conf`:
|
|||||||
✨ __Tip:__ you can use [File Browser](/serveex/files/file-browser) to browse and edit files instead of using terminal commands.
|
✨ __Tip:__ you can use [File Browser](/serveex/files/file-browser) to browse and edit files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/films.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/films.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Immich
|
title: Immich
|
||||||
|
description: Install Immich, a self-hosted alternative to Google Photos and iCloud with face recognition, geolocation, and multi-device sync.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -19,7 +20,7 @@ main:
|
|||||||
---
|
---
|
||||||
Folder structure
|
Folder structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── immich
|
└── immich
|
||||||
@@ -96,7 +97,7 @@ In the SWAG folders, create a file named `immich.subdomain.conf`.
|
|||||||
:::
|
:::
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/immich.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/immich.subdomain.conf
|
||||||
```
|
```
|
||||||
Press `i` to enter insert mode, then paste the following configuration:
|
Press `i` to enter insert mode, then paste the following configuration:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Nextcloud
|
title: Nextcloud
|
||||||
|
description: Install Nextcloud to self-host your files, photos, and calendar — a privacy-friendly alternative to Google Drive, OneDrive, and iCloud.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -25,7 +26,7 @@ main:
|
|||||||
|
|
||||||
File structure:
|
File structure:
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── nextcloud
|
└── nextcloud
|
||||||
@@ -63,7 +64,7 @@ services:
|
|||||||
|
|
||||||
Find your `PUID` and `GUID` by running the following command:
|
Find your `PUID` and `GUID` by running the following command:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
id username
|
id username
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -125,7 +126,7 @@ In Nextcloud’s files, edit the `config.php` file:
|
|||||||
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
|
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/nextcloud/config/www/nextcloud/config/config.php
|
sudo vi /docker/nextcloud/config/www/nextcloud/config/config.php
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -151,7 +152,7 @@ Press `Esc`, then save and exit by typing `:x` and hitting Enter.
|
|||||||
|
|
||||||
In Swag’s folders, create the file `nextcloud.subdomain.conf`:
|
In Swag’s folders, create the file `nextcloud.subdomain.conf`:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/nextcloud.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/nextcloud.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: File Browser
|
title: File Browser
|
||||||
|
description: Install File Browser to browse and manage your server files from a web interface, exposed securely with SWAG.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -98,7 +99,7 @@ Restart the stack by clicking "deploy" and wait for SWAG to fully initialize.
|
|||||||
|
|
||||||
In the Swag folders, create the file `files.subdomain.conf`.
|
In the Swag folders, create the file `files.subdomain.conf`.
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/files.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/files.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Pingvin
|
title: Pingvin
|
||||||
|
description: Install Pingvin Share, a self-hosted file sharing platform to send files securely without relying on WeTransfer or Google Drive.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -118,7 +119,7 @@ Dans les dossiers de Swag, créez le fichier `pingvin.subdomain.conf`.
|
|||||||
:::
|
:::
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/pingvin.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/pingvin.subdomain.conf
|
||||||
```
|
```
|
||||||
Entrez en modification avec la touche `i` et collez la configuration ci-dessous :
|
Entrez en modification avec la touche `i` et collez la configuration ci-dessous :
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Code-Server
|
title: Code-Server
|
||||||
|
description: Install code-server to run VS Code in your browser from your homelab — mount folders and expose it securely with SWAG.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -28,7 +29,7 @@ main:
|
|||||||
|
|
||||||
Folder structure
|
Folder structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
├── docker
|
├── docker
|
||||||
│ └── code-server
|
│ └── code-server
|
||||||
@@ -71,13 +72,13 @@ services:
|
|||||||
|
|
||||||
Choose a password and generate its hash:
|
Choose a password and generate its hash:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
echo -n "yourpassword" | npx argon2-cli -e
|
echo -n "yourpassword" | npx argon2-cli -e
|
||||||
```
|
```
|
||||||
|
|
||||||
Save the result carefully. Find your PUID and GUID with:
|
Save the result carefully. Find your PUID and GUID with:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
id yourusername
|
id yourusername
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ Inside the Swag config folders, create the file `code.subdomain.conf`.
|
|||||||
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit your files instead of using terminal commands.
|
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit your files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/code.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/code.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Gitea
|
title: Gitea
|
||||||
|
description: Install Gitea, a lightweight self-hosted Git service to manage your code repositories privately on your own server.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -21,7 +22,7 @@ main:
|
|||||||
---
|
---
|
||||||
Folder structure
|
Folder structure
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── gitea
|
└── gitea
|
||||||
@@ -110,7 +111,7 @@ Inside the Swag folders, create the file `gitea.subdomain.conf`.
|
|||||||
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit your files instead of using terminal commands.
|
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit your files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/gitea.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/gitea.subdomain.conf
|
||||||
```
|
```
|
||||||
Press `i` to enter edit mode and paste the configuration below:
|
Press `i` to enter edit mode and paste the configuration below:
|
||||||
@@ -176,7 +177,7 @@ Press `Esc`, then save and exit by typing `:x` and hitting `Enter`.
|
|||||||
|
|
||||||
Now open the `app.ini` file from the container's file system:
|
Now open the `app.ini` file from the container's file system:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/gitea/data/gitea/conf/app.ini
|
sudo vi /docker/gitea/data/gitea/conf/app.ini
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: IT Tools
|
title: IT Tools
|
||||||
|
description: Install IT Tools, a self-hosted collection of handy utilities for developers — converters, encoders, formatters, and more.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -100,7 +101,7 @@ Inside the Swag folders, create the file `tools.subdomain.conf`.
|
|||||||
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit your files instead of using terminal commands.
|
✨ __Tip:__ You can use [File Browser](/serveex/files/file-browser) to navigate and edit your files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/tools.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/tools.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Adguard Home
|
title: Adguard Home
|
||||||
|
description: Install AdGuard Home for network-wide ad and tracker blocking with DNS-over-HTTPS, client management, and custom filtering rules.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -40,7 +41,7 @@ This is how ads and malicious domains are blocked—Adguard blocks only the bad
|
|||||||
---
|
---
|
||||||
Folder structure:
|
Folder structure:
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── adguard
|
└── adguard
|
||||||
@@ -147,7 +148,7 @@ Create and open the file `adguard.subdomain.conf`
|
|||||||
You can use [File Browser](/serveex/files/file-browser) to browse and edit files instead of using terminal commands.
|
You can use [File Browser](/serveex/files/file-browser) to browse and edit files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/adguard.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/adguard.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Vaultwarden
|
title: Vaultwarden
|
||||||
|
description: Install Vaultwarden, a self-hosted Bitwarden-compatible password manager to replace Google or Apple password managers across all your devices.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -21,7 +22,7 @@ Vaultwarden is a fork of [Bitwarden](https://bitwarden.com/fr-fr/help/).
|
|||||||
---
|
---
|
||||||
Folder structure:
|
Folder structure:
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
root
|
root
|
||||||
└── docker
|
└── docker
|
||||||
└── vaultwarden
|
└── vaultwarden
|
||||||
@@ -75,7 +76,7 @@ services:
|
|||||||
|
|
||||||
Next, generate a password hash to put in the `TOKEN` variable in `.env`:
|
Next, generate a password hash to put in the `TOKEN` variable in `.env`:
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
echo -n 'yourpassword' | argon2 "$(openssl rand -base64 32)" -e -id -k 65540 -t 3 -p 4
|
echo -n 'yourpassword' | argon2 "$(openssl rand -base64 32)" -e -id -k 65540 -t 3 -p 4
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -143,7 +144,7 @@ In SWAG's config folder, create the file `vault.subdomain.conf`:
|
|||||||
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
|
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
|
||||||
::
|
::
|
||||||
|
|
||||||
```shell
|
```sh
|
||||||
sudo vi /docker/swag/config/nginx/proxy-confs/vault.subdomain.conf
|
sudo vi /docker/swag/config/nginx/proxy-confs/vault.subdomain.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
icon: lucide:bookmark
|
icon: lucide:bookmark
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Introduction
|
title: Introduction
|
||||||
|
description: Introduction to Stockeex — a personal project for stock and inventory management. Documentation coming soon.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Nvidia Stock Bot
|
title: Nvidia Stock Bot
|
||||||
|
description: A Python bot that monitors GPU stock availability in real time and sends Discord alerts — built during the RTX 5000 series launch shortage.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Adguard CIDRE
|
title: Adguard CIDRE
|
||||||
|
description: A Python script to sync AdGuard Home CIDR allowlists automatically, securing your self-hosted DNS server exposed to the internet.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: Lumeex
|
||||||
|
description: Lumeex is a static photo gallery site generator built with Python — minimalist, lightweight, and fully customizable without a CMS.
|
||||||
|
main:
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<img src="https://git.djeex.fr/Djeex/lumeex/raw/branch/main/illustration/logo.svg" alt="Lumeex Screenshot" width="300"/>
|
||||||
|
</div>
|
||||||
|
<p/>
|
||||||
|
<div align="center">
|
||||||
|
<p>Yet another minimalist, lightweight photo gallery static site generator.</p>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
<div align="center">
|
||||||
|
<img src="https://git.djeex.fr/Djeex/lumeex/raw/branch/main/illustration/lumeex.png" alt="Lumeex Screenshot" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Amateur photographer that I am, I spent several weeks looking for a framework with a photo gallery that could outshine Instagram. I wanted something that showcased the photos rather than the author, and that made every visit unique by loading the images in random order—while still allowing filtering and sorting by tag or combinations of tags.
|
||||||
|
|
||||||
|
In the end, I found nothing that did exactly what I wanted. And when something came close, it was always through heavy, bloated CMS platforms. So I decided to make a static site by hand, the old-school way, with Notepad++. Being fairly comfortable with HTML/CSS and a bit of JavaScript, I quickly came up with something nice during my vacation, between beach sessions. After all, a good craftsman should have good tools—and there’s no better tool than one you make yourself.
|
||||||
|
|
||||||
|
Then I thought it might be a good idea to automate certain tasks—like generating favicon formats, resizing and converting images, creating the gallery automatically instead of entering everything by hand, and generating `robots.txt` and `sitemap` files… so I turned back to Python.
|
||||||
|
|
||||||
|
Eventually, after getting good results, I figured I might as well go all the way: build a complete framework for generating a static site photo gallery, where all you need to do is fill in your site’s information in a config file and tweak the visuals a bit—without touching the code.
|
||||||
|
|
||||||
|
That’s how **Lum[eex]{style="color: #1ad6ff"}** was born.
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<img src="https://git.djeex.fr/Djeex/lumeex/raw/branch/main/illustration/lumeex-webui.png" alt="Lumeex Screenshot" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
::card-grid{grid-template-columns="repeat(2, minmax(0, 1fr));"}
|
||||||
|
#title
|
||||||
|
Et voilà!
|
||||||
|
|
||||||
|
#root
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
|
||||||
|
#default
|
||||||
|
|
||||||
|
::card{icon=noto:open-book}
|
||||||
|
#title
|
||||||
|
__Documentation__
|
||||||
|
#description
|
||||||
|
[Check out the doc](https://lumeex.djeex.fr)
|
||||||
|
::
|
||||||
|
|
||||||
|
::card{icon=simple-icons:gitea style="color: #9ee773;"}
|
||||||
|
#title
|
||||||
|
__Repository__
|
||||||
|
#description
|
||||||
|
[See the repo](https://git.djeex.fr/Djeex/lumeex)
|
||||||
|
::
|
||||||
|
|
||||||
|
::card{icon=fluent-color:design-ideas-48}
|
||||||
|
#title
|
||||||
|
__Demo__
|
||||||
|
#description
|
||||||
|
[Explore the demo](https://modern.djeex.fr)
|
||||||
|
::
|
||||||
|
::
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: Instameex
|
||||||
|
description: Instameex is a Docker-based tool to merge SDR and HDR photo exports into a proper gain-map JPEG ready for Instagram HDR upload.
|
||||||
|
main:
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<img src="https://git.djeex.fr/Djeex/instameex/raw/branch/main/src/assets/img/logo-long.svg" alt="Lumeex Screenshot" width="300"/>
|
||||||
|
</div>
|
||||||
|
<p/>
|
||||||
|
<div align="center">
|
||||||
|
<p>Mix your SDR and HDR exports into an Instagram-ready HDR photo.</p>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
<div align="center">
|
||||||
|
<img src="https://git.djeex.fr/Djeex/instameex/raw/branch/main/illustration/instameex-illustration.png" width="640" alt="Instameex Screenshot" />
|
||||||
|
</div>
|
||||||
|
---
|
||||||
|
|
||||||
|
Nothing is more frustrating than Instagram's HDR handling. It compresses and destroys gain maps, and the slightest change in aspect ratio or size simply strips HDR out entirely. As for Lightroom, its "SDR preview" system is frankly unacceptable, it makes it impossible to get consistent results. Until now, posting on Instagram meant choosing between decent SDR with broken HDR, or the other way around.
|
||||||
|
|
||||||
|
Why not simply edit your SDR file to perfection on one side, your HDR file on the other, and then recalculate a gain map from those two perfect files?
|
||||||
|
A few pioneers have already gone down that road, notably with an [Adobe Lightroom Classic](https://github.com/karachungen/lightroom-plugin-export-hdr) plugin. Judge me if you want, but I only use Lightroom CC, which does not support plugins.
|
||||||
|
|
||||||
|
I drew inspiration from a [fork of the original project](https://github.com/kostis-kounadis/instagram-hdr-assembler), the one that eventually became the LrC plugin, to build a frontend that can be easily deployed with Docker. Let's be honest: it was also a great excuse to put my Claude Code subscription to the test. And I have to say, watching it spin up its own environments, run end-to-end tests, self-correct its code, and write detailed summaries is genuinely impressive. I still reviewed everything myself, don't worry. I also learned a great deal about HDR fundamentals, gain maps, HLG/PQ tone curves, color spaces, and more.
|
||||||
|
|
||||||
|
In short, here is what my workflow now looks like for posting on Instagram:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Allow me to introduce **Instam[eex]{style="color: #1ad6ff"}**
|
||||||
|
|
||||||
|
---
|
||||||
|
::card-grid{grid-template-columns="repeat(2, minmax(0, 1fr));"}
|
||||||
|
#title
|
||||||
|
And here is the result
|
||||||
|
|
||||||
|
#root
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
|
||||||
|
#default
|
||||||
|
::card
|
||||||
|
#title
|
||||||
|
🐋 __Instameex__
|
||||||
|
#description
|
||||||
|
[Open the repository](https://git.djeex.fr/Djeex/instameex)
|
||||||
|
::
|
||||||
|
|
||||||
|
::card
|
||||||
|
#title
|
||||||
|
🌍 __Online version__
|
||||||
|
#description
|
||||||
|
[Convert online](https://instameex.djeex.fr)
|
||||||
|
::
|
||||||
|
::
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: Servarr corrector
|
title: Servarr corrector
|
||||||
|
description: A bash script to detect and fix duplicate media files in Sonarr and Radarr libraries by replacing copies with hardlinks to reclaim disk space.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -14,7 +15,7 @@ So I restructured my directories, manually updated every path in Qbittorrent, Pl
|
|||||||
|
|
||||||
My directory structure:
|
My directory structure:
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
.
|
.
|
||||||
└── media
|
└── media
|
||||||
├── seedbox
|
├── seedbox
|
||||||
@@ -42,7 +43,7 @@ Spare you the endless Q&A with ChatGPT—I was disappointed. Qwen3 was much clea
|
|||||||
|
|
||||||
To test, I first asked for a script that only lists and compares:
|
To test, I first asked for a script that only lists and compares:
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Create an associative array to store duplicates
|
# Create an associative array to store duplicates
|
||||||
@@ -88,7 +89,7 @@ Again, ChatGPT disappointed. Despite my requests, it created hardlinks *before*
|
|||||||
|
|
||||||
Quick stopover to Qwen3, RTX 5090 in overdrive, and bam—much better result. Yes, it kept ChatGPT-style emojis, but here it is:
|
Quick stopover to Qwen3, RTX 5090 in overdrive, and bam—much better result. Yes, it kept ChatGPT-style emojis, but here it is:
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
echo "🔍 Step 1: Indexing original files in /media/seedbox..."
|
echo "🔍 Step 1: Indexing original files in /media/seedbox..."
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
navigation: true
|
navigation: true
|
||||||
title: LUKS Backup
|
title: LUKS Backup
|
||||||
|
description: A bash script to automatically dump LUKS headers from all encrypted disks, identify them by serial number, and store them in an encrypted archive.
|
||||||
main:
|
main:
|
||||||
fluid: false
|
fluid: false
|
||||||
---
|
---
|
||||||
@@ -22,7 +23,7 @@ This script:
|
|||||||
* Encrypts the archive with that password
|
* Encrypts the archive with that password
|
||||||
* Deletes the unencrypted archive
|
* Deletes the unencrypted archive
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Directory where LUKS headers will be backed up
|
# Directory where LUKS headers will be backed up
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: Socat Proxy
|
||||||
|
description: Use socat to proxy the Docker socket through Docker Socket Proxy, allowing Beszel to collect container stats without exposing the full Docker socket.
|
||||||
|
main:
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
|
||||||
|
# Socat Proxy
|
||||||
|
---
|
||||||
|
|
||||||
|
This project addresses a common use case:
|
||||||
|
|
||||||
|
- I have [Beszel](https://beszel.dev/), a monitoring container running in host mode, which requires access to the Docker socket to collect container statistics.
|
||||||
|
- To avoid exposing the Docker socket fully to Beszel, I use [Docker Socket Proxy](https://github.com/Tecnativa/docker-socket-proxy), a container that sits between the Docker socket and the consuming container. It filters requests by setting appropriate permissions, preventing full exposure of the Docker socket.
|
||||||
|
|
||||||
|
The problem arises when **Beszel** runs in host mode. In that case, it must connect directly to **Docker Socket Proxy** on a host port, meaning the proxy’s port is exposed. This allows any container or application on the host to access it and use the Docker socket.
|
||||||
|
|
||||||
|
This is where [Socat Proxy](https://git.djeex.fr/Djeex/socat-proxy) comes in. It is a container that:
|
||||||
|
|
||||||
|
- Creates a UNIX socket
|
||||||
|
- Listens on this socket
|
||||||
|
- Forwards requests to Docker Socket Proxy and back
|
||||||
|
- Replaces the real Docker socket by exposing the proxy socket in the target container via a bind mount (in this case, Beszel)
|
||||||
|
|
||||||
|
With this setup, Docker Socket Proxy communicates with Socat Proxy in their isolated bridge network, while the UNIX socket bind-mounted on the host has restricted permissions, preventing access from other containers or applications.
|
||||||
|
|
||||||
|
In short:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
For example, with Beszel, the configuration would look like this:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
socat-proxy:
|
||||||
|
image: git.djeex.fr/djeex/socat-proxy:latest
|
||||||
|
container_name: socat-proxy-beszel
|
||||||
|
environment:
|
||||||
|
- TARGET_HOST=${TARGET_HOST}
|
||||||
|
- TARGET_PORT=${TARGET_PORT}
|
||||||
|
- UNIX_SOCKET_PATH=${UNIX_SOCKET_PATH}
|
||||||
|
- HOST_SOCKET_PATH=${HOST_SOCKET_PATH}
|
||||||
|
- UNIX_SOCKET_NAME=${UNIX_SOCKET_NAME}
|
||||||
|
volumes:
|
||||||
|
- ${HOST_SOCKET_PATH}:${UNIX_SOCKET_PATH}
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- ${TARGET_HOST}
|
||||||
|
|
||||||
|
socket-proxy:
|
||||||
|
image: lscr.io/linuxserver/socket-proxy:latest
|
||||||
|
container_name: ${TARGET_HOST}
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
environment:
|
||||||
|
- CONTAINERS=1
|
||||||
|
- INFO=1
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
restart: unless-stopped
|
||||||
|
read_only: true
|
||||||
|
tmpfs:
|
||||||
|
- /run
|
||||||
|
|
||||||
|
beszel-agent:
|
||||||
|
image: henrygd/beszel-agent:latest
|
||||||
|
container_name: beszel-agent
|
||||||
|
restart: unless-stopped
|
||||||
|
network_mode: host
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
volumes:
|
||||||
|
- ${HOST_SOCKET_PATH}/${UNIX_SOCKET_NAME}:/var/run/docker.sock:ro
|
||||||
|
environment:
|
||||||
|
- #... your Beszel environment variables
|
||||||
|
depends_on:
|
||||||
|
- socat-proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
More information is available on the repository:
|
||||||
|
|
||||||
|
::card
|
||||||
|
#title
|
||||||
|
🐋 **Socat Proxy**
|
||||||
|
#description
|
||||||
|
[A lightweight bind-mount socket proxy](https://git.djeex.fr/Djeex/socat-proxy)
|
||||||
|
::
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: HotDisk
|
||||||
|
description: A bash script that monitors hard drive temperatures and automatically shuts down the server when disks stay above a safe threshold for too long.
|
||||||
|
main:
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
|
||||||
|
# HotDisk
|
||||||
|
---
|
||||||
|
|
||||||
|
When you have a NAS with several drives sitting in a laundry room, temperatures can quickly rise.
|
||||||
|
Hard drives are very sensitive to heat and can suffer serious damage if they exceed a certain temperature threshold for too long.
|
||||||
|
After a particularly hot summer that caused a few cold sweats while monitoring my drives’ temperatures, I started looking for a way to automatically shut down the server when disk temperatures stay above their safe limit for an extended period.
|
||||||
|
|
||||||
|
Since I couldn’t find a convincing solution, I decided to build my own.
|
||||||
|
|
||||||
|
- The script reads SMART temperature data from all SATA drives every minute.
|
||||||
|
- It counts the number of consecutive minutes the temperature stays above or below the threshold.
|
||||||
|
- It sends Discord notifications if the threshold is exceeded or when the temperature cools down.
|
||||||
|
- It triggers a system shutdown if the temperature stays above the limit for the configured duration.
|
||||||
|
- It logs all temperatures and counter states, and automatically rotates log files.
|
||||||
|
|
||||||
|
While I was at it, I also added an installation script that installs the main script, makes it executable, creates a systemd service and timer, and enables them automatically.
|
||||||
|
The installer also lets you configure various parameters:
|
||||||
|
|
||||||
|
| Variable | Description | Default Value |
|
||||||
|
|-----------------------|------------------------------------------------------------------------------|-----------------------------------------------|
|
||||||
|
| `MAX_TEMP` | Maximum allowed temperature (°C) before the shutdown countdown starts | `60` |
|
||||||
|
| `HOT_DURATION` | Consecutive minutes above `MAX_TEMP` before shutdown | `5` |
|
||||||
|
| `COOL_RESET_DURATION` | Consecutive minutes below `MAX_TEMP` to reset all counters | `5` |
|
||||||
|
| `LOG_FILE` | Path to the main log file | `/var/log/hdd_temp_monitor.log` |
|
||||||
|
| `LOG_ROTATE_COUNT` | Number of log files to keep | `7` |
|
||||||
|
| `LOG_ROTATE_PERIOD` | Log rotation period (`daily` or `weekly`) | `daily` |
|
||||||
|
| `DISCORD_WEBHOOK` | Discord webhook URL for notifications | _Required_ |
|
||||||
|
|
||||||
|
It also runs another script that configures **logrotate** with the parameters defined above.
|
||||||
|
Finally, the installer can even be executed directly via a simple `curl` command followed by one last setup script — perfect for the laziest of us.
|
||||||
|
|
||||||
|
I also had to handle several tricky cases: running as root without sudo, using sudo directly, running as a non-sudo user, missing dependencies, permission issues, file creation errors, disk data reading errors, and more.
|
||||||
|
|
||||||
|
Concurrent access to the status file also had to be managed carefully.
|
||||||
|
|
||||||
|
More details are available directly on the repository:
|
||||||
|
|
||||||
|
::card
|
||||||
|
#title
|
||||||
|
📜 __HotDisk__
|
||||||
|
#description
|
||||||
|
[Keep your drives cool!](https://git.djeex.fr/Djeex/hotdisk)
|
||||||
|
::
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: Backrest Docker Stop
|
||||||
|
description: A bash script that stops Docker containers before a Backrest backup runs and restarts them after — ensuring safe database backups without complex dumps.
|
||||||
|
main:
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
|
||||||
|
# Backrest Docker Stop
|
||||||
|
---
|
||||||
|
|
||||||
|
[Backrest](https://github.com/garethgeorge/backrest) is a fantastic backup tool. In the case of [Serveex](https://docu.djeex.fr/serveex/introduction), most of the data that needs to be backed up consists of containers, and those containers often include databases.
|
||||||
|
|
||||||
|
The problem? You can’t safely back up a database while it’s running. There are plenty of complex solutions involving database dumps, but often the simplest method is to stop the containers, perform the backup, and then restart them.
|
||||||
|
|
||||||
|
**Backrest** doesn’t natively provide this functionality, but it does allow the execution of custom scripts triggered by events, for example, at the start and end of a backup plan. Our goal is to stop the containers whose databases need to be backed up when the backup plan starts, and restart them when the backup plan finishes.To achieve this, we’ll need a small Bash script and a secure connection between Backrest and the Docker socket, to enable the following sequence:
|
||||||
|
|
||||||
|
- The backup plan starts
|
||||||
|
- The event triggers the execution of a custom script
|
||||||
|
- The script contacts Docker and retrieves a list of containers labeled `backrest.backup.stop=true`
|
||||||
|
- It stops those containers
|
||||||
|
- The backup plan completes
|
||||||
|
- The event triggers another custom script
|
||||||
|
- The script contacts Docker again, retrieves the same list, and restarts those containers
|
||||||
|
|
||||||
|
|
||||||
|
## Securely Connecting Backrest and Docker
|
||||||
|
|
||||||
|
To allow **Backrest** to communicate securely with Docker, we’ll use [Docker Socket Proxy](https://github.com/linuxserver/docker-socket-proxy).
|
||||||
|
This avoids exposing the full Docker socket and grants only the necessary permissions.
|
||||||
|
Here’s an example Docker stack:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
services:
|
||||||
|
backrest:
|
||||||
|
image: garethgeorge/backrest:latest
|
||||||
|
container_name: backrest
|
||||||
|
hostname: backrest
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
volumes:
|
||||||
|
- ... # your volumes
|
||||||
|
environment:
|
||||||
|
- ... # your environment variables
|
||||||
|
- DOCKER_HOST=tcp://socket-proxy-backrest:2375
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- ... # your ports
|
||||||
|
depends_on:
|
||||||
|
- socket-proxy
|
||||||
|
|
||||||
|
socket-proxy:
|
||||||
|
image: lscr.io/linuxserver/socket-proxy:latest
|
||||||
|
container_name: socket-proxy-backrest
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
environment:
|
||||||
|
- CONTAINERS=1
|
||||||
|
- ALLOW_START=1
|
||||||
|
- ALLOW_STOP=1
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
restart: unless-stopped
|
||||||
|
read_only: true
|
||||||
|
tmpfs:
|
||||||
|
- /run
|
||||||
|
```
|
||||||
|
|
||||||
|
With this setup, Backrest can communicate with Docker safely and securely.
|
||||||
|
|
||||||
|
|
||||||
|
## The Scripts
|
||||||
|
|
||||||
|
Below are the scripts to use for **Backrest**’s *start* and *end* backup events.
|
||||||
|
|
||||||
|
::code-group
|
||||||
|
```sh [Stop]
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
BACKUP_LABEL="backrest.backup.stop=true"
|
||||||
|
BACKUP_CONTAINERS=$(docker ps -aqf "label=$BACKUP_LABEL")
|
||||||
|
for BC in $BACKUP_CONTAINERS
|
||||||
|
do
|
||||||
|
docker stop "$BC"
|
||||||
|
done
|
||||||
|
sleep 10
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh [Start]
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
BACKUP_LABEL="backrest.backup.stop=true"
|
||||||
|
BACKUP_CONTAINERS=$(docker ps -aqf "label=$BACKUP_LABEL")
|
||||||
|
for BC in $BACKUP_CONTAINERS
|
||||||
|
do
|
||||||
|
docker start "$BC"
|
||||||
|
done
|
||||||
|
sleep 10
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
## The Label
|
||||||
|
|
||||||
|
Once the scripts are in place and configured for the proper **Backrest** hooks, you just need to add the label `backrest.backup.stop=true` to the `compose.yaml` files of the containers that should stop and restart during backups:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
your_service:
|
||||||
|
...
|
||||||
|
labels:
|
||||||
|
- backrest.backup.stop=true
|
||||||
|
```
|
||||||
|
|
||||||
|
And that’s it!
|
||||||
|
At the next backup, all containers with the correct label will automatically stop during the backup and restart once it’s finished.
|
||||||
@@ -0,0 +1,258 @@
|
|||||||
|
---
|
||||||
|
navigation: true
|
||||||
|
title: Wireguard 14
|
||||||
|
main:
|
||||||
|
fluid: false
|
||||||
|
---
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||||
|
# Wireguard
|
||||||
|
|
||||||
|
::alert{type="info"}
|
||||||
|
🎯 __Goals:__
|
||||||
|
- Install Wireguard
|
||||||
|
- Configure clients
|
||||||
|
- Access the secure network
|
||||||
|
::
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
---
|
||||||
|
Using a VPN allows remote access to a server’s local resources without exposing them to the internet. It’s a clean and secure way to access services like SSH without exposing the port publicly. With a VPN, you can securely connect to your network from anywhere and make devices on different networks communicate.
|
||||||
|
|
||||||
|
Here we will use [Wireguard](https://www.wireguard.com/), a secure and high-performance VPN server, using containers:
|
||||||
|
|
||||||
|
- [wg-easy](https://github.com/wg-easy/wg-easy) as the server, providing a very simple web UI to manage connections and download config files (including QR codes for phones)
|
||||||
|
- [Wireguard](https://docs.linuxserver.io/images/docker-wireguard/?h=wireguard) as the client for Linux systems
|
||||||
|
|
||||||
|
Clients are also available for Windows, macOS, iOS, and Android.
|
||||||
|
|
||||||
|
The concept:
|
||||||
|
|
||||||
|
- On the internet, anyone can reach any internet box and thus any exposed server.
|
||||||
|
- Your server is on your local network. It is accessible only locally unless services are explicitly exposed (as we did with Dockge). To access non-exposed resources, you must be on the same local network.
|
||||||
|
- We want to securely access these unexposed services (like SSH) from anywhere.
|
||||||
|
- We also want to connect services between servers, like linking two Dockge instances securely.
|
||||||
|
|
||||||
|
To achieve this, we’ll create a **Virtual Private Network** (VPN), i.e., a secure tunnel that only connected machines can use. They’ll appear to be on the same private network.
|
||||||
|
|
||||||
|
Additionally, you can add your phone, laptop, or other devices to the VPN and securely access your server resources wherever you are.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
In this diagram, machine 1 is part of two networks:
|
||||||
|
|
||||||
|
- Its local network (devices behind the same router, e.g. `192.168.x.x` – machines 1 and 2)
|
||||||
|
- The VPN network (VPN devices with a second IP, e.g. `10.8.x.x` – machines 1 and 4)
|
||||||
|
|
||||||
|
You *can* allow VPN clients to share access to their local networks, but we won’t do that here for security and subnet conflict reasons (e.g., if two remote machines use the same local IP like `192.168.1.1`).
|
||||||
|
|
||||||
|
So only VPN-connected devices can communicate with each other on the VPN, not with other local devices outside the VPN.
|
||||||
|
|
||||||
|
## Server Side
|
||||||
|
---
|
||||||
|
::alert{type="info"}
|
||||||
|
📋 __Checklist:__
|
||||||
|
- Ensure port `51820 UDP` is available and properly forwarded through your router to the server (`Source 51820 UDP -> Destination 51820 UDP -> Server`).
|
||||||
|
- Ensure port `51821 TCP` is available for the web UI.
|
||||||
|
::
|
||||||
|
|
||||||
|
::alert{type="warning"}
|
||||||
|
:::list{type="warning"}
|
||||||
|
- __Warning:__ This guide uses version `14` of [wg-easy](https://wg-easy.github.io/wg-easy/latest/). Version `15` introduces breaking changes incompatible with this configuration.
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
Folder structure:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
root
|
||||||
|
└── docker
|
||||||
|
└── wg-easy
|
||||||
|
├── config
|
||||||
|
│ └── etc_wireguard
|
||||||
|
├── compose.yaml
|
||||||
|
└── .env
|
||||||
|
```
|
||||||
|
|
||||||
|
The container runs in `HOST` mode, meaning it uses the host’s network stack directly.
|
||||||
|
|
||||||
|
Open Dockge, click `compose`, and name the stack `wg_easy`.
|
||||||
|
|
||||||
|
Paste the following configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
services:
|
||||||
|
wg-easy:
|
||||||
|
network_mode: host
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
- LANG=en
|
||||||
|
- WG_HOST=${HOST}
|
||||||
|
- PASSWORD_HASH=${PW}
|
||||||
|
- WG_DEFAULT_ADDRESS=${ADDRESS}
|
||||||
|
- WG_HIDE_KEYS=never
|
||||||
|
- WG_ALLOWED_IPS=${IPS}
|
||||||
|
- WG_DEFAULT_DNS=
|
||||||
|
- UI_TRAFFIC_STATS=true
|
||||||
|
- UI_CHART_TYPE=1
|
||||||
|
image: ghcr.io/wg-easy/wg-easy:14
|
||||||
|
container_name: wg-easy
|
||||||
|
volumes:
|
||||||
|
- /docker/wg_easy/config/etc_wireguard:/etc/wireguard
|
||||||
|
restart: unless-stopped
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- SYS_MODULE
|
||||||
|
```
|
||||||
|
|
||||||
|
::alert{type="success"}
|
||||||
|
✨ __Tip:__
|
||||||
|
- You can also specify your own wireguard port with `WG_PORT`
|
||||||
|
- Add the Watchtower label to enable automatic updates
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services
|
||||||
|
wg-easy:
|
||||||
|
#...
|
||||||
|
labels:
|
||||||
|
- com.centurylinklabs.watchtower.enable=true
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
|
In `.env`:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
HOST=
|
||||||
|
PW=
|
||||||
|
ADDRESS=
|
||||||
|
IPS=
|
||||||
|
```
|
||||||
|
|
||||||
|
| Variable | Description | Example |
|
||||||
|
|--------------|-------------|---------|
|
||||||
|
| `HOST` | IP of public access of your host (router ISP's IP if it's at home) | `80.75.137.27` |
|
||||||
|
| `PW` | Bcrypt password hash, [generate here](https://bcrypt-generator.com/). **NOTE:** Double the `$` characters | `$$2a$$12$$FF6T4QqSP9Ho` |
|
||||||
|
| `ADDRESS` | VPN DHCP address range, the `x` must remain, others can vary | `10.8.0.x` |
|
||||||
|
| `IPS` | IPs routed by clients through the VPN. Use `10.8.0.0/24` to only route VPN traffic. To include local LAN, add `192.168.0.0/16` separated by commas. | `10.8.0.0/24` |
|
||||||
|
|
||||||
|
Deploy the stack.
|
||||||
|
|
||||||
|
### Enable Forwarding on Host
|
||||||
|
|
||||||
|
To allow communication between VPN clients, enable:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo sysctl net.ipv4.ip_forward=1
|
||||||
|
sudo sysctl net.ipv4.conf.all.src_valid_mark=1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Retrieve Configuration Files
|
||||||
|
|
||||||
|
To configure clients, download the config files from the server:
|
||||||
|
|
||||||
|
- Visit `http://your-server-ip:51821`
|
||||||
|
- Create a client
|
||||||
|
- Download the config file
|
||||||
|
- Rename it to `wg0.conf`
|
||||||
|
|
||||||
|
::alert{type="danger"}
|
||||||
|
:::list{type="danger"}
|
||||||
|
- If it fails, check firewall rules.
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
## On the Client Server
|
||||||
|
---
|
||||||
|
::alert{type="info"}
|
||||||
|
:::list{type="info"}
|
||||||
|
- Assumes the client is a Linux server with Docker installed
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
Folder structure:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
root
|
||||||
|
└── docker
|
||||||
|
└── wireguard
|
||||||
|
└── config
|
||||||
|
│ └── wg_confs
|
||||||
|
└── compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the folder `/docker/wireguard/config/wg_confs`:
|
||||||
|
|
||||||
|
::alert{type="success"}
|
||||||
|
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to browse and edit files without terminal
|
||||||
|
::
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo mkdir -p /docker/wireguard/config/wg_confs
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy the `wg0.conf` file downloaded earlier:
|
||||||
|
|
||||||
|
::alert{type="success"}
|
||||||
|
✨ __Tip:__ Easiest way is to transfer the file via SFTP to `/home/youruser`, then move it:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo cp ~/wg0.conf /docker/wireguard/config/wg_confs
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
|
Create `compose.yaml` in `/docker/wireguard`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo vi /docker/wireguard/compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Press `i` to enter insert mode and paste:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
wireguard:
|
||||||
|
image: lscr.io/linuxserver/wireguard:latest
|
||||||
|
container_name: wireguard
|
||||||
|
network_mode: host
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- SYS_MODULE #optional
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Paris
|
||||||
|
volumes:
|
||||||
|
- /docker/wireguard/config:/config
|
||||||
|
- /lib/modules:/lib/modules #optional
|
||||||
|
restart: unless-stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
Press `Esc` then type `:x` to save and exit.
|
||||||
|
|
||||||
|
Start the container:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /docker/wireguard
|
||||||
|
sudo docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
::alert{type="info"}
|
||||||
|
:::list{type="info"}
|
||||||
|
- Repeat for each client
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
## Other Devices
|
||||||
|
---
|
||||||
|
- **Phone:** Install Wireguard and scan the QR code from the web UI (`http://your-server-ip:51821`)
|
||||||
|
- **PC:** Install the Wireguard client and import the config file
|
||||||
|
|
||||||
|
::alert{type="warning"}
|
||||||
|
:::list{type="warning"}
|
||||||
|
- __Warning:__ If a client device is on the same LAN as the server, edit `wg0.conf` and change the endpoint to the local server IP:
|
||||||
|
`Endpoint = your-server-ip:51820`
|
||||||
|
:::
|
||||||
|
::
|
||||||
|
|
||||||
|
And this is the result:
|
||||||
|
|
||||||
|

|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
icon: lucide:trash-2
|
||||||
|
navigation.title: Deprecated
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
icon: noto:recycling-symbol
|
||||||
|
navigation.title: Recycled
|
||||||
@@ -2,6 +2,7 @@ export default defineNuxtConfig({
|
|||||||
// https://github.com/nuxt-themes/docus
|
// https://github.com/nuxt-themes/docus
|
||||||
css: ['~/assets/css/extra.css'],
|
css: ['~/assets/css/extra.css'],
|
||||||
extends: ['@nuxt-themes/docus'],
|
extends: ['@nuxt-themes/docus'],
|
||||||
|
modules: ['@nuxtjs/sitemap'],
|
||||||
devtools: { enabled: false },
|
devtools: { enabled: false },
|
||||||
colorMode: {
|
colorMode: {
|
||||||
preference: 'dark',
|
preference: 'dark',
|
||||||
@@ -37,10 +38,19 @@ export default defineNuxtConfig({
|
|||||||
{ rel: 'manifest', href: '/img/favicon/site.webmanifest' }
|
{ rel: 'manifest', href: '/img/favicon/site.webmanifest' }
|
||||||
],
|
],
|
||||||
meta: [
|
meta: [
|
||||||
{ name: 'darkreader-lock' },
|
{ name: 'darkreader-lock', content: 'true' },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
site: {
|
||||||
|
url: 'https://docu.djeex.fr'
|
||||||
|
},
|
||||||
|
|
||||||
|
sitemap: {
|
||||||
|
autoLastmod: true,
|
||||||
|
urls: ['https://docu.djeex.fr']
|
||||||
|
},
|
||||||
|
|
||||||
compatibilityDate: '2024-10-24'
|
compatibilityDate: '2024-10-24'
|
||||||
})
|
})
|
||||||
@@ -15,8 +15,9 @@
|
|||||||
"@nuxt/eslint-config": "^0.6.1",
|
"@nuxt/eslint-config": "^0.6.1",
|
||||||
"@nuxt/icon": "^1.7.5",
|
"@nuxt/icon": "^1.7.5",
|
||||||
"@nuxtjs/plausible": "^1.0.3",
|
"@nuxtjs/plausible": "^1.0.3",
|
||||||
|
"@nuxtjs/sitemap": "6.1.5",
|
||||||
"@types/node": "^22.9.0",
|
"@types/node": "^22.9.0",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"nuxt": "^3.14.159"
|
"nuxt": "^3.21.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export default defineNuxtPlugin(() => {
|
||||||
|
const route = useRoute()
|
||||||
|
const canonicalUrl = withSiteUrl(computed(() => route.path), { canonical: true })
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
link: [
|
||||||
|
{ rel: 'canonical', href: canonicalUrl }
|
||||||
|
],
|
||||||
|
meta: [
|
||||||
|
{ property: 'og:url', content: canonicalUrl }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 242 KiB |
|
After Width: | Height: | Size: 436 KiB |
|
After Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 138 KiB |