4 |
5 | Guide with examples !
6 |
7 | # Services
8 |
9 | * [traefik](traefik/) - reverse proxy and SSL manager
10 | * [borg-backup](borg-backup/) - backup scripts (local and AWS)
11 | * [fail2ban](fail2ban/) - security tool (ban IP)
12 | * [freshrss](freshrss/) - RSS feed aggregator
13 | * [gotify](gotify/) - notification service
14 | * [jellyfin](jellyfin/) - media System
15 | * [nextcloud](nextcloud/) - file-hosting software system
16 | * [seafile](seafile/) - file-hosting software system
17 | * [synapse-element](synapse-element/) - decentralised communication system
18 | * [transmission](transmission/) - fast, easy, and free BitTorrent client
19 | * [trilium](trilium/) - hierarchical note-taking application
20 | * [vaultwarden](vaultwarden/) - password manager
21 | * [watchtower](watchtower/) - automatic docker images update
22 | * [webserver](webserver/) - simple apache webserver
23 | * [wireguard-pihole-unbound](wireguard-pihole-unbound/) - combination of WireGuard, PiHole, and Unbound
24 | * [wordpress](wordpress/) - blogging tool with a content management system (CMS)
25 |
26 |
27 | # Information
28 |
29 | The overall guide is centered around example. Each of the services is tied with either a docker-compose or a script, everything has been made so that each service is almost ready to use, only a few user-specific variable are required.
30 |
31 | All services respect a certain format :
32 |
33 | - **About** - basic overview of the service
34 | - **Table of Contents**
35 | - **Files structure** - lists all the files and folder required
36 | - **Information** - detailed information about the service and the example
37 | - **Usage** - required configuration and commands to use the service
38 | - **Update** - how to update the container, most of the time it is using watchtower
39 | - **Backup** - how to back up the container, most of the time it is using borg-backup
40 |
41 | Traefik is the core of this setup as it is the reverse proxy, it should be one of the first services to configure and use.
42 |
43 | # Requirement
44 |
45 | Basic linux knowledge is required and docker is a must-have, everything should be pretty easy to set up but understanding docker will make it even more easy.
46 | Each guide gives links to the official documentation, they are usually well written, and they should answer most of your questions.
47 |
48 | On the technical side :
49 |
50 | * docker and docker-compose (1.X) are required, the installation process is fairly easy.
51 | * a domain, some can be found for free but most are usually pretty cheap.
52 |
53 | # Usage
54 |
55 | All the docker-compose provided in this repository are ready to be used, and you should not have to touch them. The only thing you need to change are the `.env` file provided with the docker-compose, they are user-specific.
56 |
57 | To begin with, you can clone this repository on your host.
58 |
59 | ```bash
60 | git clone https://github.com/BaptisteBdn/docker-selfhosted-apps.git
61 | ```
62 |
63 | Provided you already have a domain, you can use the following commands to update all `.env` at once as well as some specific config files.
64 |
65 | ```bash
66 | DOMAIN=your-domain.com
67 | find ./ \( -name ".env" -or -name "*.yml" -or -name "*.json" \) -type f -exec sed -i 's/example.com/'$DOMAIN'/g' {} \;
68 | ```
69 |
70 | You can now go forward and try whatever service you want, every example as a `# Usage` section to guide you through the process. However, as most of them are using Traefik, it is recommended to set this one first.
71 |
72 | # Other
73 |
74 | ## Docker and UFW
75 |
76 | UFW is a popular iptables front end on Ubuntu that makes it easy to manage firewall rules. But when Docker is installed, Docker bypass the UFW rules and the published ports can be accessed from outside.
77 |
78 | An [easy fix](https://github.com/chaifeng/ufw-docker) is available, allowing to easily manage your firewall. As most of the services are going through Traefik, only the port 443 is mandatory. If another port is required, it will be listed in the requirements.
79 |
80 | ## Docker tips
81 |
82 | * Get shell access whilst the container is running
83 | ```
84 | docker exec -it container-name /bin/bash
85 | ```
86 | * Monitor the logs of the container in realtime
87 | ```
88 | docker logs -f container-name
89 | ```
90 |
91 | ## Docker images
92 |
93 | Most images are used with the tag `latest` as it simplify the testing. It is usually not recommended running an image with this tag as it is not very dynamic and precise.
94 | Feel free to experiment with the provided docker-compose examples and then use a better versionning system. For more information about [latest](https://vsupalov.com/docker-latest-tag/).
95 |
96 | ## Updating docker images
97 |
98 | This repository images are automatically updated with watchtower, however this can be a security risk. More details in the [watchtower guide](watchtower).
99 |
100 | If you want to manually update an image, you can use docker-compose.
101 |
102 | * Update all images for a specific docker-compose file
103 | ```
104 | sudo docker-compose pull
105 | ```
106 | * Update a single image
107 | ```
108 | sudo docker-compose pull image-name
109 | ```
110 | * Recreate all updated containers with docker-compose
111 | ```
112 | sudo docker-compose up -d
113 | ```
114 | * Recreate a single container with docker-compose
115 | ```
116 | sudo docker-compose up -d container-name
117 | ```
118 | * Remove all dangling and unused images
119 | ```
120 | sudo docker image prune -a
121 | ```
122 |
123 | ## Docker tools
124 |
125 | Some useful tools to manage your private docker infrastructure.
126 |
127 | - [lazydocker](https://github.com/jesseduffield/lazydocker) - A simple terminal UI for both docker and docker-compose, written in Go with the gocui library. By @jesseduffield
128 | - [dive](https://github.com/wagoodman/dive) - A tool for exploring each layer in a docker image. By @anchore.
129 | - [grype](https://github.com/anchore/grype) - A vulnerability scanner for container images and filesystems. By @anchore.
130 |
131 | ## Docker resources
132 |
133 | A compilation of resources mainly focus on security.
134 |
135 | - [CIS Docker 1.13.0 Benchmark](https://downloads.cisecurity.org/#/) - provides prescriptive guidance for establishing a secure configuration posture for Docker
136 | - [Docker security](https://docs.docker.com/engine/security/) - official docker documentation about security
137 | - [Docker security OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html) - OWASP security cheat sheet
138 |
139 | # Credits
140 |
141 | This guide is inspired from [@DoTheEvo](https://github.com/DoTheEvo/selfhosted-apps-docker) own docker guide, built with caddy at its core, check it out !
142 |
--------------------------------------------------------------------------------
/_utilities/bitwarden.svg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/bitwarden.svg.png
--------------------------------------------------------------------------------
/_utilities/borg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
--------------------------------------------------------------------------------
/_utilities/docker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/docker.png
--------------------------------------------------------------------------------
/_utilities/element.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/element.png
--------------------------------------------------------------------------------
/_utilities/fail2ban.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/fail2ban.png
--------------------------------------------------------------------------------
/_utilities/freshrss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/freshrss.png
--------------------------------------------------------------------------------
/_utilities/gotify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/gotify.png
--------------------------------------------------------------------------------
/_utilities/httpd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/httpd.png
--------------------------------------------------------------------------------
/_utilities/jellyfin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/jellyfin.png
--------------------------------------------------------------------------------
/_utilities/matrix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/matrix.png
--------------------------------------------------------------------------------
/_utilities/nextcloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/nextcloud.png
--------------------------------------------------------------------------------
/_utilities/nextcloud_instruction.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/nextcloud_instruction.png
--------------------------------------------------------------------------------
/_utilities/pihole.svg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/pihole.svg.png
--------------------------------------------------------------------------------
/_utilities/seafile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/seafile.png
--------------------------------------------------------------------------------
/_utilities/traefik.logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/traefik.logo.png
--------------------------------------------------------------------------------
/_utilities/transmission.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/transmission.png
--------------------------------------------------------------------------------
/_utilities/trilium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/trilium.png
--------------------------------------------------------------------------------
/_utilities/unbound.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/_utilities/watchtower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/watchtower.png
--------------------------------------------------------------------------------
/_utilities/wireguard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/wireguard.png
--------------------------------------------------------------------------------
/_utilities/wordpress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/_utilities/wordpress.png
--------------------------------------------------------------------------------
/borg-backup/.env:
--------------------------------------------------------------------------------
1 | # Directory to back up
2 | DOCKER_DIR=/path/to/docker_directory
3 |
4 | # Borg repository
5 | BORG_REPO=/path/to/borg_repository
6 | BORG_PASSPHRASE=borg_passphrase
7 |
8 | # AWS configuration
9 | BORG_S3_BACKUP_BUCKET=bucket_name
10 | BORG_S3_BACKUP_AWS_PROFILE=aws_backup_profile
11 |
12 | # Gotify url and token (optional)
13 | GOTIFY_URL=https://gotify.example.com
14 | GOTIFY_TOKEN=gotify_token
15 |
16 | # Threshold (in GB) to limit the amount of data synced to AWS (optional)
17 | # If the borg repository is above the threshold, backup will not be saved to AWS
18 | # 0 for unlimited
19 | BACKUP_THRESHOLD=50
--------------------------------------------------------------------------------
/borg-backup/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | BorgBackup is a deduplicating backup program, it supports compression and authenticated encryption.
8 |
9 | * [Github](https://github.com/borgbackup/borg)
10 | * [Documentation](https://borgbackup.readthedocs.io/en/stable/)
11 |
12 | Borg is a key element for this selfhosted infrastructure as it will back up all your valuable data, the scripts alongside borg provides the following features :
13 |
14 | - Local backup of your docker repository
15 | - docker-compose, env files, etc.
16 | - **volumes** containing important data for your containers
17 | - External cloud backup on AWS (S3)
18 | - Backup notifications with [Gotify](../gotify)
19 |
20 | The scripts are a modified version of [luispabon/borg-s3-home-backup](https://github.com/luispabon/borg-s3-home-backup).
21 |
22 | # Table of Contents
23 |
24 |
25 |
26 | - [About](#about)
27 | - [Table of Contents](#table-of-contents)
28 | - [Files structure](#files-structure)
29 | - [Information](#information)
30 | - [env](#env)
31 | - [borg](#borg)
32 | - [aws](#aws)
33 | - [Gotify](#gotify)
34 | - [Backup scripts](#backup-scripts)
35 | - [Usage](#usage)
36 | - [Requirements](#requirements)
37 | - [Configuration](#configuration)
38 | - [Download and extract backups](#download-and-extract-backups)
39 | - [Security](#security)
40 |
41 |
42 |
43 | # Files structure
44 |
45 | ```bash
46 | .
47 | |-- .env
48 | |-- backup-borg-s3.sh*
49 | |-- download-backup-s3.sh*
50 | `-- excludes.txt
51 | ```
52 | - `.env` - a file containing all the environment variables used in backup scripts
53 | - `backup-borg-s3.sh`- a script to back up your data : locally and in the cloud (AWS S3)
54 | - `download-backup-s3.sh`- a script to download your data from the cloud
55 | - `excludes.txt` - an exclude file, default will back up all your docker infrastructure
56 |
57 | Please make sure that all the files and directories are present.
58 |
59 | # Information
60 |
61 | Borg requires user's specific configuration.
62 |
63 | ## .env
64 | Links to the following [.env](.env).
65 |
66 | ### borg
67 |
68 | ```bash
69 | # Directory to back up
70 | DOCKER_DIR=/path/to/docker_directory
71 | ```
72 | The directory containing all the configuration of the docker containers, usually the directory you cloned this guide into.
73 |
74 |
75 | ```bash
76 | # Borg repository
77 | BORG_REPO=/path/to/borg_repository
78 | BORG_PASSPHRASE=borg_passphrase
79 | ```
80 | The borg repository where the backups will be located, and the corresponding passphrase used to encrypt the datas.
81 |
82 | To create the repository and set your passphrase :
83 |
84 | ```bash
85 | borg init --encryption=repokey /path/to/repo
86 | ```
87 |
88 | > You can use [vaultwarden](../vaultwarden) to store your passphrase securly.
89 |
90 | ### aws
91 |
92 | > Keep in mind that AWS S3 is not free. Currently, with approximatly 50 GB of data it costs me around $1 per month.
93 |
94 | ```bash
95 | # AWS configuration
96 | BORG_S3_BACKUP_BUCKET=bucket_name
97 | BORG_S3_BACKUP_AWS_PROFILE=aws_backup_profile
98 | ```
99 |
100 | AWS provides a lot of services, we are gonna use S3 : Amazon Simple Storage Service (Amazon S3) is an object storage service where you can store and protect any amount of data for virtually any use case.
101 | It is a great, reliable and cheap way to store your already encrypted backups.
102 |
103 | In order to use S3, you will need an AWS account. If you do not have one, I suggest following the [AWS startup guide](https://aws.amazon.com/getting-started/guides/setup-environment/), only the first 3 modules are important.
104 |
105 | Within your AWS account, create another user within IAM, if you followed the guide you should already have created one, I recommend creating a unique user for the backup.
106 |
107 | Next, create your S3 bucket, keep in mind that the name of the bucket must be unique between all users using S3, you can choose something like `aws-docker-selfhosted-backups-8888`. Please be careful not to put your bucket publicly visible, by default it should not be.
108 |
109 | Then, go to IAM, select your backup user and choose `Add permissions` then `Attach existing policies` and then `Create policy`. On the editor, choose JSON and set the following policy for your backup user while changing with the name of the bucket you just created.
110 |
111 | `S3-full-access-backup-bucket`
112 | ```json
113 | {
114 | "Version": "2012-10-17",
115 | "Statement": [
116 | {
117 | "Sid": "AllAccess",
118 | "Action": "s3:*",
119 | "Effect": "Allow",
120 | "Resource": [
121 | "arn:aws:s3:::name-of-your-bucket",
122 | "arn:aws:s3:::name-of-your-bucket/*"
123 | ]
124 | }
125 | ]
126 | }
127 | ```
128 |
129 | Once this is done, add it to your user, this will give full access to the bucket you created to your backup user.
130 |
131 | Now everything is configured within your AWS account, the last step is to configure the profile on your docker host. This step is explained in the module 3 in the [AWS startup guide](https://aws.amazon.com/getting-started/guides/setup-environment/).
132 |
133 | > NOTE: Content inside docker volumes can be sometimes owned by root as they are created by docker, as a result, to avoid conflict I run the backups and AWS upload as root. If you want to do the same, the AWS profile will have to be configured inside root's home.
134 |
135 | The AWS configuration is finished, add the bucket name and the name of your aws profile to the `.env` file.
136 |
137 | To check that everything is set up correctly, use the following command (as root if you plan to run the backup as root):
138 |
139 | ```bash
140 | aws s3 ls --profile=your-profile-name --summarize --recursive s3://name-of-your-bucket
141 | ```
142 |
143 | The response should be empty, but you should not have any error.
144 |
145 | ### Gotify
146 |
147 | You need to have a selfhosted [gotify](../gotify) available, check the guide if you want to know how to generate a token.
148 |
149 | ## Backup scripts
150 |
151 | The backup script works in 5 steps :
152 |
153 | - Stops all running docker container to ensure uncorrupted files
154 | - Create local borg backup
155 | - Prune old backups
156 | - Keep the most up to date daily, weekly and monthly backup
157 | - Synchronise the local backup to the AWS bucket (kind of like rsync would do)
158 | - Starts all docker containers
159 | - Notify using Gotify
160 |
161 |
162 | The download script works in 2 steps :
163 |
164 | - Check that you have enough space on your host
165 | - Download the remote encrypted backup
166 |
167 |
168 | # Usage
169 |
170 | ## Requirements
171 |
172 | Please ensure that the `.env` is correctly configure.
173 |
174 | ## Configuration
175 |
176 | While you want to keep most of the data, you may also want to exclude heavy files from backups (media files, logs, etc.).
177 | Add any **full path** to any directory or file that you want to exclude to `exclude.txt`.
178 |
179 | > Default will back up EVERYTHING. I also recommend setting the BACKUP_THRESHOLD value in the `.env` as it will prevent any AWS upload if the backup is larger than the setting.
180 |
181 | Now that everything is set up, you can run the backup script.
182 |
183 | ```bash
184 | sudo /bin/bash /path/to/backup-borg-s3.sh
185 | ```
186 |
187 | You can also use cron to automate the backup.
188 |
189 | ```bash
190 | 1 3 * * 1 root /bin/bash /path/to/backup-borg-s3.sh >> /var/log/backup.log
191 | ```
192 | This will run the backup script as root every monday at 3.
193 |
194 | ## Download and extract backups
195 |
196 | If you ever need your backup, borg makes it pretty easy.
197 |
198 | First, download the backup using the download backup script, you will need the `.env` with only the AWS settings (aws bucket name and AWS profile name).
199 |
200 | ```bash
201 | /bin/bash /download-backup-s3.sh /tmp/aws-backup
202 | ```
203 |
204 | List the backups available (you will need your passphrase).
205 |
206 | ```bash
207 | borg list /tmp/aws-backup
208 | ```
209 |
210 | Then create and move to the folder you want to extract your backup in.
211 |
212 | ```bash
213 | mkdir /tmp/extracted-backup && cd /tmp/extracted-backup
214 | ```
215 |
216 | Finally, extract the backup you need (it will extract in the directory you are located in).
217 |
218 | ```bash
219 | borg extract /tmp/aws-backup::backup-2021-12-06T03.01
220 | ```
221 |
222 |
223 | # Security
224 |
225 | A few security points :
226 | - Please be careful not to put your bucket publicly visible, by default it should not be.
227 | - You can store your passphrase in [vaultwarden](../vaultwarden).
228 | - Test your backup recovery process, try to download, extract and run your backup to check if everything runs correctly.
229 | - Check the backup scripts and try to understand them, you will have more trust in your backup, that's the beauty of opensource.
230 |
231 |
232 |
--------------------------------------------------------------------------------
/borg-backup/backup-borg-s3.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ENV_FILE=$(dirname $0)/.env
4 | if [ ! -f "${ENV_FILE}" ]; then
5 | printf "\n\n** Please create an env file with the required environment variables at '${ENV_FILE}'."
6 | exit 1
7 | fi
8 | # Export env variables
9 | set -o allexport
10 | source .env
11 | set +o allexport
12 |
13 | # Name to give this backup within the borg repo
14 | BACKUP_NAME=backup-$(date +%Y-%m-%dT%H.%M)
15 |
16 | printf "** Starting backup ${BACKUP_NAME} ...\n"
17 |
18 | # Check environment vars are set
19 | if [[ ! "$DOCKER_DIR" ]]; then
20 | printf "\n\n** Please provide with DOCKER_DIR on the environment\n"
21 | exit 1
22 | fi
23 |
24 | if [[ ! "$BORG_REPO" ]]; then
25 | printf "\n\n** Please provide with BORG_REPO on the environment\n"
26 | exit 1
27 | fi
28 |
29 | if [[ ! "$BORG_S3_BACKUP_BUCKET" ]]; then
30 | printf "\n\n** Please provide with BORG_S3_BACKUP_BUCKET on the environment\n"
31 | exit 1
32 | fi
33 |
34 | if [[ ! "$BORG_S3_BACKUP_AWS_PROFILE" ]]; then
35 | printf "\n\n** Please provide with BORG_S3_BACKUP_AWS_PROFILE on the environment (awscli profile)\n"
36 | exit 1
37 | fi
38 |
39 | if [[ ! "$GOTIFY_URL" && ! "$GOTIFY_TOKEN" ]]; then
40 | printf "\n\n** Please provide with GOTIFY_URL and GOTIFY_TOKEN on the environment\n"
41 | exit 1
42 | fi
43 |
44 | SYNC_COMMAND="aws s3 sync ${BORG_REPO} s3://${BORG_S3_BACKUP_BUCKET} --profile=${BORG_S3_BACKUP_AWS_PROFILE} --delete"
45 |
46 | EXCLUDES_FILE=$(dirname $0)/excludes.txt
47 | if [ ! -f "${EXCLUDES_FILE}" ]; then
48 | printf "\n\n** Please create an excludes file (even if empty) at '${EXCLUDES_FILE}'."
49 | exit 1
50 | fi
51 |
52 | # Stopping docker containers to ensure uncorrupted files
53 | printf "\n** Stopping docker containers...\n"
54 | docker stop $(docker ps -a -q)
55 |
56 | # Local borg backup
57 | printf "\n** Backing up ${DOCKER_DIR} with borg...\n"
58 | borg create ::${BACKUP_NAME} ${DOCKER_DIR} --stats --exclude-from ${EXCLUDES_FILE} --compression zlib,6
59 |
60 | # Define and store the backup's exit status
61 | OPERATION_STATUS=$?
62 |
63 | # Only continue if backup was actually successful
64 | if [ $OPERATION_STATUS == 0 ]; then
65 | # Clean up old backups: keep last daily, last weekly and last monthly
66 | printf "\n** Pruning old backups...\n"
67 | borg prune -v --list --keep-daily=1 --keep-weekly=1 --keep-monthly=1
68 |
69 | # Check and compare backup size with threshold
70 | if [[ "$BACKUP_THRESHOLD" && $BACKUP_THRESHOLD != 0 ]]; then
71 | BACKUP_SIZE=$(borg info --json | jq .cache.stats.unique_csize | awk '{ printf "%d", $1/1024/1024/1024; }')
72 | if [[ $BACKUP_SIZE -gt $BACKUP_THRESHOLD ]]; then
73 | printf "Backup size ${BACKUP_SIZE} GB is larger than the threshold ${BACKUP_THRESHOLD} GB"
74 | OPERATION_STATUS=1
75 | MESSAGE="Backup size ${BACKUP_SIZE} GB is larger than the threshold ${BACKUP_THRESHOLD} GB"
76 | fi
77 | fi
78 | fi
79 |
80 | # Sync to AWS if the backup size if lower than the threshold
81 | if [ $OPERATION_STATUS == 0 ]; then
82 | # Sync borg repo to s3
83 | printf "\n** Syncing to s3 bucket ${BORG_S3_BACKUP_BUCKET}...\n"
84 | borg with-lock ${BORG_REPO} ${SYNC_COMMAND}
85 |
86 | # We do care about s3 sync succeeding though
87 | OPERATION_STATUS=$?
88 | fi
89 |
90 | if [ $OPERATION_STATUS == 0 ]; then
91 | # Create Gotify stats
92 | BORG_STATS=$(borg info ::${BACKUP_NAME})
93 | AWS_STATS=$(aws s3 ls --profile=${BORG_S3_BACKUP_AWS_PROFILE} --summarize --recursive s3://${BORG_S3_BACKUP_BUCKET} | tail -1 | awk '{ printf "%.3f GB", $3/1024/1024/1024; }')
94 | NL=$'\n'
95 |
96 | STATUS_MESSAGE="Backup successful"
97 | MESSAGE="${BORG_STATS}${NL}AWS bucket size : ${AWS_STATS}"
98 | else
99 | STATUS_MESSAGE="Backup failed"
100 | fi
101 |
102 | # Stopping docker containers to ensure uncorrupted files
103 | printf "\n\n** Starting docker containers...\n"
104 | docker start $(docker ps -a -q)
105 |
106 | # Waiting 60s for gotify to start
107 | sleep 60
108 |
109 | # Send gotify notification and exit appropriately
110 | printf "\n** Sending notification to gotify...\n"
111 | if [ $OPERATION_STATUS == 0 ]; then
112 | curl -s "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" -F "title=${STATUS_MESSAGE}" -F "message=${MESSAGE}" -F "priority=5" > /dev/null
113 | else
114 | curl -s "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" -F "title=${STATUS_MESSAGE}" -F "message=${MESSAGE}" -F "priority=5" > /dev/null
115 | fi
116 |
117 | # Same as above, but on stdout
118 | printf "\n** ${STATUS_MESSAGE}\n"
119 | exit ${OPERATION_STATUS}
120 |
--------------------------------------------------------------------------------
/borg-backup/download-backup-s3.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | bold=$(tput bold)
4 | normal=$(tput sgr0)
5 | accent=$(tput setaf 99)
6 | secondary_accent=$(tput setaf 12)
7 |
8 | DOWNLOAD_FOLDER=$1
9 | if [[ ! "$DOWNLOAD_FOLDER" ]]; then
10 | SCRIPT=$(basename "$0")
11 | printf "\n**Please provide the folder we're downloading your backup files into. The folder must exist and be empty.\n"
12 | printf "\nExample: ${SCRIPT} /path/to/folder\n\n"
13 | exit 1
14 | fi
15 |
16 | if [[ ! -d "$DOWNLOAD_FOLDER" ]]; then
17 | printf "\n**The folder ${DOWNLOAD_FOLDER} does not exist. Please create.\n\n"
18 | exit 1
19 | fi
20 |
21 | if [ "$(ls -A $DOWNLOAD_FOLDER)" ]; then
22 | printf "\n**The folder ${DOWNLOAD_FOLDER} is not empty.\n\n"
23 | exit 1
24 | fi
25 |
26 | ENV_FILE=$(dirname $0)/.env
27 | if [ ! -f "${ENV_FILE}" ]; then
28 | printf "\n\n** Please create an env file with the required environment variables at '${ENV_FILE}'."
29 | exit 1
30 | fi
31 | # Export env variables
32 | export $(cat $ENV_FILE | sed 's/#.*//g' | xargs)
33 |
34 | if [[ ! "$BORG_S3_BACKUP_BUCKET" ]]; then
35 | printf "\n\n**Please provide with BORG_S3_BACKUP_BUCKET on the environment\n"
36 | exit 1
37 | fi
38 |
39 | if [[ ! "$BORG_S3_BACKUP_AWS_PROFILE" ]]; then
40 | printf "\n\n**Please provide with BORG_S3_BACKUP_AWS_PROFILE on the environment (awscli profile)\n"
41 | exit 1
42 | fi
43 |
44 | DOWNLOAD_FOLDER_AVAILABLE=$(df -B1 ${DOWNLOAD_FOLDER} | tail -1 | awk '{print $4}')
45 |
46 | printf "${bold}Computing bucket size...${normal}\n\n"
47 |
48 | BUCKET_URI="s3://${BORG_S3_BACKUP_BUCKET}"
49 | BUCKET_SIZE=`aws s3 ls --profile=${BORG_S3_BACKUP_AWS_PROFILE} --summarize --recursive ${BUCKET_URI} | tail -1 | awk '{print \$3}'`
50 | DOWNLOAD_COMMAND="aws s3 sync ${BUCKET_URI} ${DOWNLOAD_FOLDER} --profile=${BORG_S3_BACKUP_AWS_PROFILE}"
51 |
52 | BUCKET_SIZE_GB=`numfmt --to iec --format "%8.4f" ${BUCKET_SIZE}`
53 | DOWNLOAD_FOLDER_AVAILABLE_GB=`numfmt --to iec --format "%8.4f" ${DOWNLOAD_FOLDER_AVAILABLE}`
54 |
55 | echo "${bold}Bucket size:${normal} ${accent}${BUCKET_SIZE_GB}${normal}"
56 | echo "${bold}Available space at ${secondary_accent}${DOWNLOAD_FOLDER}:${normal} ${accent}${DOWNLOAD_FOLDER_AVAILABLE_GB}${normal}"
57 |
58 | if (( $BUCKET_SIZE > $DOWNLOAD_FOLDER_AVAILABLE )); then
59 | printf "\n**There is not enough space to download your backup at ${secondary_accent}${DOWNLOAD_FOLDER}${normal}\n"
60 | exit 1
61 | fi
62 |
63 | printf "\n${bold}Starting download: ${secondary_accent}${BUCKET_URI} ${accent}--> ${secondary_accent}${DOWNLOAD_FOLDER}${normal}\n\n"
64 |
65 | $DOWNLOAD_COMMAND
66 |
67 | printf "\n\n${bold}Backup download success.\n\n"
--------------------------------------------------------------------------------
/borg-backup/excludes.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BaptisteBdn/docker-selfhosted-apps/70e8ee22b1a1d2f0c2bf4940301b565928ac2b95/borg-backup/excludes.txt
--------------------------------------------------------------------------------
/fail2ban/.env:
--------------------------------------------------------------------------------
1 | TZ=Europe/Paris
--------------------------------------------------------------------------------
/fail2ban/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Fail2ban scans log files and bans IPs that show the malicious signs.
8 |
9 | * [Github](https://github.com/fail2ban/fail2ban)
10 | * [Documentation](http://www.fail2ban.org/wiki/index.php/Fail2Ban)
11 | * [Docker Image](https://github.com/crazy-max/docker-fail2ban)
12 |
13 | We are going to be using a prebuilt docker image by crazymax to facilitate the process.
14 | There are a lot of fail2ban configurations availabe on the internet, and you can even create your own, this guide provides the following features :
15 |
16 | - SSH jail configuration
17 | - Vaultwarden jail configuration
18 |
19 | # Table of Contents
20 |
21 |
22 |
23 | - [About](#about)
24 | - [Table of Contents](#table-of-contents)
25 | - [Files structure](#files-structure)
26 | - [Information](#information)
27 | - [docker-compose](#docker-compose)
28 | - [jails](#jails)
29 | - [Usage](#usage)
30 | - [Configuration](#configuration)
31 | - [Fail2ban](#fail2ban)
32 | - [Update](#update)
33 | - [Security](#security)
34 | - [Backup](#backup)
35 |
36 |
37 |
38 | # Files structure
39 | ```bash
40 | .
41 | |-- data/
42 | | |-- action.d/
43 | | | |-- nftables-forward.conf
44 | | | |-- nftables-input.conf
45 | | |-- db/
46 | | |-- filter.d/
47 | | | |-- bitwarden-admin.conf
48 | | | |-- bitwarden-auth.conf
49 | | `-- jail.d/
50 | | |-- bitwarden-admin.conf
51 | | |-- bitwarden-auth.conf
52 | | |-- sshd.conf
53 | `-- docker-compose.yml
54 | ```
55 |
56 | - `data/action.d` - a directory containing custom action configuration to execute when banning an IP
57 | - `data/db` - a directory used to store fail2ban sqlite database
58 | - `data/filter.d` - a directory containing custom filter configuration used by a jail to match malicious signs
59 | - `data/jail.d` - a directory containing custom jail configuration for your services
60 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
61 |
62 | Please make sure that all the files and directories are present.
63 |
64 |
65 | # Information
66 |
67 | ## docker-compose
68 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
69 |
70 | * docker-compose.yml
71 | ```yaml
72 | version: '3'
73 |
74 | services:
75 | fail2ban:
76 | image: crazymax/fail2ban:latest
77 | container_name: fail2ban
78 | restart: unless-stopped
79 | volumes:
80 | - /var/log:/var/log:ro
81 | - ./data:/data
82 | environment:
83 | - TZ=${TZ}
84 | network_mode: host
85 | cap_add:
86 | - NET_ADMIN
87 | - NET_RAW
88 | labels:
89 | # Watchtower Update
90 | - "com.centurylinklabs.watchtower.enable=true"
91 | ```
92 | * .env
93 | ```ini
94 | TZ=Europe/Paris
95 | ```
96 |
97 | We are gonna use `/var/log` directory to parse log files.
98 |
99 | ## jails
100 |
101 | The jail.d directory is provided with three examples.
102 |
103 | - sshd.conf : provides ssh protection, will ban any IP trying to bruteforce your ssh credentials, a must-have if you are still on port 22.
104 |
105 | - bitwarden-auth.conf : provides your vaultwarden password manager from bruteforce.
106 |
107 | - bitwarden-admin.conf : provides your vaultwarden admin dashboard from bruteforce.
108 |
109 | You can find the vaultwarden filters in the filter.d directory. For example, in `filter.d/vaultwarden-auth` you can find :
110 |
111 | ```ini
112 | [INCLUDES]
113 | before = common.conf
114 |
115 | [Definition]
116 | failregex = ^.*Username or password is incorrect\. Try again\. IP: \. Username:.*$
117 | ignoreregex =
118 | ```
119 |
120 | This filter is using regex and will match any log that fails to connect to your vaultwarden vault. The log file that is parsed is `/var/log/syslog`, redirection is provided with the docker-compose available in the [vaultwarden guide](../vaultwarden).
121 |
122 | # Usage
123 |
124 | ## Configuration
125 |
126 | Replace the environment variables in `.env` with your own, then run :
127 |
128 | ```bash
129 | sudo docker-compose up -d
130 | ```
131 |
132 | The jails and filters configured are going to be active, you can now create as many as you want to protect your services.
133 |
134 | ## Fail2ban
135 |
136 | [Fail2ban commands](http://www.fail2ban.org/wiki/index.php/Commands) can be used through the container.
137 | Here is an example if you want to unban an IP manually:
138 |
139 | ```
140 | sudo docker exec -t fail2ban fail2ban-client set unbanip
141 | ```
142 |
143 | The same example with [bitwarden](../vaultwarden), in the case you failed to enter the right password 3 times:
144 | ```
145 | sudo docker exec -t fail2ban fail2ban-client set bitwarden-auth unbanip
146 | ```
147 |
148 | For a more general example, you can use any fail2ban command as follows:
149 | ```
150 | sudo docker exec -t fail2ban fail2ban-client
151 | ```
152 |
153 | # Update
154 |
155 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
156 |
157 | ```yaml
158 | # Watchtower Update
159 | - "com.centurylinklabs.watchtower.enable=true"
160 | ```
161 |
162 | # Security
163 |
164 | Be careful not to get ban as the iptable action is pretty aggressive, you will not be able to SSH with the banned IP.
165 |
166 | # Backup
167 |
168 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/fail2ban/data/action.d/nftables-forward.conf:
--------------------------------------------------------------------------------
1 | [INCLUDES]
2 | before = nftables.conf
3 |
4 | [Init]
5 | chain = f2b-chain-forward
6 | chain_hook = forward
--------------------------------------------------------------------------------
/fail2ban/data/action.d/nftables-input.conf:
--------------------------------------------------------------------------------
1 | [INCLUDES]
2 | before = nftables.conf
3 |
4 | [Init]
5 | chain = f2b-chain-input
6 | chain_hook = input
--------------------------------------------------------------------------------
/fail2ban/data/filter.d/bitwarden-admin.conf:
--------------------------------------------------------------------------------
1 | [INCLUDES]
2 | before = common.conf
3 |
4 | [Definition]
5 | failregex = ^.*Invalid admin token\. IP: .*$
6 | ignoreregex =
7 |
--------------------------------------------------------------------------------
/fail2ban/data/filter.d/bitwarden-auth.conf:
--------------------------------------------------------------------------------
1 | [INCLUDES]
2 | before = common.conf
3 |
4 | [Definition]
5 | failregex = ^.*Username or password is incorrect\. Try again\. IP: \. Username:.*$
6 | ignoreregex =
7 |
--------------------------------------------------------------------------------
/fail2ban/data/jail.d/bitwarden-admin.conf:
--------------------------------------------------------------------------------
1 | [bitwarden-admin]
2 | enabled = true
3 | banaction = nftables-forward
4 | logpath = /var/log/syslog
5 | maxretry = 5
6 | bantime = 14400
7 | findtime = 14400
--------------------------------------------------------------------------------
/fail2ban/data/jail.d/bitwarden-auth.conf:
--------------------------------------------------------------------------------
1 | [bitwarden-auth]
2 | enabled = true
3 | banaction = nftables-forward
4 | logpath = /var/log/syslog
5 | maxretry = 3
6 | bantime = 14400
7 | findtime = 14400
--------------------------------------------------------------------------------
/fail2ban/data/jail.d/sshd.conf:
--------------------------------------------------------------------------------
1 | [sshd]
2 | enabled = true
3 | chain = INPUT
4 | port = ssh
5 | filter = sshd[mode=aggressive]
6 | logpath = /var/log/auth.log
7 | maxretry = 3
8 | bantime = 14400
9 | findtime = 14400
10 |
--------------------------------------------------------------------------------
/fail2ban/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | fail2ban:
5 | image: crazymax/fail2ban:latest
6 | container_name: fail2ban
7 | restart: unless-stopped
8 | volumes:
9 | - /var/log:/var/log:ro
10 | - ./data:/data
11 | environment:
12 | - TZ=${TZ}
13 | network_mode: host
14 | cap_add:
15 | - NET_ADMIN
16 | - NET_RAW
17 | labels:
18 | # Watchtower Update
19 | - "com.centurylinklabs.watchtower.enable=true"
20 |
--------------------------------------------------------------------------------
/freshrss/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_FRESHRSS=freshrss.example.com
2 | TZ=Europe/Paris
--------------------------------------------------------------------------------
/freshrss/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | FreshRSS is a self-hosted RSS feed aggregator
8 |
9 | * [Github](https://github.com/FreshRSS/FreshRSS)
10 | * [Documentation](https://freshrss.github.io/FreshRSS/en/admins/01_Index.html)
11 | * [Docker Image](https://hub.docker.com/r/linuxserver/freshrss)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Information](#information)
20 | - [docker-compose](#docker-compose)
21 | - [Usage](#usage)
22 | - [Requirements](#requirements)
23 | - [Configuration](#configuration)
24 | - [Update](#update)
25 | - [Backup](#backup)
26 |
27 |
28 |
29 | ```bash
30 | .
31 | |-- .env
32 | |-- data/
33 | `-- docker-compose.yml
34 | ```
35 |
36 | * `.env` - a file containing all the environment variables used in the docker-compose.yml
37 | * `docker-compose.yml` - a docker-compose file, use to configure your application’s services
38 | * `data/` - a directory used to store the data
39 |
40 | Please make sure that all the files and directories are present.
41 |
42 | # Information
43 |
44 | ## docker-compose
45 |
46 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
47 |
48 | * docker-compose.yml
49 | ```yaml
50 | version: '3'
51 |
52 | services:
53 | freshrss:
54 | image: 'freshrss/freshrss'
55 | container_name: freshrss
56 | restart: unless-stopped
57 | volumes:
58 | - "./data:/var/www/FreshRSS/data"
59 | environment:
60 | - 'CRON_MIN=4,34'
61 | - 'TZ=Europe/Paris'
62 | networks:
63 | - proxy
64 | labels:
65 | - "traefik.enable=true"
66 | - "traefik.http.routers.webserver.rule=Host(`${TRAEFIK_FRESHRSS}`)"
67 | - "traefik.http.routers.webserver.entrypoints=https"
68 | - "traefik.http.routers.webserver.tls=true"
69 | - "traefik.http.routers.webserver.tls.certresolver=mydnschallenge"
70 | # Watchtower Update
71 | - "com.centurylinklabs.watchtower.enable=true"
72 |
73 | networks:
74 | proxy:
75 | external: true
76 | ```
77 | * .env
78 | ```ini
79 | TRAEFIK_FRESHRSS=freshrss.example.com
80 | TZ=Europe/Paris
81 | ```
82 |
83 | The docker-compose contains only one service using the freshrss image.
84 |
85 | # Usage
86 |
87 | ## Requirements
88 |
89 | * [Traefik up and running](../traefik).
90 | * A subdomain of your choice, this example uses `freshrss`.
91 | * You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
92 |
93 | ## Configuration
94 |
95 | Replace the environment variables in `.env` with your own, then run :
96 |
97 | ```bash
98 | sudo docker-compose up -d
99 | ```
100 |
101 | You should now be able to access the freshrss setup instruction, it is quite straigthforward and nothing is required.
102 |
103 | # Update
104 |
105 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
106 |
107 | ```yaml
108 | # Watchtower Update
109 | - "com.centurylinklabs.watchtower.enable=true"
110 | ```
111 |
112 | # Backup
113 |
114 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
115 |
--------------------------------------------------------------------------------
/freshrss/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | freshrss:
5 | image: 'freshrss/freshrss'
6 | container_name: freshrss
7 | restart: unless-stopped
8 | volumes:
9 | - "./data:/var/www/FreshRSS/data"
10 | environment:
11 | - 'CRON_MIN=4,34'
12 | - 'TZ=Europe/Paris'
13 | networks:
14 | - proxy
15 | labels:
16 | - "traefik.enable=true"
17 | - "traefik.http.routers.freshrss.rule=Host(`${TRAEFIK_FRESHRSS}`)"
18 | - "traefik.http.routers.freshrss.entrypoints=https"
19 | - "traefik.http.routers.freshrss.tls=true"
20 | - "traefik.http.routers.freshrss.tls.certresolver=mydnschallenge"
21 | # Watchtower Update
22 | - "com.centurylinklabs.watchtower.enable=true"
23 |
24 | networks:
25 | proxy:
26 | external: true
--------------------------------------------------------------------------------
/gotify/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_GOTIFY=gotify.example.com
2 | GOTIFY_DEFAULTUSER_PASS=xxxxxxxxxxxxxxxxx
3 |
--------------------------------------------------------------------------------
/gotify/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Gotify is a simple server for sending and receiving notification messages. It is used a lot throughout this guide for services such as backups and automatic updates, a must-have self-hosted solution.
8 |
9 | * [Github](https://github.com/gotify/server)
10 | * [Documentation](https://gotify.net/docs/index)
11 | * [Docker Image](https://hub.docker.com/r/gotify/server)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Files structure](#files-structure)
20 | - [Information](#information)
21 | - [docker-compose](#docker-compose)
22 | - [Usage](#usage)
23 | - [Requirements](#requirements)
24 | - [Configuration](#configuration)
25 | - [Update](#update)
26 | - [Security](#security)
27 | - [Backup](#backup)
28 |
29 |
30 |
31 | # Files structure
32 |
33 | ```bash
34 | .
35 | |-- .env
36 | |-- docker-compose.yml
37 | `-- data/
38 | ```
39 |
40 | - `.env` - a file containing all the environment variables used in the docker-compose.yml
41 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
42 | - `data/` - a directory used to store the service's data
43 |
44 | Please make sure that all the files and directories are present.
45 |
46 |
47 | # Information
48 |
49 | ## docker-compose
50 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
51 |
52 | * docker-compose.yml
53 | ```yaml
54 | version: "3"
55 |
56 | services:
57 | gotify:
58 | image: gotify/server
59 | container_name: gotify
60 | restart: unless-stopped
61 | volumes:
62 | - "./data:/app/data"
63 | environment:
64 | - GOTIFY_DEFAULTUSER_PASS=${GOTIFY_DEFAULTUSER_PASS}
65 | networks:
66 | - proxy
67 | labels:
68 | - "traefik.enable=true"
69 | - "traefik.http.routers.gotify.rule=Host(`gotify.example.com`)"
70 | - "traefik.http.routers.gotify.entrypoints=https"
71 | - "traefik.http.routers.gotify.tls=true"
72 | - "traefik.http.routers.gotify.tls.certresolver=mydnschallenge"
73 |
74 | # Watchtower Update
75 | - "com.centurylinklabs.watchtower.enable=true"
76 |
77 | networks:
78 | proxy:
79 | external: true
80 | ```
81 | * .env
82 | ```ini
83 | TRAEFIK_GOTIFY=gotify.example.com
84 | GOTIFY_DEFAULTUSER_PASS=xxxxxxxxxxxxxxxxx
85 | ```
86 |
87 | # Usage
88 |
89 | ## Requirements
90 | - [Traefik up and running](../traefik).
91 | - A subdomain of your choice, this example uses `gotify`.
92 | - You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
93 |
94 | ## Configuration
95 |
96 | Replace the environment variables in `.env` with your own, then run :
97 |
98 | ```bash
99 | sudo docker-compose up -d
100 | ```
101 |
102 | You should then be able to access the gotify web-ui with the default user being `admin` and the GOTIFY_DEFAULTUSER_PASS defined in `.env`.
103 |
104 | # Update
105 |
106 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
107 |
108 | ```yaml
109 | # Watchtower Update
110 | - "com.centurylinklabs.watchtower.enable=true"
111 | ```
112 |
113 | # Security
114 |
115 | Don't forget to change the GOTIFY_DEFAULTUSER_PASS after first using it.
116 |
117 | # Backup
118 |
119 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/gotify/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | gotify:
5 | image: gotify/server
6 | container_name: gotify
7 | restart: unless-stopped
8 | volumes:
9 | - "./data:/app/data"
10 | environment:
11 | - GOTIFY_DEFAULTUSER_PASS=${GOTIFY_DEFAULTUSER_PASS}
12 | networks:
13 | - proxy
14 | labels:
15 | - "traefik.enable=true"
16 | - "traefik.http.routers.gotify.rule=Host(`${TRAEFIK_GOTIFY}`)"
17 | - "traefik.http.routers.gotify.entrypoints=https"
18 | - "traefik.http.routers.gotify.tls=true"
19 | - "traefik.http.routers.gotify.tls.certresolver=mydnschallenge"
20 |
21 | # Watchtower Update
22 | - "com.centurylinklabs.watchtower.enable=true"
23 |
24 | networks:
25 | proxy:
26 | external: true
--------------------------------------------------------------------------------
/jellyfin/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_JELLYFIN=jellyfin.example.com
--------------------------------------------------------------------------------
/jellyfin/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media.
8 |
9 | * [Github](https://github.com/jellyfin/jellyfin)
10 | * [Documentation](https://jellyfin.org/docs/)
11 | * [Docker Image](https://hub.docker.com/r/jellyfin/jellyfin/)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Files structure](#files-structure)
20 | - [Information](#information)
21 | - [docker-compose](#docker-compose)
22 | - [Usage](#usage)
23 | - [Requirements](#requirements)
24 | - [Configuration](#configuration)
25 | - [Note](#note)
26 | - [Update](#update)
27 | - [Backup](#backup)
28 |
29 |
30 |
31 | # Files structure
32 |
33 | ```bash
34 | .
35 | |-- .env
36 | |-- cache/
37 | |-- config/
38 | |-- docker-compose.yml
39 | `-- media/
40 | ```
41 |
42 | - `.env` - a file containing all the environment variables used in the docker-compose.yml
43 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
44 | - `cache/` - a directory used to store jellyfin caching data (optionnal)
45 | - `config/` - a directory used to store jellyfin config data
46 | - `media/` - a directory used to store media that will be scanned by jellyfin
47 |
48 | Please make sure that all the files and directories are present.
49 |
50 | # Information
51 |
52 | ## docker-compose
53 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
54 |
55 | * docker-compose.yml
56 | ```yaml
57 | version: '3'
58 |
59 | services:
60 | jellyfin:
61 | image: jellyfin/jellyfin
62 | container_name: jellyfin
63 | volumes:
64 | - ./config:/config
65 | - ./cache:/cache
66 | - ./media:/media
67 | labels:
68 | - "traefik.enable=true"
69 | - "traefik.http.routers.jellyfin.rule=Host(`${TRAEFIK_JELLYFIN}`)"
70 | - "traefik.http.routers.jellyfin.entrypoints=https"
71 | - "traefik.http.routers.jellyfin.tls=true"
72 | - "traefik.http.routers.jellyfin.tls.certresolver=mydnschallenge"
73 |
74 | # Watchtower Update
75 | - "com.centurylinklabs.watchtower.enable=true"
76 | networks:
77 | - proxy
78 |
79 | networks:
80 | proxy:
81 | external: true
82 | ```
83 | * .env
84 | ```ini
85 | TRAEFIK_JELLYFIN=jellyfin.example.com
86 | ```
87 |
88 | # Usage
89 |
90 | ## Requirements
91 | - [Traefik up and running](../traefik).
92 | - A subdomain of your choice, this example uses `jellyfin`.
93 | - You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
94 |
95 | ## Configuration
96 |
97 | Replace the environment variables in `.env` with your own, then run :
98 |
99 | ```bash
100 | sudo docker-compose up -d
101 | ```
102 |
103 | You should then be able to access the jellyfin web-ui.
104 |
105 | ## Note
106 |
107 | Jellyfin can be combined with [transmission](../transmission), download any media you want and watch them directly on jellyfin !
108 | In order to do that, you can configure a volume on transmission that will link to the volume in Jellyfin or the opposite.
109 |
110 | In transmission, you could replace
111 | ```
112 | - ./data/downloads:/downloads
113 | ```
114 | With :
115 | ```
116 | - ../jellyfin/media:/downloads
117 | ```
118 |
119 | This can be configured more precisely, depending on your use-case.
120 |
121 | # Update
122 |
123 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
124 |
125 | ```yaml
126 | # Watchtower Update
127 | - "com.centurylinklabs.watchtower.enable=true"
128 | ```
129 |
130 | # Backup
131 |
132 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
133 |
134 | You may want to exclude the cache and media folder from the backups, add the following to [`borg-backup/excludes.txt`](../borg-backup/excludes.txt):
135 | ```
136 | /full/path/to/jellyfin/cache
137 | /full/path/to/jellyfin/media
138 | ```
139 |
--------------------------------------------------------------------------------
/jellyfin/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | jellyfin:
5 | image: jellyfin/jellyfin
6 | container_name: jellyfin
7 | volumes:
8 | - ./config:/config
9 | - ./cache:/cache
10 | - ./media:/media
11 | labels:
12 | - "traefik.enable=true"
13 | - "traefik.http.routers.jellyfin.rule=Host(`${TRAEFIK_JELLYFIN}`)"
14 | - "traefik.http.routers.jellyfin.entrypoints=https"
15 | - "traefik.http.routers.jellyfin.tls=true"
16 | - "traefik.http.routers.jellyfin.tls.certresolver=mydnschallenge"
17 |
18 | # Watchtower Update
19 | - "com.centurylinklabs.watchtower.enable=true"
20 | networks:
21 | - proxy
22 |
23 | networks:
24 | proxy:
25 | external: true
--------------------------------------------------------------------------------
/nextcloud/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_NEXTCLOUD=nextcloud.example.com
2 | DB_ROOT_PASSWD=xxxxxxxxxxxxxxx
3 | DB_PASSWD=xxxxxxxxxxxxxxx
--------------------------------------------------------------------------------
/nextcloud/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Nextcloud is a safe home for all your data. Access & share your files, calendars, contacts, mail & more from any device, on your terms.
8 |
9 | * [Github](https://github.com/nextcloud/docker)
10 | * [Documentation](https://docs.nextcloud.com/server/latest/admin_manual/contents.html)
11 | * [Docker Image](https://hub.docker.com/_/nextcloud)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Files structure](#files-structure)
20 | - [Information](#information)
21 | - [docker-compose](#docker-compose)
22 | - [Usage](#usage)
23 | - [Requirements](#requirements)
24 | - [Configuration](#configuration)
25 | - [Update](#update)
26 | - [Security](#security)
27 | - [Backup](#backup)
28 |
29 |
30 |
31 | # Files structure
32 |
33 | ```bash
34 | .
35 | |-- .env
36 | |-- docker-compose.yml
37 | |-- nextcloud-mysql/
38 | `-- shared/
39 | ```
40 |
41 | - `.env` - a file containing all the environment variables used in the docker-compose.yml
42 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
43 | - `nextcloud-mysql/` - a directory used to store the mysql data
44 | - `shared/` - a directory used to store nextcloud's data
45 |
46 | Please make sure that all the files and directories are present.
47 |
48 | # Information
49 |
50 | ## docker-compose
51 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
52 |
53 | * docker-compose.yml
54 | ```yaml
55 | version: '3'
56 |
57 | services:
58 | db:
59 | image: mariadb:10.5
60 | container_name: nextcloud-mysql
61 | restart: unless-stopped
62 | command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
63 | volumes:
64 | - ./nextcloud-mysql/db:/var/lib/mysql
65 | environment:
66 | - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWD} # Requested, set the root's password of MySQL service.
67 | - MYSQL_PASSWORD=${DB_PASSWD}
68 | - MYSQL_DATABASE=nextcloud
69 | - MYSQL_USER=nextcloud
70 | - MYSQL_LOG_CONSOLE=true
71 | networks:
72 | - nextcloud-net
73 | labels:
74 | # Watchtower Update
75 | - "com.centurylinklabs.watchtower.enable=true"
76 |
77 | nextcloud:
78 | image: nextcloud:latest
79 | container_name: nextcloud
80 | restart: unless-stopped
81 | volumes:
82 | - ./shared:/shared
83 | networks:
84 | - proxy
85 | - nextcloud-net
86 | depends_on:
87 | - db
88 | labels:
89 | - "traefik.enable=true"
90 | - "traefik.http.routers.nextcloud.rule=Host(`${TRAEFIK_NEXTCLOUD}`)"
91 | - "traefik.http.routers.nextcloud.entrypoints=https"
92 | - "traefik.http.routers.nextcloud.tls=true"
93 | - "traefik.http.routers.nextcloud.tls.certresolver=mydnschallenge"
94 | # Watchtower Update
95 | - "com.centurylinklabs.watchtower.enable=true"
96 | # Ip filtering
97 | - "traefik.http.routers.nextcloud.middlewares=whitelist@file"
98 |
99 | networks:
100 | nextcloud-net:
101 | proxy:
102 | external: true
103 | ```
104 | * .env
105 | ```ini
106 | TRAEFIK_NEXTCLOUD=nextcloud.example.com
107 | DB_ROOT_PASSWD=xxxxxxxxxxxxxxx
108 | DB_PASSWD=xxxxxxxxxxxxxxx
109 | ```
110 |
111 |
112 |
113 | # Usage
114 |
115 | ## Requirements
116 | - [Traefik up and running](../traefik).
117 | - A subdomain of your choice, this example uses `nextcloud`.
118 | - You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
119 |
120 | ## Configuration
121 |
122 | Replace the environment variables in `.env` with your own, then run :
123 |
124 | ```bash
125 | sudo docker-compose up -d
126 | ```
127 |
128 | You should now be able to access the nextcloud admin account creation.
129 | Nextcloud will ask you to create your admin account as well as to choose what type of database your want to use. In the docker-compose we set up a mariadb database, choose it and enter the following database credentials.
130 |
131 |
132 |
133 |
134 |
135 | The password is the one you have modified in the `.env` file : DB_PASSWD.
136 | Nextcloud will now finish installing and will soon be ready to use.
137 |
138 |
139 | # Update
140 |
141 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
142 |
143 | ```yaml
144 | # Watchtower Update
145 | - "com.centurylinklabs.watchtower.enable=true"
146 | ```
147 |
148 | # Security
149 |
150 | Nextcloud provides client-side end-to-end data encryption. You can create encrypted libraries to use this feature. Use this feature to add extra security to your documents.
151 |
152 | # Backup
153 |
154 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/nextcloud/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | db:
5 | image: mariadb:10.5
6 | container_name: nextcloud-mysql
7 | restart: unless-stopped
8 | command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
9 | volumes:
10 | - ./nextcloud-mysql/db:/var/lib/mysql
11 | environment:
12 | - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWD} # Requested, set the root's password of MySQL service.
13 | - MYSQL_PASSWORD=${DB_PASSWD}
14 | - MYSQL_DATABASE=nextcloud
15 | - MYSQL_USER=nextcloud
16 | - MYSQL_LOG_CONSOLE=true
17 | networks:
18 | - nextcloud-net
19 | labels:
20 | # Watchtower Update
21 | - "com.centurylinklabs.watchtower.enable=true"
22 |
23 | nextcloud:
24 | image: nextcloud:latest
25 | container_name: nextcloud
26 | restart: unless-stopped
27 | volumes:
28 | - ./shared:/shared
29 | networks:
30 | - proxy
31 | - nextcloud-net
32 | depends_on:
33 | - db
34 | labels:
35 | - "traefik.enable=true"
36 | - "traefik.http.routers.nextcloud.rule=Host(`${TRAEFIK_NEXTCLOUD}`)"
37 | - "traefik.http.routers.nextcloud.entrypoints=https"
38 | - "traefik.http.routers.nextcloud.tls=true"
39 | - "traefik.http.routers.nextcloud.tls.certresolver=mydnschallenge"
40 | # Watchtower Update
41 | - "com.centurylinklabs.watchtower.enable=true"
42 | # Ip filtering
43 | - "traefik.http.routers.nextcloud.middlewares=whitelist@file"
44 |
45 | networks:
46 | nextcloud-net:
47 | proxy:
48 | external: true
--------------------------------------------------------------------------------
/seafile/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_SEAFILE=seafile.example.com
2 | DB_ROOT_PASSWD=xxxxxxxxxxxxxxx
3 | SEAFILE_ADMIN_EMAIL=admin@example.com
4 | SEAFILE_ADMIN_PASSWORD=xxxxxxxxxxxxxxxx
--------------------------------------------------------------------------------
/seafile/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Seafile is an open-source, cross-platform file-hosting software system. Files are stored on a central server and can be synchronized with personal computers and mobile devices through apps or through the web interface.
8 |
9 | * [Github](https://github.com/haiwen/seafile)
10 | * [Documentation](https://manual.seafile.com/docker/deploy_seafile_with_docker/)
11 | * [Docker Image](https://hub.docker.com/r/seafileltd/seafile-mc)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Files structure](#files-structure)
20 | - [Information](#information)
21 | - [docker-compose](#docker-compose)
22 | - [Usage](#usage)
23 | - [Requirements](#requirements)
24 | - [Configuration](#configuration)
25 | - [Update](#update)
26 | - [Security](#security)
27 | - [Backup](#backup)
28 |
29 |
30 |
31 | # Files structure
32 |
33 | ```bash
34 | .
35 | |-- .env
36 | |-- docker-compose.yml
37 | |-- seafile-mysql/
38 | `-- shared/
39 | ```
40 |
41 | - `.env` - a file containing all the environment variables used in the docker-compose.yml
42 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
43 | - `seafile-mysql/` - a directory used to store the mysql data
44 | - `shared/` - a directory used to store seafile's data
45 |
46 | Please make sure that all the files and directories are present.
47 |
48 | # Information
49 |
50 | ## docker-compose
51 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
52 |
53 | * docker-compose.yml
54 | ```yaml
55 | version: '3'
56 |
57 | services:
58 | db:
59 | image: mariadb:10.5
60 | container_name: seafile-mysql
61 | restart: unless-stopped
62 | volumes:
63 | - ./seafile-mysql/db:/var/lib/mysql
64 | environment:
65 | - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWD} # Requested, set the root's password of MySQL service.
66 | - MYSQL_LOG_CONSOLE=true
67 | networks:
68 | - seafile-net
69 | labels:
70 | # Watchtower Update
71 | - "com.centurylinklabs.watchtower.enable=true"
72 |
73 | memcached:
74 | image: memcached:latest
75 | container_name: seafile-memcached
76 | restart: unless-stopped
77 | entrypoint: memcached -m 256
78 | networks:
79 | - seafile-net
80 | labels:
81 | # Watchtower Update
82 | - "com.centurylinklabs.watchtower.enable=true"
83 |
84 | seafile:
85 | image: seafileltd/seafile-mc:latest
86 | container_name: seafile
87 | restart: unless-stopped
88 | volumes:
89 | - ./shared:/shared
90 | environment:
91 | - DB_HOST=db
92 | - DB_ROOT_PASSWD=${DB_ROOT_PASSWD} # Requested, the value shuold be root's password of MySQL service.
93 | - SEAFILE_ADMIN_EMAIL=${SEAFILE_ADMIN_EMAIL} # Specifies Seafile admin user, default is 'me@example.com'.
94 | - SEAFILE_ADMIN_PASSWORD=${SEAFILE_ADMIN_PASSWORD} # Specifies Seafile admin password, default is 'asecret'.
95 | - SEAFILE_SERVER_LETSENCRYPT=false # Whether to use https or not.
96 | - SEAFILE_SERVER_HOSTNAME=${TRAEFIK_SEAFILE} # Specifies your host name if https is enabled.
97 | - SEAFILE_SERVICE_URL=https://${TRAEFIK_SEAFILE}
98 | networks:
99 | - proxy
100 | - seafile-net
101 | depends_on:
102 | - db
103 | - memcached
104 | labels:
105 | - "traefik.enable=true"
106 | - "traefik.http.routers.seafile.rule=Host(`${TRAEFIK_SEAFILE}`)"
107 | - "traefik.http.routers.seafile.entrypoints=https"
108 | - "traefik.http.routers.seafile.tls=true"
109 | - "traefik.http.routers.seafile.tls.certresolver=mydnschallenge"
110 | # Watchtower Update
111 | - "com.centurylinklabs.watchtower.enable=true"
112 | # Ip filtering
113 | - "traefik.http.routers.seafile.middlewares=whitelist@file"
114 |
115 | networks:
116 | seafile-net:
117 | proxy:
118 | external: true
119 | ```
120 | * .env
121 | ```ini
122 | TRAEFIK_SEAFILE=seafile.example.com
123 | DB_ROOT_PASSWD=xxxxxxxxxxxxxxx
124 | SEAFILE_ADMIN_EMAIL=admin@example.com
125 | SEAFILE_ADMIN_PASSWORD=xxxxxxxxxxxxxxxx
126 | ```
127 |
128 | # Usage
129 |
130 | ## Requirements
131 | - [Traefik up and running](../traefik).
132 | - A subdomain of your choice, this example uses `seafile`.
133 | - You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
134 |
135 | ## Configuration
136 |
137 | Replace the environment variables in `.env` with your own, then run :
138 |
139 | ```bash
140 | sudo docker-compose up -d
141 | ```
142 |
143 | You should then be able to access the seafile web-ui with the SEAFILE_ADMIN_EMAIL and SEAFILE_ADMIN_PASSWORD.
144 |
145 | # Update
146 |
147 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
148 |
149 | ```yaml
150 | # Watchtower Update
151 | - "com.centurylinklabs.watchtower.enable=true"
152 | ```
153 |
154 | # Security
155 |
156 | Seafile provides client-side end-to-end data encryption. You can create encrypted libraries to use this feature. Use this feature to add extra security to your documents.
157 |
158 | # Backup
159 |
160 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/seafile/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | db:
5 | image: mariadb:10.5
6 | container_name: seafile-mysql
7 | restart: unless-stopped
8 | volumes:
9 | - ./seafile-mysql/db:/var/lib/mysql
10 | environment:
11 | - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWD} # Requested, set the root's password of MySQL service.
12 | - MYSQL_LOG_CONSOLE=true
13 | networks:
14 | - seafile-net
15 | labels:
16 | # Watchtower Update
17 | - "com.centurylinklabs.watchtower.enable=true"
18 |
19 | memcached:
20 | image: memcached:latest
21 | container_name: seafile-memcached
22 | restart: unless-stopped
23 | entrypoint: memcached -m 256
24 | networks:
25 | - seafile-net
26 | labels:
27 | # Watchtower Update
28 | - "com.centurylinklabs.watchtower.enable=true"
29 |
30 | seafile:
31 | image: seafileltd/seafile-mc:latest
32 | container_name: seafile
33 | restart: unless-stopped
34 | volumes:
35 | - ./shared:/shared
36 | environment:
37 | - DB_HOST=db
38 | - DB_ROOT_PASSWD=${DB_ROOT_PASSWD} # Requested, the value shuold be root's password of MySQL service.
39 | - SEAFILE_ADMIN_EMAIL=${SEAFILE_ADMIN_EMAIL} # Specifies Seafile admin user, default is 'me@example.com'.
40 | - SEAFILE_ADMIN_PASSWORD=${SEAFILE_ADMIN_PASSWORD} # Specifies Seafile admin password, default is 'asecret'.
41 | - SEAFILE_SERVER_LETSENCRYPT=false # Whether to use https or not.
42 | - SEAFILE_SERVER_HOSTNAME=${TRAEFIK_SEAFILE} # Specifies your host name if https is enabled.
43 | - SEAFILE_SERVICE_URL=https://${TRAEFIK_SEAFILE}
44 | networks:
45 | - proxy
46 | - seafile-net
47 | depends_on:
48 | - db
49 | - memcached
50 | labels:
51 | - "traefik.enable=true"
52 | - "traefik.http.routers.seafile.rule=Host(`${TRAEFIK_SEAFILE}`)"
53 | - "traefik.http.routers.seafile.entrypoints=https"
54 | - "traefik.http.routers.seafile.tls=true"
55 | - "traefik.http.routers.seafile.tls.certresolver=mydnschallenge"
56 | # Watchtower Update
57 | - "com.centurylinklabs.watchtower.enable=true"
58 | # Ip filtering
59 | - "traefik.http.routers.seafile.middlewares=whitelist@file"
60 |
61 | networks:
62 | seafile-net:
63 | proxy:
64 | external: true
--------------------------------------------------------------------------------
/synapse-element/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_MATRIX=matrix.example.com
2 | TRAEFIK_ELEMENT=element.example.com
--------------------------------------------------------------------------------
/synapse-element/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Matrix is an open standard for decentralised communication, which securely distributes persistent chatrooms over an open federation of servers preventing any single points of control or failure.
10 |
11 | Synapse is a Matrix "homeserver" implementation developed by the matrix.org core team.
12 |
13 | Element is a Matrix web client built using the Matrix React SDK.
14 |
15 | * Synapse
16 | * [Github](https://github.com/matrix-org/synapse)
17 | * [Documentation](https://matrix-org.github.io/synapse/latest/)
18 | * [Docker Image](https://hub.docker.com/r/matrixdotorg/synapse)
19 |
20 | * Element
21 | * [Github](https://github.com/vector-im/element-web)
22 | * [Docker Image](https://hub.docker.com/r/vectorim/element-web)
23 |
24 | # Table of Contents
25 |
26 |
27 |
28 | - [About](#about)
29 | - [Table of Contents](#table-of-contents)
30 | - [Files structure](#files-structure)
31 | - [Information](#information)
32 | - [docker-compose](#docker-compose)
33 | - [Usage](#usage)
34 | - [Requirements](#requirements)
35 | - [Configuration](#configuration)
36 | - [Update](#update)
37 | - [Security](#security)
38 | - [Backup](#backup)
39 |
40 |
41 |
42 |
43 | # Files structure
44 |
45 | ```bash
46 | .
47 | |-- docker-compose.yml
48 | |-- matrix-data/
49 | |-- element-web/config.json
50 | ```
51 |
52 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
53 | - `matrix-data/` - a directory used to store the matrix data
54 | - `element-web/config.json` - a file used to store element's data
55 |
56 | Please make sure that all the files and directories are present.
57 |
58 | # Information
59 |
60 | ## docker-compose
61 | Links to the following [docker-compose.yml](docker-compose.yml).
62 |
63 | * docker-compose.yml
64 | ```yaml
65 | version: '3'
66 |
67 | services:
68 |
69 | synapse:
70 | image: matrixdotorg/synapse:latest
71 | restart: unless-stopped
72 | container_name: synapse
73 | environment:
74 | - SYNAPSE_LOG_LEVEL=INFO
75 | volumes:
76 | - ./matrix-data:/data
77 | labels:
78 | - "traefik.enable=true"
79 | - "traefik.http.routers.synapse.rule=Host(`${TRAEFIK_MATRIX}`)"
80 | - "traefik.http.routers.synapse.entrypoints=https"
81 | - "traefik.http.routers.synapse.tls=true"
82 | - "traefik.http.routers.synapse.tls.certresolver=mydnschallenge"
83 |
84 | # Watchtower Update
85 | - "com.centurylinklabs.watchtower.enable=true"
86 | networks:
87 | - proxy
88 |
89 | element:
90 | image: vectorim/element-web:latest
91 | restart: unless-stopped
92 | container_name: element
93 | depends_on:
94 | - synapse
95 | volumes:
96 | - ./element-web/config.json:/app/config.json:ro
97 | labels:
98 | - "traefik.enable=true"
99 | - "traefik.http.routers.element.rule=Host(`${TRAEFIK_ELEMENT}`)"
100 | - "traefik.http.routers.element.entrypoints=https"
101 | - "traefik.http.routers.element.tls=true"
102 | - "traefik.http.routers.element.tls.certresolver=mydnschallenge"
103 |
104 | # Watchtower Update
105 | - "com.centurylinklabs.watchtower.enable=true"
106 | networks:
107 | - proxy
108 |
109 |
110 | networks:
111 | proxy:
112 | external: true
113 | ```
114 | * .env
115 | ```ini
116 | TRAEFIK_MATRIX=matrix.example.com
117 | TRAEFIK_ELEMENT=element.example.com
118 | ```
119 |
120 |
121 | # Usage
122 |
123 | ## Requirements
124 | - [Traefik up and running](../traefik).
125 | - Subdomains of your choice, this example uses `element` and `matrix`.
126 | - You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
127 |
128 | ## Configuration
129 |
130 | Check that the URL is correct in `element-web/config.json` and replace the environment variables in `.env` with your own.
131 |
132 | The first step is to generate a valid config file. To do this, you can run the image with the generate command line option. Please replace the `SYNAPSE_SERVER_NAME` with your own.
133 |
134 | ```bash
135 | sudo docker run -it --rm \
136 | -v "$(pwd)/matrix-data:/data" \
137 | -e SYNAPSE_SERVER_NAME=matrix.example.com \
138 | -e SYNAPSE_REPORT_STATS=no \
139 | matrixdotorg/synapse:latest generate
140 | ```
141 |
142 | You can now start the service with :
143 |
144 | ```bash
145 | sudo docker-compose up -d
146 | ```
147 |
148 | You can check that the matrix server is working by accessing the URL. You should then be able to access the element web-ui and create a new account. By default, the registration is disabled, change the `enable_registration` value to `true` in `matrix-data/homeserver.yaml`, then restart the container.
149 |
150 | # Update
151 |
152 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
153 |
154 | ```yaml
155 | # Watchtower Update
156 | - "com.centurylinklabs.watchtower.enable=true"
157 | ```
158 |
159 | # Security
160 |
161 | You can modify the matrix config file to increase security : `matrix-data/homeserver.yaml`.
162 | After you have created your account, you can disable registration with `enable_registration: false`.
163 |
164 |
165 |
166 | # Backup
167 |
168 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/synapse-element/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 |
5 | synapse:
6 | image: matrixdotorg/synapse:latest
7 | restart: unless-stopped
8 | container_name: synapse
9 | environment:
10 | - SYNAPSE_LOG_LEVEL=INFO
11 | volumes:
12 | - ./matrix-data:/data
13 | labels:
14 | - "traefik.enable=true"
15 | - "traefik.http.routers.synapse.rule=Host(`${TRAEFIK_MATRIX}`)"
16 | - "traefik.http.routers.synapse.entrypoints=https"
17 | - "traefik.http.routers.synapse.tls=true"
18 | - "traefik.http.routers.synapse.tls.certresolver=mydnschallenge"
19 |
20 | # Watchtower Update
21 | - "com.centurylinklabs.watchtower.enable=true"
22 | networks:
23 | - proxy
24 |
25 | element:
26 | image: vectorim/element-web:latest
27 | restart: unless-stopped
28 | container_name: element
29 | depends_on:
30 | - synapse
31 | volumes:
32 | - ./element-web/config.json:/app/config.json:ro
33 | labels:
34 | - "traefik.enable=true"
35 | - "traefik.http.routers.element.rule=Host(`${TRAEFIK_ELEMENT}`)"
36 | - "traefik.http.routers.element.entrypoints=https"
37 | - "traefik.http.routers.element.tls=true"
38 | - "traefik.http.routers.element.tls.certresolver=mydnschallenge"
39 |
40 | # Watchtower Update
41 | - "com.centurylinklabs.watchtower.enable=true"
42 | networks:
43 | - proxy
44 |
45 |
46 | networks:
47 | proxy:
48 | external: true
--------------------------------------------------------------------------------
/synapse-element/element-web/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "default_server_config": {
3 | "m.homeserver": {
4 | "base_url": "https://matrix.example.com",
5 | "server_name": "example.com"
6 | },
7 | "m.identity_server": {
8 | "base_url": "https://vector.im"
9 | }
10 | },
11 | "disable_custom_urls": false,
12 | "disable_guests": false,
13 | "disable_login_language_selector": false,
14 | "disable_3pid_login": false,
15 | "brand": "2li Matrix",
16 | "integrations_ui_url": "https://scalar.vector.im/",
17 | "integrations_rest_url": "https://scalar.vector.im/api",
18 | "integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
19 | "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
20 | "defaultCountryCode": "GB",
21 | "showLabsSettings": false,
22 | "features": {
23 | "feature_pinning": "labs",
24 | "feature_custom_status": "labs",
25 | "feature_custom_tags": "labs",
26 | "feature_state_counters": "labs"
27 | },
28 | "default_federate": true,
29 | "default_theme": "light"
30 | }
--------------------------------------------------------------------------------
/traefik/.env:
--------------------------------------------------------------------------------
1 | # DOMAIN.TLD = example.com
2 | DOMAIN=example
3 | TLD=com
4 |
5 | # DNS challenge credentials - will not be the same if you are using another provider
6 | OVH_ENDPOINT=xxxxxxxxxxxxxxxxxxxxxxx
7 | OVH_APPLICATION_KEY=xxxxxxxxxxxxxxxxxxxxxxx
8 | OVH_APPLICATION_SECRET=xxxxxxxxxxxxxxxxxxxxxxx
9 | OVH_CONSUMER_KEY=xxxxxxxxxxxxxxxxxxxxxxx
--------------------------------------------------------------------------------
/traefik/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Traefik is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy.
8 | It is an Edge Router, it means that it's the door to your platform, and that it intercepts and routes every incoming request.
9 |
10 | * [Github](https://github.com/traefik/traefik/)
11 | * [Documentation](https://doc.traefik.io/traefik/)
12 | * [Docker Image](https://hub.docker.com/_/traefik)
13 |
14 | Traefik is a key component for this selfhosted infrastructure, it is providing the following features :
15 |
16 | - Act as a reverse proxy, enabling you to self-hosted multiple services behind a single IP
17 | - HTTPS for your services by leveraging Let's Encrypt
18 | - Easily configure TLS for all services
19 | - Use a whitelist to restrict services to a fix set of IPs
20 |
21 |
22 | # Table of Contents
23 |
24 |
25 |
26 | - [About](#about)
27 | - [Table of Contents](#table-of-contents)
28 | - [Files structure](#files-structure)
29 | - [Information](#information)
30 | - [docker-compose](#docker-compose)
31 | - [socket-proxy](#socket-proxy)
32 | - [traefik](#traefik)
33 | - [DNS Challenge with Let's Encrypt](#dns-challenge-with-lets-encrypt)
34 | - [Global redirect to HTTPS](#global-redirect-to-https)
35 | - [Redirect root to www](#redirect-root-to-www)
36 | - [Usage](#usage)
37 | - [Requirements](#requirements)
38 | - [Configuration](#configuration)
39 | - [Note](#note)
40 | - [Update](#update)
41 | - [Security](#security)
42 | - [Backup](#backup)
43 |
44 |
45 |
46 | # Files structure
47 |
48 | ```bash
49 | .
50 | |-- .env
51 | |-- docker-compose.yml
52 | |-- letsencrypt/
53 | |-- rules/
54 | | |-- tls.yml
55 | | `-- whitelist.yml
56 | `-- traefik.yml
57 | ```
58 |
59 | - `.env` - a file containing all the environment variables used in the docker-compose.yml
60 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
61 | - `letsencrypt/` - a directory used to store the certificates' information
62 | - `rules/` - a directory used to store traefik optional rules (TLS, IP whitelist)
63 | - `traefik.yml` - traefik configuration file
64 |
65 | Please make sure that all the files and directories are present.
66 |
67 | # Information
68 |
69 | Traefik has multiple ways to be configured, I will be using two of them for this guide :
70 | - Configuration file : Such as traefik.yml, tls.yml, ...
71 | - Labels : Used in a docker-compose file
72 |
73 | The configuration could be done using only one of the two method, but I find it easy to use files for standard configurations that should almost never change and labels to allow a more dynamic configuration.
74 |
75 | ## docker-compose
76 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
77 |
78 | * docker-compose.yml
79 | ```yaml
80 | version: "3"
81 |
82 | services:
83 | traefik:
84 | image: "traefik:latest"
85 | container_name: "traefik"
86 | restart: unless-stopped
87 | depends_on:
88 | - socket-proxy
89 | ports:
90 | - "80:80"
91 | - "443:443"
92 | volumes:
93 | - "./traefik.yml:/traefik.yml:ro"
94 | - "./rules:/rules:ro"
95 | - "./letsencrypt:/letsencrypt"
96 | environment:
97 | - OVH_ENDPOINT=${OVH_ENDPOINT}
98 | - OVH_APPLICATION_KEY=${OVH_APPLICATION_KEY}
99 | - OVH_APPLICATION_SECRET=${OVH_APPLICATION_SECRET}
100 | - OVH_CONSUMER_KEY=${OVH_CONSUMER_KEY}
101 | networks:
102 | - proxy
103 | labels:
104 | - "traefik.enable=true"
105 |
106 | # global redirect to https
107 | - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
108 | - "traefik.http.routers.http-catchall.entrypoints=http"
109 | - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
110 |
111 | # middleware redirect
112 | - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
113 | - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
114 |
115 | # redirect root to www
116 | - "traefik.http.routers.root.rule=host(`example.com`)"
117 | - "traefik.http.routers.root.entrypoints=https"
118 | - "traefik.http.routers.root.middlewares=redirect-root-to-www"
119 | - "traefik.http.routers.root.tls=true"
120 |
121 | # middleware redirect root to www
122 | - "traefik.http.middlewares.redirect-root-to-www.redirectregex.regex=^https://example\\.com/(.*)"
123 | - "traefik.http.middlewares.redirect-root-to-www.redirectregex.replacement=https://www.example.com/$${1}"
124 |
125 | # Watchtower Update
126 | - "com.centurylinklabs.watchtower.enable=true"
127 |
128 | socket-proxy:
129 | image: tecnativa/docker-socket-proxy
130 | container_name: traefik-socket-proxy
131 | restart: unless-stopped
132 | volumes:
133 | - /var/run/docker.sock:/var/run/docker.sock:ro
134 | environment:
135 | CONTAINERS: 1
136 | networks:
137 | - proxy
138 | labels:
139 | # Watchtower Update
140 | - "com.centurylinklabs.watchtower.enable=true"
141 |
142 | networks:
143 | proxy:
144 | external: true
145 | ```
146 | * .env
147 | ```ini
148 | # DOMAIN.TLD = example.com
149 | DOMAIN=example
150 | TLD=com
151 |
152 | # DNS challenge credentials - will not be the same if you are using another provider
153 | OVH_ENDPOINT=xxxxxxxxxxxxxxxxxxxxxxx
154 | OVH_APPLICATION_KEY=xxxxxxxxxxxxxxxxxxxxxxx
155 | OVH_APPLICATION_SECRET=xxxxxxxxxxxxxxxxxxxxxxx
156 | OVH_CONSUMER_KEY=xxxxxxxxxxxxxxxxxxxxxxx
157 | ```
158 |
159 | The docker-compose contains two services :
160 | - socket-proxy : This ensures Docker’s socket file to not be exposed to the public
161 | - traefik : Traefik application configuration
162 |
163 | ## socket-proxy
164 |
165 | The socket-proxy service is used to protect the docker socket, allowing Traefik unrestricted access to your Docker socket file could result in a vulnerability to the host computer, as per [Traefik own documentation](https://doc.traefik.io/traefik/providers/docker/#docker-api-access), should any other part of the Traefik container ever be compromised.
166 |
167 | Instead of allowing Traefik container full access to the Docker socket file, we can instead proxy only the API calls we need with [Tecnativa’s Docker Socket Proxy](https://github.com/Tecnativa/docker-socket-proxy), following the [principle of the least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege).
168 |
169 | ## traefik
170 |
171 | ### DNS Challenge with Let's Encrypt
172 |
173 | Traefik can use an ACME provider (like Let's Encrypt) for automatic certificate generation. It will create the certificate and attempt to renew it automatically 30 days before expiration. One of the great benefit of using DNS challenges is that it will allow us to use wildcard certificates, on the other hand, it can create a security risk as it requires giving rights to Traefik to create and remove some DNS records.
174 |
175 | For the DNS challenge, you'll need a [working provider](https://doc.traefik.io/traefik/https/acme/#providers) along with the credentials allowing to create and remove DNS records,
176 | If you are using OVH, you can use this [guide](https://medium.com/nephely/configure-traefik-for-the-dns-01-challenge-with-ovh-as-dns-provider-c737670c0434) to retrieve the credentials.
177 |
178 |
179 | ### Global redirect to HTTPS
180 |
181 | ```yaml
182 | # global redirect to https
183 | - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
184 | - "traefik.http.routers.http-catchall.entrypoints=http"
185 | - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
186 | ```
187 | This rule will match all the HTTP requests and redirect them to HTTPS. It uses the redirect-to-https middleware.
188 |
189 | ### Redirect root to www
190 |
191 | ```yaml
192 | # redirect root to www
193 | - "traefik.http.routers.root.rule=host(`example.com`)"
194 | - "traefik.http.routers.root.entrypoints=https"
195 | - "traefik.http.routers.root.middlewares=redirect-root-to-www"
196 | - "traefik.http.routers.root.tls=true"
197 | ```
198 | This rule will automatically redirect the root domain `example.com` to `www.example.com`. You can use the [webserver](../webserver) example to set up a website using docker.
199 |
200 | # Usage
201 |
202 | ## Requirements
203 | - A domain, we will use example.com for this guide.
204 | - DNS manager, usually it goes with the provider you used for your domain. We will use OVH for the guide. List of compatible [providers](https://doc.traefik.io/traefik/https/acme/#providers).
205 | - Ports 80 and 443 open, check your firewall.
206 |
207 |
208 | ## Configuration
209 | Before using the docker-compose file, please update the following configurations.
210 |
211 | - **change the domain** : The current domain is example.com, change it to your domain. The change need to be made in `.env` and `traefik.yml`
212 | ```bash
213 | DOMAIN=example
214 | TLD=com
215 | sed -i -e "s/example/'$DOMAIN'/g" .env
216 | sed -i -e "s/com/'$TLD'/g" .env
217 | sed -i -e "s/example.com/'$DOMAIN'.'$TLD'/g" traefik.yml
218 | ```
219 |
220 | - **change the dns provider credentials** : Replace the provider name in `traefik.yml` if you are not using ovh. Replace the environment variables in `.env` and in `docker-compose.yml`. The example uses OVH but it can work with other providers, such as GoDaddy :
221 | - Get the [required settings](https://go-acme.github.io/lego/dns/godaddy/) and update the `.env` file
222 | ```bash
223 | # DNS challenge credentials
224 | GODADDY_API_KEY=xxxxx
225 | GODADDY_API_SECRET=xxxxx
226 | ```
227 | - This is the only case where you are going to have to modify the docker-compose
228 | ```yaml
229 | environment:
230 | - GODADDY_API_KEY${GODADDY_API_KEY}
231 | - GODADDY_API_SECRET=${GODADDY_API_SECRET}
232 | ```
233 |
234 | - **create the docker network** : As our services are split in multiple docker-compose, we need a network so that traefik can forward the requests.
235 | ```bash
236 | sudo docker network create proxy
237 | ```
238 |
239 | - **update the whitelist (optional)** : Replace the IP address in `rules/whitelist.yml`. Use the IP address as well as the [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). Whitelist is disable by default with `0.0.0.0/0`. The whitelist will be used on containers setting the following label.
240 | ```yaml
241 | # Ip filtering
242 | - "traefik.http.routers.service-router-name.middlewares=whitelist@file"
243 | ```
244 | You can use the private IP address range used by docker (172.16.0.0/12) if you are using [wireguard](../wireguard-pihole-unbound). Then your services will only be available through your VPN (recommend for a better security).
245 |
246 | You can now run :
247 |
248 | ```bash
249 | sudo docker-compose up -d
250 | ```
251 | To check the logs :
252 |
253 | ```bash
254 | sudo docker logs traefik
255 | ```
256 |
257 | Traefik should be up and running ! To test if everything is running smoothly, you can try and use the [webserver](../webserver) service, it is a simple apache webserver showing `Hello World`.
258 | Keep in mind that traefik can take a little time to generate the first certificate, usually a couple of minutes.
259 |
260 | ## Note
261 |
262 | If you want to use the [Redirect root to www](#redirect-root-to-www) fonctionnality, you also need to have a certificate generated for your root domain. In order to do so, you will need to use a service which uses the root domain.
263 | The simplest way to do that is by running the [webserver](../webserver) service with the root domain. It only needs to be done once, you should then be able to see the entry in `letsencrypt/acme.json`, it will then be renewed automaticaly by traefik.
264 |
265 | # Update
266 |
267 | Both `traefik` and `socket-proxy` images are automatically updated with [watchtower](../watchtower) thanks to the following label :
268 |
269 | ```yaml
270 | # Watchtower Update
271 | - "com.centurylinklabs.watchtower.enable=true"
272 | ```
273 |
274 |
275 | # Security
276 |
277 | The socket-proxy service is used to protect the docker socket.
278 |
279 | # Backup
280 |
281 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/traefik/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | traefik:
5 | image: "traefik:latest"
6 | container_name: "traefik"
7 | restart: unless-stopped
8 | depends_on:
9 | - socket-proxy
10 | ports:
11 | - "80:80"
12 | - "443:443"
13 | volumes:
14 | - "./traefik.yml:/traefik.yml:ro"
15 | - "./rules:/rules:ro"
16 | - "./letsencrypt:/letsencrypt"
17 | environment:
18 | - OVH_ENDPOINT=${OVH_ENDPOINT}
19 | - OVH_APPLICATION_KEY=${OVH_APPLICATION_KEY}
20 | - OVH_APPLICATION_SECRET=${OVH_APPLICATION_SECRET}
21 | - OVH_CONSUMER_KEY=${OVH_CONSUMER_KEY}
22 | networks:
23 | - proxy
24 | labels:
25 | - "traefik.enable=true"
26 |
27 | # global redirect to https
28 | - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
29 | - "traefik.http.routers.http-catchall.entrypoints=http"
30 | - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
31 |
32 | # middleware redirect
33 | - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
34 | - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
35 |
36 | # redirect root to www
37 | - "traefik.http.routers.root.rule=host(`${DOMAIN}.${TLD}`)"
38 | - "traefik.http.routers.root.entrypoints=https"
39 | - "traefik.http.routers.root.middlewares=redirect-root-to-www"
40 | - "traefik.http.routers.root.tls=true"
41 |
42 | # middleware redirect root to www
43 | - "traefik.http.middlewares.redirect-root-to-www.redirectregex.regex=^https://${DOMAIN}\\.${TLD}/(.*)"
44 | - "traefik.http.middlewares.redirect-root-to-www.redirectregex.replacement=https://www.${DOMAIN}.${TLD}/$${1}"
45 |
46 | # Watchtower Update
47 | - "com.centurylinklabs.watchtower.enable=true"
48 |
49 | socket-proxy:
50 | image: tecnativa/docker-socket-proxy
51 | container_name: traefik-socket-proxy
52 | restart: unless-stopped
53 | volumes:
54 | - /var/run/docker.sock:/var/run/docker.sock:ro
55 | environment:
56 | CONTAINERS: 1
57 | networks:
58 | - proxy
59 | labels:
60 | # Watchtower Update
61 | - "com.centurylinklabs.watchtower.enable=true"
62 |
63 | networks:
64 | proxy:
65 | external: true
--------------------------------------------------------------------------------
/traefik/rules/tls.yml:
--------------------------------------------------------------------------------
1 | tls:
2 | options:
3 | TLSv13:
4 | minVersion: VersionTLS13
5 | cipherSuites:
6 | - TLS_AES_256_GCM_SHA384
7 | - TLS_CHACHA20_POLY1305_SHA256
8 | sniStrict: true
9 |
10 | default:
11 | minVersion: VersionTLS12
12 | cipherSuites:
13 | - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
14 | - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
15 | sniStrict: true
--------------------------------------------------------------------------------
/traefik/rules/whitelist.yml:
--------------------------------------------------------------------------------
1 | http:
2 | middlewares:
3 | whitelist:
4 | ipWhiteList:
5 | sourceRange:
6 | - "0.0.0.0/0"
7 | # Private IP range use by docker, enable to enable services access through VPN
8 | #- "172.16.0.0/12"
--------------------------------------------------------------------------------
/traefik/traefik.yml:
--------------------------------------------------------------------------------
1 | entryPoints:
2 | http:
3 | address: ":80"
4 |
5 | https:
6 | address: ":443"
7 |
8 | providers:
9 | docker:
10 | endpoint: "tcp://socket-proxy:2375"
11 | exposedByDefault: false
12 |
13 | file:
14 | directory: /rules
15 | watch: true
16 |
17 | certificatesResolvers:
18 | mydnschallenge:
19 | acme:
20 | email: mail@example.com
21 | storage: ./letsencrypt/acme.json
22 | dnsChallenge:
23 | provider: ovh
24 | delayBeforeCheck: 10
25 |
26 | log:
27 | level: INFO
--------------------------------------------------------------------------------
/transmission/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_TRANSMISSION=transmission.example.com
2 | TZ=Europe/Paris
3 | WEB_USER=xxxxxxxxxxxxxxx
4 | WEB_PASS=xxxxxxxxxxxxxxx
5 |
6 | # user PUID and group PGID - can be found by running id your-user
7 | PUID=1000
8 | PGID=1000
--------------------------------------------------------------------------------
/transmission/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Transmission is a fast, easy, and free BitTorrent client.
8 |
9 | * [Github](https://github.com/transmission/transmission)
10 | * [website](https://transmissionbt.com/)
11 | * [Docker Image](https://hub.docker.com/r/linuxserver/transmission)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Information](#information)
20 | - [docker-compose](#docker-compose)
21 | - [Usage](#usage)
22 | - [Requirements](#requirements)
23 | - [Configuration](#configuration)
24 | - [Update](#update)
25 | - [Backup](#backup)
26 |
27 |
28 |
29 | ```bash
30 | .
31 | |-- .env
32 | |-- data/
33 | `-- docker-compose.yml
34 | ```
35 |
36 | * `.env` - a file containing all the environment variables used in the docker-compose.yml
37 | * `docker-compose.yml` - a docker-compose file, use to configure your application’s services
38 | * `data/` - a directory used to store the data
39 |
40 | Please make sure that all the files and directories are present.
41 |
42 | # Information
43 |
44 | ## docker-compose
45 |
46 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
47 |
48 | * docker-compose.yml
49 | ```yaml
50 | vversion: '3'
51 |
52 | services:
53 | transmission:
54 | image: 'linuxserver/transmission:latest'
55 | container_name: transmission
56 | restart: unless-stopped
57 | volumes:
58 | - ./data/config:/config
59 | - ./data/downloads:/downloads
60 | - ./data/watch:/watch
61 | environment:
62 | - PUID=${PUID}
63 | - PGID=${PGID}
64 | - TZ=${TZ}
65 | - USER=${WEB_USER}
66 | - PASS=${WEB_PASS}
67 | ports:
68 | - 51413:51413
69 | - 51413:51413/udp
70 | networks:
71 | - proxy
72 | labels:
73 | - "traefik.enable=true"
74 | - "traefik.http.routers.transmission.rule=Host(`${TRAEFIK_TRANSMISSION}`)"
75 | - "traefik.http.routers.transmission.entrypoints=https"
76 | - "traefik.http.routers.transmission.tls=true"
77 | - "traefik.http.routers.transmission.tls.certresolver=mydnschallenge"
78 | - "traefik.http.services.transmission.loadbalancer.server.port=9091"
79 | # Watchtower Update
80 | - "com.centurylinklabs.watchtower.enable=true"
81 |
82 | networks:
83 | proxy:
84 | external: true
85 | ```
86 | * .env
87 | ```
88 | TRAEFIK_TRANSMISSION=transmission.example.com
89 | TZ=Europe/Paris
90 | WEB_USER=xxxxxxxxxxxxxxx
91 | WEB_PASS=xxxxxxxxxxxxxxx
92 |
93 | # user PUID and group PGID - can be found by running id your-user
94 | PUID=1000
95 | PGID=1000
96 | ```
97 |
98 | The docker-compose contains only one service using the transmission image.
99 |
100 | # Usage
101 |
102 | ## Requirements
103 |
104 | * [Traefik up and running](../traefik).
105 | * A subdomain of your choice, this example uses `transmission`.
106 | * You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
107 | * Port 51413 open, check your firewall.
108 |
109 | ## Configuration
110 |
111 | The linuxserver images are using the PUID and PGID, they allow the container to map the container's internal user to a user on the host machine, more information [here](https://docs.linuxserver.io/general/understanding-puid-and-pgid).
112 |
113 | To find yours, use `id user`. Replace the environment variables in `.env` with your own, then run :
114 |
115 | ```bash
116 | sudo docker-compose up -d
117 | ```
118 |
119 | # Update
120 |
121 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
122 |
123 | ```yaml
124 | # Watchtower Update
125 | - "com.centurylinklabs.watchtower.enable=true"
126 | ```
127 |
128 | # Backup
129 |
130 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
131 |
132 | You may want to exclude the downloads folder from the backups, add the following to [`borg-backup/excludes.txt`](../borg-backup/excludes.txt):
133 | ```
134 | /full/path/to/transmission/data/downloads
135 | ```
136 |
--------------------------------------------------------------------------------
/transmission/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | transmission:
5 | image: 'linuxserver/transmission:latest'
6 | container_name: transmission
7 | restart: unless-stopped
8 | volumes:
9 | - ./data/config:/config
10 | - ./data/downloads:/downloads
11 | - ./data/watch:/watch
12 | environment:
13 | - PUID=${PUID}
14 | - PGID=${PGID}
15 | - TZ=${TZ}
16 | - USER=${WEB_USER}
17 | - PASS=${WEB_PASS}
18 | ports:
19 | - 51413:51413
20 | - 51413:51413/udp
21 | networks:
22 | - proxy
23 | labels:
24 | - "traefik.enable=true"
25 | - "traefik.http.routers.transmission.rule=Host(`${TRAEFIK_TRANSMISSION}`)"
26 | - "traefik.http.routers.transmission.entrypoints=https"
27 | - "traefik.http.routers.transmission.tls=true"
28 | - "traefik.http.routers.transmission.tls.certresolver=mydnschallenge"
29 | - "traefik.http.services.transmission.loadbalancer.server.port=9091"
30 | # Watchtower Update
31 | - "com.centurylinklabs.watchtower.enable=true"
32 |
33 | networks:
34 | proxy:
35 | external: true
--------------------------------------------------------------------------------
/trilium/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_TRILIUM=trilium.example.com
--------------------------------------------------------------------------------
/trilium/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Trilium Notes is a hierarchical note-taking application with focus on building large personal knowledge bases
8 |
9 | * [Github](https://github.com/zadam/trilium)
10 | * [Documentation](https://github.com/zadam/trilium/wiki/)
11 | * [Docker Image](https://hub.docker.com/r/zadam/trilium)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Information](#information)
20 | - [docker-compose](#docker-compose)
21 | - [Usage](#usage)
22 | - [Requirements](#requirements)
23 | - [Configuration](#configuration)
24 | - [Update](#update)
25 | - [Backup](#backup)
26 |
27 |
28 |
29 | ```bash
30 | .
31 | |-- .env
32 | |-- data/
33 | `-- docker-compose.yml
34 | ```
35 |
36 | * `.env` - a file containing all the environment variables used in the docker-compose.yml
37 | * `docker-compose.yml` - a docker-compose file, use to configure your application’s services
38 | * `data/` - a directory used to store the data
39 |
40 | Please make sure that all the files and directories are present.
41 |
42 | # Information
43 |
44 | ## docker-compose
45 |
46 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
47 |
48 | * docker-compose.yml
49 | ```yaml
50 | version: '3'
51 |
52 | services:
53 | trilium:
54 | image: 'zadam/trilium:latest'
55 | container_name: trilium
56 | restart: unless-stopped
57 | volumes:
58 | - "./data:/home/node/trilium-data"
59 | networks:
60 | - proxy
61 | labels:
62 | - "traefik.enable=true"
63 | - "traefik.http.routers.webserver.rule=Host(`${TRAEFIK_TRILIUM}`)"
64 | - "traefik.http.routers.webserver.entrypoints=https"
65 | - "traefik.http.routers.webserver.tls=true"
66 | - "traefik.http.routers.webserver.tls.certresolver=mydnschallenge"
67 | # Watchtower Update
68 | - "com.centurylinklabs.watchtower.enable=true"
69 |
70 | networks:
71 | proxy:
72 | external: true
73 | ```
74 | * .env
75 | ```
76 | TRAEFIK_TRILIUM=trilium.example.com
77 | ```
78 |
79 | The docker-compose contains only one service using the trilium image.
80 |
81 | # Usage
82 |
83 | ## Requirements
84 |
85 | * [Traefik up and running](../traefik).
86 | * A subdomain of your choice, this example uses `trilium`.
87 | * You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
88 |
89 | ## Configuration
90 |
91 | Replace the environment variables in `.env` with your own, then run :
92 |
93 | ```bash
94 | sudo docker-compose up -d
95 | ```
96 |
97 | You should then be able to access the trilium web-ui and start creating notes !
98 |
99 | # Update
100 |
101 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
102 |
103 | ```yaml
104 | # Watchtower Update
105 | - "com.centurylinklabs.watchtower.enable=true"
106 | ```
107 |
108 | # Backup
109 |
110 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
111 |
--------------------------------------------------------------------------------
/trilium/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | trilium:
5 | image: 'zadam/trilium:latest'
6 | container_name: trilium
7 | restart: unless-stopped
8 | volumes:
9 | - "./data:/home/node/trilium-data"
10 | networks:
11 | - proxy
12 | labels:
13 | - "traefik.enable=true"
14 | - "traefik.http.routers.trilium.rule=Host(`${TRAEFIK_TRILIUM}`)"
15 | - "traefik.http.routers.trilium.entrypoints=https"
16 | - "traefik.http.routers.trilium.tls=true"
17 | - "traefik.http.routers.trilium.tls.certresolver=mydnschallenge"
18 | # Watchtower Update
19 | - "com.centurylinklabs.watchtower.enable=true"
20 |
21 | networks:
22 | proxy:
23 | external: true
--------------------------------------------------------------------------------
/vaultwarden/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_VAULTWARDEN=vaultwarden.example.com
2 | ADMIN_TOKEN=xxxxxxxxxxxxxxxxx
--------------------------------------------------------------------------------
/vaultwarden/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Vaultwarden is an alternative implementation of the Bitwarden server API written in Rust and compatible with upstream Bitwarden clients, it is perfect for self-hosted deployment where running the official resource-heavy service might not be ideal.
8 |
9 | * [Github](https://github.com/dani-garcia/vaultwarden)
10 | * [Documentation](https://github.com/dani-garcia/vaultwarden/wiki)
11 | * [Docker Image](https://hub.docker.com/r/vaultwarden/server)
12 |
13 | Bitwarden is a free and open-source password management service that stores sensitive information such as website credentials in an encrypted vault.
14 |
15 | # Table of Contents
16 |
17 |
18 |
19 | - [About](#about)
20 | - [Table of Contents](#table-of-contents)
21 | - [Files structure](#files-structure)
22 | - [Information](#information)
23 | - [docker-compose](#docker-compose)
24 | - [Usage](#usage)
25 | - [Requirements](#requirements)
26 | - [Configuration](#configuration)
27 | - [Update](#update)
28 | - [Security](#security)
29 | - [Backup](#backup)
30 |
31 |
32 |
33 | # Files structure
34 |
35 | ```bash
36 | .
37 | |-- .env
38 | |-- data/
39 | `-- docker-compose.yml
40 | ```
41 |
42 | - `.env` - a file containing all the environment variables used in the docker-compose.yml
43 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
44 | - `data/` - a directory used to store vaultwarden data
45 |
46 | Please make sure that all the files and directories are present.
47 |
48 | # Information
49 |
50 | ## docker-compose
51 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
52 |
53 | * docker-compose.yml
54 | ```yaml
55 | version: "3"
56 |
57 | services:
58 | bitwardenrs:
59 | image: vaultwarden/server
60 | container_name: vaultwarden
61 | restart: unless-stopped
62 | volumes:
63 | - ./data:/data
64 | environment:
65 | - WEBSOCKET_ENABLED=true
66 | - WEB_VAULT_ENABLED=true
67 | - SIGNUPS_ALLOWED=false
68 | # Comment admin token to disable admin interface
69 | - ADMIN_TOKEN=${ADMIN_TOKEN}
70 | networks:
71 | - proxy
72 | labels:
73 | - "traefik.enable=true"
74 | - "traefik.http.routers.bitwarden.rule=Host(`${TRAEFIK_VAULTWARDEN}`)"
75 | - "traefik.http.routers.bitwarden.entrypoints=https"
76 | - "traefik.http.routers.bitwarden.tls=true"
77 | - "traefik.http.routers.bitwarden.tls.certresolver=mydnschallenge"
78 | # Watchtower Update
79 | - "com.centurylinklabs.watchtower.enable=true"
80 | # Ip filtering
81 | - "traefik.http.routers.bitwarden.middlewares=whitelist@file"
82 | logging:
83 | driver: "syslog"
84 | options:
85 | tag: "Bitwarden"
86 |
87 | networks:
88 | proxy:
89 | external: true
90 | ```
91 | * .env
92 | ```ini
93 | TRAEFIK_VAULTWARDEN=vaultwarden.example.com
94 | ADMIN_TOKEN=xxxxxxxxxxxxxxxxx
95 | ```
96 |
97 | # Usage
98 |
99 | ## Requirements
100 | - [Traefik up and running](../traefik).
101 | - A subdomain of your choice, this example uses `vaultwarden`.
102 | - You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
103 |
104 | ## Configuration
105 |
106 | Replace the environment variable in `.env` with your own, then run :
107 |
108 | ```bash
109 | sudo docker-compose up -d
110 | ```
111 |
112 | You should then be able to access the bitwarden web-ui admin interface with the ADMIN_TOKEN.
113 |
114 | # Update
115 |
116 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
117 |
118 | ```yaml
119 | # Watchtower Update
120 | - "com.centurylinklabs.watchtower.enable=true"
121 | ```
122 |
123 | # Security
124 |
125 | Comment admin token to disable the admin interface after you have created your users.
126 | The IP filtering label is set in the docker-compose, you can restrict access to this service by modifying the traefik [whitelist](traefik/rules/whitelist.yml).
127 |
128 | # Backup
129 |
130 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/vaultwarden/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | bitwardenrs:
5 | image: vaultwarden/server
6 | container_name: vaultwarden
7 | restart: unless-stopped
8 | volumes:
9 | - ./data:/data
10 | environment:
11 | - WEBSOCKET_ENABLED=true
12 | - WEB_VAULT_ENABLED=true
13 | - SIGNUPS_ALLOWED=false
14 | # Comment admin token to disable admin interface
15 | - ADMIN_TOKEN=${ADMIN_TOKEN}
16 | networks:
17 | - proxy
18 | labels:
19 | - "traefik.enable=true"
20 | - "traefik.http.routers.bitwarden.rule=Host(`${TRAEFIK_VAULTWARDEN}`)"
21 | - "traefik.http.routers.bitwarden.entrypoints=https"
22 | - "traefik.http.routers.bitwarden.tls=true"
23 | - "traefik.http.routers.bitwarden.tls.certresolver=mydnschallenge"
24 | # Watchtower Update
25 | - "com.centurylinklabs.watchtower.enable=true"
26 | # Ip filtering
27 | - "traefik.http.routers.bitwarden.middlewares=whitelist@file"
28 | logging:
29 | driver: "syslog"
30 | options:
31 | tag: "Bitwarden"
32 |
33 | networks:
34 | proxy:
35 | external: true
--------------------------------------------------------------------------------
/watchtower/.env:
--------------------------------------------------------------------------------
1 | GOTIFY_URL=https://gotify.example.com/
2 | GOTIFY_TOKEN=xxxxxxxxxxxxxxxxxx
--------------------------------------------------------------------------------
/watchtower/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | Watchtower is a container-based solution for automating Docker container base image updates. It will pull down your new image, gracefully shut down your existing container and restart it with the same options that were used when it was deployed initially.
8 |
9 | * [Github](https://github.com/containrrr/watchtower)
10 | * [Documentation](https://containrrr.dev/watchtower/)
11 | * [Docker Image](https://hub.docker.com/r/containrrr/watchtower)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Files structure](#files-structure)
20 | - [Information](#information)
21 | - [docker-compose](#docker-compose)
22 | - [Usage](#usage)
23 | - [Configuration](#configuration)
24 | - [Update](#update)
25 | - [Security](#security)
26 | - [Backup](#backup)
27 |
28 |
29 |
30 | # Files structure
31 |
32 | ```bash
33 | .
34 | |-- .env
35 | `-- docker-compose.yml
36 | ```
37 |
38 | - `.env` - a file containing all the environment variables used in the docker-compose.yml
39 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
40 |
41 | Please make sure that all the files and directories are present.
42 |
43 | # Information
44 |
45 | The following docker-compose is configured to check for update every monday. If you are using the borg-backup [strategy](../borg-backup), everything will be backed-up before the image is updated to prevent data corruption.
46 |
47 | Watchtower if configured to automatically upgrade your images and to then, send you a notification with [gotify](../gotify). Everything can be changed by modifying the [environnement variables](https://containrrr.dev/watchtower/arguments/).
48 |
49 | If you want watchtower to only notify you and not upgrade the images, uncomment the following environnement variable in the docker-compose : `- WATCHTOWER_MONITOR_ONLY=true`
50 |
51 | ## docker-compose
52 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
53 |
54 | * docker-compose.yml
55 | ```yaml
56 | version: "3"
57 |
58 | services:
59 | watchtower:
60 | image: containrrr/watchtower
61 | container_name: watchtower
62 | restart: unless-stopped
63 | volumes:
64 | - /var/run/docker.sock:/var/run/docker.sock
65 | environment:
66 | - WATCHTOWER_CLEANUP=true
67 | - WATCHTOWER_LABEL_ENABLE=true
68 | #- WATCHTOWER_MONITOR_ONLY=true
69 | #- WATCHTOWER_POLL_INTERVAL=30
70 | - WATCHTOWER_SCHEDULE=0 0 4 * * MON
71 | - WATCHTOWER_NOTIFICATIONS=gotify
72 | - WATCHTOWER_NOTIFICATION_GOTIFY_URL=${GOTIFY_URL}
73 | - WATCHTOWER_NOTIFICATION_GOTIFY_TOKEN=${GOTIFY_TOKEN}
74 | labels:
75 | - "com.centurylinklabs.watchtower.enable=true"
76 | ```
77 | * .env
78 | ```ini
79 | # The gotify token can be configured in the gotify WebUI
80 | GOTIFY_URL=https://gotify.example.com/
81 | GOTIFY_TOKEN=xxxxxxxxxxxxxxxxxx
82 | ```
83 |
84 | # Usage
85 |
86 | ## Configuration
87 |
88 | If you don't want to use gotify for the notification, feel free to remove the environnement variables from both the `.env` and the `docker-compose.yml` file.
89 |
90 | Replace the environment variables in `.env` with your own, then run :
91 |
92 | ```bash
93 | sudo docker-compose up -d
94 | ```
95 |
96 | Watchtower will then check for update every monday and send you a notification with gotify once an image is updated.
97 |
98 | # Update
99 |
100 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
101 |
102 | ```yaml
103 | # Watchtower Update
104 | - "com.centurylinklabs.watchtower.enable=true"
105 | ```
106 |
107 | # Security
108 |
109 | Automatically upgrading open-source images can be a huge security risk. The safest solution would be to only [monitor](https://containrrr.dev/watchtower/arguments/#without_updating_containers) the images and check the updated image before doing the upgrade.
110 |
111 | # Backup
112 |
113 | Backup are not required.
--------------------------------------------------------------------------------
/watchtower/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | watchtower:
5 | image: containrrr/watchtower
6 | container_name: watchtower
7 | restart: unless-stopped
8 | volumes:
9 | - /var/run/docker.sock:/var/run/docker.sock
10 | environment:
11 | - WATCHTOWER_CLEANUP=true
12 | - WATCHTOWER_LABEL_ENABLE=true
13 | #- WATCHTOWER_MONITOR_ONLY=true
14 | #- WATCHTOWER_POLL_INTERVAL=30
15 | - WATCHTOWER_SCHEDULE=0 0 4 * * MON
16 | - WATCHTOWER_NOTIFICATIONS=gotify
17 | - WATCHTOWER_NOTIFICATION_GOTIFY_URL=${GOTIFY_URL}
18 | - WATCHTOWER_NOTIFICATION_GOTIFY_TOKEN=${GOTIFY_TOKEN}
19 | labels:
20 | - "com.centurylinklabs.watchtower.enable=true"
--------------------------------------------------------------------------------
/webserver/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_WEBSERVER=www.example.com
--------------------------------------------------------------------------------
/webserver/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | The Apache HTTP Server Project is a collaborative software development effort aimed at creating a robust, commercial-grade, featureful, and freely-available source code implementation of an HTTP (Web) server.
8 |
9 | * [Github](https://github.com/apache/httpd)
10 | * [Documentation](https://httpd.apache.org/docs/current/)
11 | * [Docker Image](https://hub.docker.com/_/httpd)
12 |
13 | Use this service in combination with Traefik to host any custom-made website you want. Portofolio, resume, blog, ...
14 |
15 | The following example will host a simple Hello World website.
16 |
17 | # Table of Contents
18 |
19 |
20 |
21 | - [About](#about)
22 | - [Table of Contents](#table-of-contents)
23 | - [Files structure](#files-structure)
24 | - [Information](#information)
25 | - [docker-compose](#docker-compose)
26 | - [Usage](#usage)
27 | - [Requirements](#requirements)
28 | - [Configuration](#configuration)
29 | - [Update](#update)
30 | - [Backup](#backup)
31 |
32 |
33 |
34 | # Files structure
35 |
36 | ```bash
37 | .
38 | |-- data/
39 | | `-- index.html
40 | `-- docker-compose.yml
41 | ```
42 |
43 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
44 | - `data/` - a directory used to store your website content
45 |
46 | Please make sure that all the files and directories are present.
47 |
48 | # Information
49 |
50 | In this example, the website will only display a Hello World as you can see in the [index.html](data/index.html).
51 |
52 | ## docker-compose
53 | Links to the following [docker-compose.yml](docker-compose.yml).
54 |
55 | * docker-compose.yml
56 | ```yaml
57 | version: '3'
58 |
59 | services:
60 | webserver:
61 | image: 'httpd:2.4'
62 | container_name: webserver
63 | restart: unless-stopped
64 | volumes:
65 | - ./data:/usr/local/apache2/htdocs/
66 | networks:
67 | - proxy
68 | labels:
69 | - "traefik.enable=true"
70 | - "traefik.http.routers.webserver.rule=Host(`www.example.com`)"
71 | - "traefik.http.routers.webserver.entrypoints=https"
72 | - "traefik.http.routers.webserver.tls=true"
73 | - "traefik.http.routers.webserver.tls.certresolver=mydnschallenge"
74 | # Watchtower Update
75 | - "com.centurylinklabs.watchtower.enable=true"
76 |
77 | networks:
78 | proxy:
79 | external: true
80 | ```
81 | * .env
82 | ```ini
83 | TRAEFIK_WEBSERVER=www.example.com
84 | ```
85 |
86 | The docker-compose contains only one service using the apache httpd image.
87 |
88 | # Usage
89 |
90 | ## Requirements
91 | - [Traefik up and running](../traefik).
92 | - A subdomain of your choice, this example uses `www`.
93 | - You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
94 |
95 |
96 | ## Configuration
97 | Before using the docker-compose file, please update the following configurations.
98 |
99 | - **change the domain** : The current domain is example.com, change it to your domain
100 | ```bash
101 | sed -i -e "s/www.example.com/www.your-domain.com/g" docker-compose.yml
102 | ```
103 |
104 | - **change the content of the website (optional)** : Replace the content of `data` with your own website.
105 |
106 | You can now run :
107 |
108 | ```bash
109 | sudo docker-compose up -d
110 | ```
111 |
112 | # Update
113 |
114 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
115 |
116 | ```yaml
117 | # Watchtower Update
118 | - "com.centurylinklabs.watchtower.enable=true"
119 | ```
120 |
121 | # Backup
122 |
123 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/webserver/data/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hi
5 |
6 |
7 |
10 |
11 | Wireguard is a virtual private network (VPN), it provides you a secure, encrypted tunnel for online traffic and allow you to manage a remote private network.
12 | Pihole is a DNS sinkhole that protects your devices from unwanted content without installing any client-side software. Unbound is a validating, recursive, caching DNS resolver.
13 |
14 | * Wireguard
15 | * [Github](https://github.com/WireGuard)
16 | * [Documentation](https://www.wireguard.com/quickstart/)
17 | * [Docker Image](https://hub.docker.com/r/linuxserver/wireguard)
18 |
19 | * Pi-Hole
20 | * [Github](https://github.com/pi-hole/pi-hole)
21 | * [Documentation](https://docs.pi-hole.net/)
22 | * [Docker Image](https://hub.docker.com/r/pihole/pihole)
23 |
24 | * Unbound
25 | * [Github](https://github.com/NLnetLabs/unbound)
26 | * [Documentation](https://unbound.docs.nlnetlabs.nl/en/latest/)
27 | * [Docker Image](https://hub.docker.com/r/mvance/unbound)
28 |
29 | This guide combine the three services so that every device that are connected to the VPN also pass through pihole and unbound. Having a VPN will also reinforce security for your overall infrastructure as you can combine it with [traefik IP whitelist](../traefik#Configuration).
30 |
31 | Credits to [@IAmStoxe](https://github.com/IAmStoxe/wirehole).
32 |
33 | # Table of Contents
34 |
35 |
36 |
37 | - [About](#about)
38 | - [Table of Contents](#table-of-contents)
39 | - [Files structure](#files-structure)
40 | - [Information](#information)
41 | - [docker-compose](#docker-compose)
42 | - [Usage](#usage)
43 | - [Requirements](#requirements)
44 | - [Configuration](#configuration)
45 | - [Wireguard](#wireguard)
46 | - [Pihole](#pihole)
47 | - [Update](#update)
48 | - [Security](#security)
49 | - [Backup](#backup)
50 |
51 |
52 |
53 | # Files structure
54 |
55 | ```bash
56 | .
57 | |-- docker-compose.yml
58 | |-- etc-dnsmasq.d/
59 | |-- etc-pihole/
60 | |-- unbound/
61 | `-- wireguard/
62 | ```
63 |
64 | * `docker-compose.yml` - a docker-compose file, use to configure your application’s services
65 | * `etc-dnsmasq.d/` - a directory used to store dnsmasq configs
66 | * `etc-pihole/` - a directory used to store your Pi-hole configs
67 | * `wireguard/` - a directory used to store wireguard data, including client ready-to-use configuration files
68 | * `unbound/` - a directory used to store unbound data
69 |
70 | Please make sure that all the files and directories are present.
71 |
72 | # Information
73 |
74 | ## docker-compose
75 |
76 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
77 |
78 | * docker-compose.yml
79 | ```yaml
80 | version: "3"
81 |
82 | services:
83 | unbound:
84 | image: mvance/unbound:latest
85 | container_name: unbound
86 | restart: unless-stopped
87 | hostname: unbound
88 | volumes:
89 | - ./unbound:/opt/unbound/etc/unbound/
90 | networks:
91 | private_network:
92 | ipv4_address: 10.2.0.200
93 | labels:
94 | # Watchtower Update
95 | - "com.centurylinklabs.watchtower.enable=true"
96 |
97 |
98 | wireguard:
99 | depends_on: [unbound, pihole]
100 | image: linuxserver/wireguard
101 | container_name: wireguard
102 | restart: unless-stopped
103 | cap_add:
104 | - NET_ADMIN
105 | - SYS_MODULE
106 | environment:
107 | - PUID=${PUID}
108 | - PGID=${PGID}
109 | - TZ=${TZ}
110 | - SERVERPORT=51820
111 | - SERVERURL=${SERVERURL} #optional
112 | - PEERS=${PEERS} # How many peers to generate for you (clients)
113 | - PEERDNS=10.2.0.100 # Set it to point to pihole
114 | - INTERNAL_SUBNET=10.6.0.0
115 | volumes:
116 | - ./wireguard:/config
117 | - /lib/modules:/lib/modules
118 | ports:
119 | - "51820:51820/udp"
120 | dns:
121 | - 10.2.0.100 # Points to pihole
122 | - 10.2.0.200 # Points to unbound
123 | sysctls:
124 | - net.ipv4.conf.all.src_valid_mark=1
125 | networks:
126 | private_network:
127 | ipv4_address: 10.2.0.3
128 | labels:
129 | # Watchtower Update
130 | - "com.centurylinklabs.watchtower.enable=true"
131 |
132 | pihole:
133 | depends_on: [unbound]
134 | container_name: pihole
135 | image: pihole/pihole:latest
136 | restart: unless-stopped
137 | hostname: pihole
138 | dns:
139 | - 127.0.0.1
140 | - 10.2.0.200 # Points to unbound
141 | environment:
142 | TZ: "Europe/Paris"
143 | WEBPASSWORD: "" # Blank password - Can be whatever you want.
144 | ServerIP: 10.1.0.100 # Internal IP of pihole
145 | DNS1: 10.2.0.200 # Unbound IP
146 | DNS2: 10.2.0.200 # If we don't specify two, it will auto pick google.
147 | # Volumes store your data between container upgrades
148 | volumes:
149 | - "./etc-pihole/:/etc/pihole/"
150 | - "./etc-dnsmasq.d/:/etc/dnsmasq.d/"
151 | # Recommended but not required (DHCP needs NET_ADMIN)
152 | # https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
153 | cap_add:
154 | - NET_ADMIN
155 | networks:
156 | private_network:
157 | ipv4_address: 10.2.0.100
158 | labels:
159 | # Watchtower Update
160 | - "com.centurylinklabs.watchtower.enable=true"
161 |
162 | networks:
163 | private_network:
164 | ipam:
165 | driver: default
166 | config:
167 | - subnet: 10.2.0.0/24
168 | ```
169 | * .env
170 | ```ini
171 | SERVERURL=vpn.example.com
172 |
173 | # How many peers to generate for you (clients)
174 | PEERS=2
175 |
176 | # user PUID and group PGID - can be found by running id your-user
177 | PUID=1000
178 | PGID=1000
179 | ```
180 |
181 | # Usage
182 |
183 | ## Requirements
184 |
185 | * A subdomain of your choice for your VPN, this example uses `vpn`.
186 | * You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
187 | * Ports 51820 open, check your firewall.
188 |
189 | ## Configuration
190 |
191 | The linuxserver images are using the PUID and PGID, they allow the container to map the container's internal user to a user on the host machine, more information [here](https://docs.linuxserver.io/general/understanding-puid-and-pgid).
192 |
193 | To find yours, use `id user`. Replace the environment variables in `.env` with your own, then run :
194 |
195 | ```bash
196 | sudo docker-compose up -d
197 | ```
198 |
199 | ### Wireguard
200 |
201 | * Getting the client configuration file
202 |
203 | You should be able to find the required configuration for your clients in the `wireguard` directory. Each client will have an associated folder called `peerX`.
204 | Inside this folder you can find a QR code for your smartphone as well as configuration file for your linux/windows.
205 |
206 | * Adding more clients
207 |
208 | If you want more clients, just change the value in the `.env` file and relaunch the service `sudo docker-compose up -d`.
209 |
210 |
211 | ### Pihole
212 |
213 | Once connected to the VPN you should be able to access the pihole admin interface at http://10.2.0.100/admin, for more information regarding pihole you can check the well written official pihole [documentation](https://docs.pi-hole.net/).
214 |
215 | # Update
216 |
217 | The images are automatically updated with [watchtower](../watchtower) thanks to the following label :
218 |
219 | ```yaml
220 | # Watchtower Update
221 | - "com.centurylinklabs.watchtower.enable=true"
222 | ```
223 |
224 | # Security
225 |
226 | A VPN is often a good solution to always have a dedicated IP. If you want to secure your others services, you can limit their access only when you are connected to your VPN. An easy way to do that is to add the private IP address range used by docker (172.16.0.0/12), your internal IP through the VPN will be one of this range, to the traefik [whitelist](traefik/rules/whitelist.yml).
227 |
228 | Keep in mind that only the containers that have the following label attached will be prone to this IP restriction.
229 |
230 | ```yaml
231 | # Ip filtering
232 | - "traefik.http.routers.service-router-name.middlewares=whitelist@file"
233 | ```
234 |
235 | # Backup
236 |
237 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
238 |
--------------------------------------------------------------------------------
/wireguard-pihole-unbound/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 | unbound:
5 | image: mvance/unbound:latest
6 | container_name: unbound
7 | restart: unless-stopped
8 | hostname: unbound
9 | volumes:
10 | - ./unbound:/opt/unbound/etc/unbound/
11 | networks:
12 | private_network:
13 | ipv4_address: 10.2.0.200
14 | labels:
15 | # Watchtower Update
16 | - "com.centurylinklabs.watchtower.enable=true"
17 |
18 |
19 | wireguard:
20 | depends_on: [unbound, pihole]
21 | image: linuxserver/wireguard
22 | container_name: wireguard
23 | restart: unless-stopped
24 | cap_add:
25 | - NET_ADMIN
26 | - SYS_MODULE
27 | environment:
28 | - PUID=${PUID}
29 | - PGID=${PGID}
30 | - TZ=${TZ}
31 | - SERVERPORT=51820
32 | - SERVERURL=${SERVERURL} #optional
33 | - PEERS=${PEERS} # How many peers to generate for you (clients)
34 | - PEERDNS=10.2.0.100 # Set it to point to pihole
35 | - INTERNAL_SUBNET=10.6.0.0
36 | volumes:
37 | - ./wireguard:/config
38 | - /lib/modules:/lib/modules
39 | ports:
40 | - "51820:51820/udp"
41 | dns:
42 | - 10.2.0.100 # Points to pihole
43 | - 10.2.0.200 # Points to unbound
44 | sysctls:
45 | - net.ipv4.conf.all.src_valid_mark=1
46 | networks:
47 | private_network:
48 | ipv4_address: 10.2.0.3
49 | labels:
50 | # Watchtower Update
51 | - "com.centurylinklabs.watchtower.enable=true"
52 |
53 | pihole:
54 | depends_on: [unbound]
55 | container_name: pihole
56 | image: pihole/pihole:latest
57 | restart: unless-stopped
58 | hostname: pihole
59 | dns:
60 | - 127.0.0.1
61 | - 10.2.0.200 # Points to unbound
62 | environment:
63 | TZ: "Europe/Paris"
64 | WEBPASSWORD: "" # Blank password - Can be whatever you want.
65 | ServerIP: 10.1.0.100 # Internal IP of pihole
66 | DNS1: 10.2.0.200 # Unbound IP
67 | DNS2: 10.2.0.200 # If we don't specify two, it will auto pick google.
68 | # Volumes store your data between container upgrades
69 | volumes:
70 | - "./etc-pihole/:/etc/pihole/"
71 | - "./etc-dnsmasq.d/:/etc/dnsmasq.d/"
72 | # Recommended but not required (DHCP needs NET_ADMIN)
73 | # https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
74 | cap_add:
75 | - NET_ADMIN
76 | networks:
77 | private_network:
78 | ipv4_address: 10.2.0.100
79 | labels:
80 | # Watchtower Update
81 | - "com.centurylinklabs.watchtower.enable=true"
82 |
83 | networks:
84 | private_network:
85 | ipam:
86 | driver: default
87 | config:
88 | - subnet: 10.2.0.0/24
--------------------------------------------------------------------------------
/wireguard-pihole-unbound/unbound/unbound.conf:
--------------------------------------------------------------------------------
1 | server:
2 | ###########################################################################
3 | # BASIC SETTINGS
4 | ###########################################################################
5 | # Time to live maximum for RRsets and messages in the cache. If the maximum
6 | # kicks in, responses to clients still get decrementing TTLs based on the
7 | # original (larger) values. When the internal TTL expires, the cache item
8 | # has expired. Can be set lower to force the resolver to query for data
9 | # often, and not trust (very large) TTL values.
10 | cache-max-ttl: 86400
11 |
12 | # Time to live minimum for RRsets and messages in the cache. If the minimum
13 | # kicks in, the data is cached for longer than the domain owner intended,
14 | # and thus less queries are made to look up the data. Zero makes sure the
15 | # data in the cache is as the domain owner intended, higher values,
16 | # especially more than an hour or so, can lead to trouble as the data in
17 | # the cache does not match up with the actual data any more.
18 | cache-min-ttl: 60
19 |
20 | # Set the working directory for the program.
21 | directory: "/opt/unbound/etc/unbound"
22 |
23 | # RFC 6891. Number of bytes size to advertise as the EDNS reassembly buffer
24 | # size. This is the value put into datagrams over UDP towards peers.
25 | # 4096 is RFC recommended. 1472 has a reasonable chance to fit within a
26 | # single Ethernet frame, thus lessing the chance of fragmentation
27 | # reassembly problems (usually seen as timeouts). Setting to 512 bypasses
28 | # even the most stringent path MTU problems, but is not recommended since
29 | # the amount of TCP fallback generated is excessive.
30 | edns-buffer-size: 1472
31 |
32 | # Listen to for queries from clients and answer from this network interface
33 | # and port.
34 | interface: 0.0.0.0@53
35 |
36 | # Rotates RRSet order in response (the pseudo-random number is taken from
37 | # the query ID, for speed and thread safety).
38 | rrset-roundrobin: yes
39 |
40 | # Drop user privileges after binding the port.
41 | username: "_unbound"
42 |
43 | ###########################################################################
44 | # LOGGING
45 | ###########################################################################
46 |
47 | # Do not print log lines to inform about local zone actions
48 | log-local-actions: no
49 |
50 | # Do not print one line per query to the log
51 | log-queries: no
52 |
53 | # Do not print one line per reply to the log
54 | log-replies: no
55 |
56 | # Do not print log lines that say why queries return SERVFAIL to clients
57 | log-servfail: no
58 |
59 | # Further limit logging
60 | logfile: /dev/null
61 |
62 | # Only log errors
63 | verbosity: 1
64 |
65 | ###########################################################################
66 | # PRIVACY SETTINGS
67 | ###########################################################################
68 |
69 | # RFC 8198. Use the DNSSEC NSEC chain to synthesize NXDO-MAIN and other
70 | # denials, using information from previous NXDO-MAINs answers. In other
71 | # words, use cached NSEC records to generate negative answers within a
72 | # range and positive answers from wildcards. This increases performance,
73 | # decreases latency and resource utilization on both authoritative and
74 | # recursive servers, and increases privacy. Also, it may help increase
75 | # resilience to certain DoS attacks in some circumstances.
76 | aggressive-nsec: yes
77 |
78 | # Extra delay for timeouted UDP ports before they are closed, in msec.
79 | # This prevents very delayed answer packets from the upstream (recursive)
80 | # servers from bouncing against closed ports and setting off all sort of
81 | # close-port counters, with eg. 1500 msec. When timeouts happen you need
82 | # extra sockets, it checks the ID and remote IP of packets, and unwanted
83 | # packets are added to the unwanted packet counter.
84 | delay-close: 10000
85 |
86 | # Prevent the unbound server from forking into the background as a daemon
87 | do-daemonize: no
88 |
89 | # Add localhost to the do-not-query-address list.
90 | do-not-query-localhost: no
91 |
92 | # Number of bytes size of the aggressive negative cache.
93 | neg-cache-size: 4M
94 |
95 | # Send minimum amount of information to upstream servers to enhance
96 | # privacy (best privacy).
97 | qname-minimisation: yes
98 |
99 | ###########################################################################
100 | # SECURITY SETTINGS
101 | ###########################################################################
102 | # Only give access to recursion clients from LAN IPs
103 | access-control: 127.0.0.1/32 allow
104 | access-control: 192.168.0.0/16 allow
105 | access-control: 172.16.0.0/12 allow
106 | access-control: 10.0.0.0/8 allow
107 | # access-control: fc00::/7 allow
108 | # access-control: ::1/128 allow
109 |
110 | # File with trust anchor for one zone, which is tracked with RFC5011
111 | # probes.
112 | auto-trust-anchor-file: "var/root.key"
113 |
114 | # Enable chroot (i.e, change apparent root directory for the current
115 | # running process and its children)
116 | chroot: "/opt/unbound/etc/unbound"
117 |
118 | # Deny queries of type ANY with an empty response.
119 | #deny-any: yes
120 |
121 | # Harden against algorithm downgrade when multiple algorithms are
122 | # advertised in the DS record.
123 | harden-algo-downgrade: yes
124 |
125 | # RFC 8020. returns nxdomain to queries for a name below another name that
126 | # is already known to be nxdomain.
127 | harden-below-nxdomain: yes
128 |
129 | # Require DNSSEC data for trust-anchored zones, if such data is absent, the
130 | # zone becomes bogus. If turned off you run the risk of a downgrade attack
131 | # that disables security for a zone.
132 | harden-dnssec-stripped: yes
133 |
134 | # Only trust glue if it is within the servers authority.
135 | harden-glue: yes
136 |
137 | # Ignore very large queries.
138 | harden-large-queries: yes
139 |
140 | # Perform additional queries for infrastructure data to harden the referral
141 | # path. Validates the replies if trust anchors are configured and the zones
142 | # are signed. This enforces DNSSEC validation on nameserver NS sets and the
143 | # nameserver addresses that are encountered on the referral path to the
144 | # answer. Experimental option.
145 | harden-referral-path: no
146 |
147 | # Ignore very small EDNS buffer sizes from queries.
148 | harden-short-bufsize: yes
149 |
150 | # Refuse id.server and hostname.bind queries
151 | hide-identity: yes
152 |
153 | # Refuse version.server and version.bind queries
154 | hide-version: yes
155 |
156 | # Report this identity rather than the hostname of the server.
157 | identity: "DNS"
158 |
159 | # These private network addresses are not allowed to be returned for public
160 | # internet names. Any occurrence of such addresses are removed from DNS
161 | # answers. Additionally, the DNSSEC validator may mark the answers bogus.
162 | # This protects against DNS Rebinding
163 | private-address: 10.0.0.0/8
164 | private-address: 172.16.0.0/12
165 | private-address: 192.168.0.0/16
166 | private-address: 169.254.0.0/16
167 | private-address: fd00::/8
168 | private-address: fe80::/10
169 | private-address: ::ffff:0:0/96
170 |
171 | # Enable ratelimiting of queries (per second) sent to nameserver for
172 | # performing recursion. More queries are turned away with an error
173 | # (servfail). This stops recursive floods (e.g., random query names), but
174 | # not spoofed reflection floods. Cached responses are not rate limited by
175 | # this setting. Experimental option.
176 | #ratelimit: 1000
177 |
178 | # Use this certificate bundle for authenticating connections made to
179 | # outside peers (e.g., auth-zone urls, DNS over TLS connections).
180 | tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
181 |
182 | # Set the total number of unwanted replies to eep track of in every thread.
183 | # When it reaches the threshold, a defensive action of clearing the rrset
184 | # and message caches is taken, hopefully flushing away any poison.
185 | # Unbound suggests a value of 10 million.
186 | unwanted-reply-threshold: 10000000
187 |
188 | # Use 0x20-encoded random bits in the query to foil spoof attempts. This
189 | # perturbs the lowercase and uppercase of query names sent to authority
190 | # servers and checks if the reply still has the correct casing.
191 | # This feature is an experimental implementation of draft dns-0x20.
192 | # Experimental option.
193 | #use-caps-for-id: yes
194 |
195 | # Help protect users that rely on this validator for authentication from
196 | # potentially bad data in the additional section. Instruct the validator to
197 | # remove data from the additional section of secure messages that are not
198 | # signed properly. Messages that are insecure, bogus, indeterminate or
199 | # unchecked are not affected.
200 | val-clean-additional: yes
201 |
202 | ###########################################################################
203 | # PERFORMANCE SETTINGS
204 | ###########################################################################
205 | # https://nlnetlabs.nl/documentation/unbound/howto-optimise/
206 | # https://nlnetlabs.nl/news/2019/Feb/05/unbound-1.9.0-released/
207 |
208 | # Number of slabs in the infrastructure cache. Slabs reduce lock contention
209 | # by threads. Must be set to a power of 2.
210 | # infra-cache-slabs: 4
211 |
212 | # Number of incoming TCP buffers to allocate per thread. Default
213 | # is 10. If set to 0, or if do-tcp is "no", no TCP queries from
214 | # clients are accepted. For larger installations increasing this
215 | # value is a good idea.
216 | # incoming-num-tcp: 10
217 |
218 | # Number of slabs in the key cache. Slabs reduce lock contention by
219 | # threads. Must be set to a power of 2. Setting (close) to the number
220 | # of cpus is a reasonable guess.
221 | # key-cache-slabs: 4
222 |
223 | # Number of bytes size of the message cache.
224 | # Unbound recommendation is to Use roughly twice as much rrset cache memory
225 | # as you use msg cache memory.
226 | msg-cache-size: 260991658
227 |
228 | # Number of slabs in the message cache. Slabs reduce lock contention by
229 | # threads. Must be set to a power of 2. Setting (close) to the number of
230 | # cpus is a reasonable guess.
231 | #msg-cache-slabs: 4
232 |
233 | # The number of queries that every thread will service simultaneously. If
234 | # more queries arrive that need servicing, and no queries can be jostled
235 | # out (see jostle-timeout), then the queries are dropped.
236 | # This is best set at half the number of the outgoing-range.
237 | # This Unbound instance was compiled with libevent so it can efficiently
238 | # use more than 1024 file descriptors.
239 | num-queries-per-thread: 4096
240 |
241 | # The number of threads to create to serve clients.
242 | # This is set dynamically at run time to effectively use available CPUs
243 | # resources
244 | #num-threads: 3
245 |
246 | # Number of ports to open. This number of file descriptors can be opened
247 | # per thread.
248 | # This Unbound instance was compiled with libevent so it can efficiently
249 | # use more than 1024 file descriptors.
250 | outgoing-range: 8192
251 |
252 | # Number of bytes size of the RRset cache.
253 | # Use roughly twice as much rrset cache memory as msg cache memory
254 | rrset-cache-size: 260991658
255 |
256 | # Number of slabs in the RRset cache. Slabs reduce lock contention by
257 | # threads. Must be set to a power of 2.
258 | #rrset-cache-slabs: 4
259 |
260 | # Do no insert authority/additional sections into response messages when
261 | # those sections are not required. This reduces response size
262 | # significantly, and may avoid TCP fallback for some responses. This may
263 | # cause a slight speedup.
264 | minimal-responses: yes
265 |
266 | # # Fetch the DNSKEYs earlier in the validation process, when a DS record
267 | # is encountered. This lowers the latency of requests at the expense of
268 | # little more CPU usage.
269 | prefetch: yes
270 |
271 | # Fetch the DNSKEYs earlier in the validation process, when a DS record is
272 | # encountered. This lowers the latency of requests at the expense of little
273 | # more CPU usage.
274 | prefetch-key: yes
275 |
276 | # Have unbound attempt to serve old responses from cache with a TTL of 0 in
277 | # the response without waiting for the actual resolution to finish. The
278 | # actual resolution answer ends up in the cache later on.
279 | serve-expired: yes
280 |
281 | # Open dedicated listening sockets for incoming queries for each thread and
282 | # try to set the SO_REUSEPORT socket option on each socket. May distribute
283 | # incoming queries to threads more evenly.
284 | so-reuseport: yes
285 |
286 | # Ensure kernel buffer is large enough to not lose messages in traffic spikes
287 | so-rcvbuf: 1m
288 |
289 | ###########################################################################
290 | # LOCAL ZONE
291 | ###########################################################################
292 |
293 | # # Include file for local-data and local-data-ptr
294 | # include: /opt/unbound/etc/unbound/a-records.conf
295 | # include: /opt/unbound/etc/unbound/srv-records.conf
296 |
297 | # ###########################################################################
298 | # # FORWARD ZONE
299 | # ###########################################################################
300 |
301 | # include: /opt/unbound/etc/unbound/forward-records.conf
302 |
303 | # OPTIONAL:
304 | # Forward Secure DNS to upstread provider Cloudflare DNS
305 |
306 | # forward-zone:
307 | # name: "."
308 | # forward-addr: 1.1.1.1@853#cloudflare-dns.com
309 | # forward-addr: 1.0.0.1@853#cloudflare-dns.com
310 | # forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com
311 | # forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com
312 | # forward-tls-upstream: yes
313 |
314 | remote-control:
315 | control-enable: no
--------------------------------------------------------------------------------
/wordpress/.env:
--------------------------------------------------------------------------------
1 | TRAEFIK_WORDPRESS=wordpress.example.com
2 | DB_ROOT_PASSWD=xxxxxxxxxxxxxxx
3 | DB_PASSWD=xxxxxxxxxxxxxxx
--------------------------------------------------------------------------------
/wordpress/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 |
4 |
5 |
6 |
7 | WordPress is a free and open source blogging tool and a content management system (CMS) based on PHP and MySQL, which runs on a web hosting service.
8 |
9 | * [Github](https://github.com/WordPress/WordPress)
10 | * [Documentation](https://codex.wordpress.org/)
11 | * [Docker Image](https://hub.docker.com/_/wordpress)
12 |
13 | # Table of Contents
14 |
15 |
16 |
17 | - [About](#about)
18 | - [Table of Contents](#table-of-contents)
19 | - [Files structure](#files-structure)
20 | - [Information](#information)
21 | - [docker-compose](#docker-compose)
22 | - [Usage](#usage)
23 | - [Requirements](#requirements)
24 | - [Configuration](#configuration)
25 | - [Update](#update)
26 | - [Backup](#backup)
27 |
28 |
29 |
30 | # Files structure
31 |
32 | ```bash
33 | .
34 | |-- .env
35 | |-- docker-compose.yml
36 | |-- wordpress-mysql/
37 | `-- data/
38 | ```
39 |
40 | - `.env` - a file containing all the environment variables used in the docker-compose.yml
41 | - `docker-compose.yml` - a docker-compose file, use to configure your application’s services
42 | - `wordpress-mysql/` - a directory used to store the mysql data
43 | - `data/` - a directory used to store wordpress's data
44 |
45 | Please make sure that all the files and directories are present.
46 |
47 | # Information
48 |
49 | ## docker-compose
50 | Links to the following [docker-compose.yml](docker-compose.yml) and the corresponding [.env](.env).
51 |
52 | * docker-compose.yml
53 | ```yaml
54 | version: '3'
55 |
56 | services:
57 | db:
58 | image: mariadb
59 | container_name: wordpress-mysql
60 | restart: unless-stopped
61 | command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
62 | volumes:
63 | - ./wordpress-mysql/db:/var/lib/mysql
64 | environment:
65 | - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWD} # Requested, set the root's password of MySQL service.
66 | - MYSQL_PASSWORD=${DB_PASSWD}
67 | - MYSQL_DATABASE=wordpress
68 | - MYSQL_USER=wordpress
69 | - MYSQL_LOG_CONSOLE=true
70 | networks:
71 | - wordpress-net
72 | labels:
73 | # Watchtower Update
74 | - "com.centurylinklabs.watchtower.enable=true"
75 |
76 | wordpress:
77 | image: wordpress:latest
78 | container_name: wordpress
79 | restart: unless-stopped
80 | volumes:
81 | - ./data:/var/www/html
82 | networks:
83 | - proxy
84 | - wordpress-net
85 | depends_on:
86 | - db
87 | labels:
88 | - "traefik.enable=true"
89 | - "traefik.http.routers.wordpress.rule=Host(`${TRAEFIK_WORDPRESS}`)"
90 | - "traefik.http.routers.wordpress.entrypoints=https"
91 | - "traefik.http.routers.wordpress.tls=true"
92 | - "traefik.http.routers.wordpress.tls.certresolver=mydnschallenge"
93 | # Watchtower Update
94 | - "com.centurylinklabs.watchtower.enable=true"
95 |
96 | networks:
97 | wordpress-net:
98 | proxy:
99 | external: true
100 | ```
101 | * .env
102 | ```ini
103 | TRAEFIK_WORDPRESS=wordpress.example.com
104 | DB_ROOT_PASSWD=xxxxxxxxxxxxxxx
105 | DB_PASSWD=xxxxxxxxxxxxxxx
106 | ```
107 |
108 |
109 |
110 | # Usage
111 |
112 | ## Requirements
113 | - [Traefik up and running](../traefik).
114 | - A subdomain of your choice, this example uses `wordpress`.
115 | - You should be able to create a subdomain with your DNS provider, use a `A record` with the same IP address as your root domain.
116 |
117 | ## Configuration
118 |
119 | Replace the environment variables in `.env` with your own.
120 |
121 | Then replace the following variables in `data/wp-config.php`.
122 |
123 | * DB_PASSWORD is equivalent to DB_PASSWD in `.env`
124 | ```
125 | define( 'DB_PASSWORD', 'xxxxxxxxxxxxxxx' );
126 | ```
127 |
128 | * Change the following unique keys and salt, you can use this [wordpress salt generator](https://api.wordpress.org/secret-key/1.1/salt/) and copy past it
129 | ```
130 | define( 'AUTH_KEY', 'change-me' );
131 | define( 'SECURE_AUTH_KEY', 'change-me' );
132 | define( 'LOGGED_IN_KEY', 'change-me' );
133 | define( 'NONCE_KEY', 'change-me' );
134 | define( 'AUTH_SALT', 'change-me' );
135 | define( 'SECURE_AUTH_SALT', 'change-me' );
136 | define( 'LOGGED_IN_SALT', 'change-me' );
137 | define( 'NONCE_SALT', 'change-me' );
138 | ```
139 |
140 | You can now run :
141 |
142 | ```bash
143 | sudo docker-compose up -d
144 | ```
145 |
146 | You should now be able to access the wordpress initialisation page.
147 |
148 | # Update
149 |
150 | The image is automatically updated with [watchtower](../watchtower) thanks to the following label :
151 |
152 | ```yaml
153 | # Watchtower Update
154 | - "com.centurylinklabs.watchtower.enable=true"
155 | ```
156 | ACCESS_DENIED\
157 | # Backup
158 |
159 | Docker volumes are globally backed up using [borg-backup](../borg-backup).
--------------------------------------------------------------------------------
/wordpress/data/wp-config.php:
--------------------------------------------------------------------------------
1 |