I used Techno Tim's guide Put Wildcard Certificates and SSL on EVERYTHING while setting up my home lab. I highly recommend watching the video and reading his guide. I will be using the same tools and techniques as Tim but will be primarily focusing on documenting my personal setup.
- Access to your Router:
- Used for configuring local DNS and static IP addresses.
- I use an RT-AXE7800 router.
- A docker host:
- Refer to Docker's documentation for installation instructions.
- I use Ubuntu 22.04.3 LTS as my host operating system.
- See PC-Part Picker for my server build.
- A domain name that you own:
- This will cost approximately ~$10 USD per year depending on the domain name.
- I use CloudFlare.
- All the necessary env files. See Environment Variables & .env files for more information.
The following directory structure is used for each service:
service-name/
├── data
│ ├── folder-1
│ ├── folder-2
│ └── ...
└── docker-compose.yaml
For multiple services that share the same docker-compose file, the following structure is used instead:
./application-name/
├── service-1
│ └── data
├── service-2
│ └── data
└── docker-compose.yaml
The data folder is used for any bind mounts. (You can also use named volumes instead).
The first step is to configure a static IP address for the docker host so that we don't have to worry about having to update DNS records if the server IP gets re-assigned.
You can run the following command to get the IP address of your docker host:
#!/usr/bin/env bash
hostname -I
Regarding the router configuration, you can follow the instructions provided by ASUS for assigning a static IP address for their routers. The instructions should be similar for other routers.
#!/usr/bin/env bash
docker network create proxy
All services will belong to this network and traefik will route traffic to the appropriate service. As such, typically, we will not be publishing ports for our services except for traefik and pi-hole.
For Ubuntu, the container will fail to start if the systemd-resolved.service
is running.
As such, as per the pi-hole documentation, you'll need to either disable the stub resolver:
#!/usr/bin/env bash
# Disable Stub Resolver
sudo sed -r -i.orig 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf
# Update nameserver setting
sudo sh -c 'rm /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'
# Restart the Service
sudo systemctl restart systemd-resolved
Or disable the systemd-resolved.service
entirely i.e.
#!/usr/bin/env bash
sudo systemctl disable systemd-resolved.service
sudo systemctl stop systemd-resolved.service
Start the pi-hole service as follows:
#!/usr/bin/env bash
docker compose \
--env-file "./docker-volumes/env-files/common.env" \
--env-file "./docker-volumes/env-files/pi-hole.env" \
--file "./docker-volumes/pi-hole/docker-compose.yaml" up --detach
The web UI will be accessible via the following URL: http://${DOCKER_HOST_IP}/admin
Note: After traefik is up, you can access the web UI via the following URL: https://pi-hole.local.$LOCAL_DOMAIN/admin
You'll need to update your router's DNS settings to use the Pi-Hole service after it is up and running.
You can follow the instructions provided by ASUS for configuring a custom DNS server for their routers. The instructions should be similar for other routers.
Start the traefik service as follows:
#!/usr/bin/env bash
docker compose \
--env-file "./docker-volumes/env-files/common.env" \
--env-file "./docker-volumes/env-files/traefik.env" \
--file "./docker-volumes/traefik/docker-compose.yaml" up --detach
Start the portainer service as follows:
#!/usr/bin/env bash
docker compose \
--env-file "./docker-volumes/env-files/common.env" \
--file "./docker-volumes/portainer/docker-compose.yaml" up --detach
For any new service, ensure that the network we created earlier is used and that the following labels are defined:
version: "3.9"
services:
service-name:
image: "image-name:latest"
container_name: "container-name"
restart: "unless-stopped"
networks:
- "proxy"
labels:
- "traefik.enable=true"
- "traefik.http.routers.${SERVICE_NAME}.entrypoints=http"
- "traefik.http.routers.${SERVICE_NAME}.rule=Host(`${SERVICE_NAME}.local.$LOCAL_DOMAIN_NAME`)"
- "traefik.http.middlewares.${SERVICE_NAME}-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.${SERVICE_NAME}.middlewares=${SERVICE_NAME}-https-redirect"
- "traefik.http.routers.${SERVICE_NAME}-secure.entrypoints=https"
- "traefik.http.routers.${SERVICE_NAME}-secure.rule=Host(`${SERVICE_NAME}.local.$LOCAL_DOMAIN_NAME`)"
- "traefik.http.routers.${SERVICE_NAME}-secure.tls=true"
- "traefik.http.routers.${SERVICE_NAME}-secure.service=${SERVICE_NAME}"
- "traefik.http.services.${SERVICE_NAME}.loadbalancer.server.port=${SERVICE_PORT}"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
Note: Include the following label if you don't want Watchtower to automatically update the container:
version: "3.9"
services:
someimage:
container_name: someimage
labels:
- "com.centurylinklabs.watchtower.enable=false"
Calibre-Web is a web app that offers a clean and intuitive interface for browsing, reading, and downloading eBooks using a valid Calibre database.
A modern server dashboard, running on the latest tech, designed with glassmorphism in mind. It is intended to be used for smaller VPS and private servers.
A simple, yet powerful dashboard for your server.
The leading open source automation server
High Performance, Kubernetes Native Object Storage
Grafana Loki is a horizontally-scalable, highly-available, multi-tenant log aggregation system inspired by Prometheus.
- Loki - Dockerhub
- Loki - Installation Instructions
- Promtail - Dockerhub
- Promtail - Installation Instructions
Prometheus is an open-source systems monitoring and alerting toolkit originally built at SoundCloud.
- Prometheus - Dockerhub
- Prometheus - Installation Instructions
- Node Exporter - Dockerhub
- Node Exporter - Installation Instructions
As per docker's documentation, you'll need to enable the metrics endpoint in the daemon.json for Prometheus to work:
{
"metrics-addr": "127.0.0.1:9323"
}
Grafana is a multi-platform open source analytics and interactive visualization web application
You may need to fix the permissions if you are using bind mounts:
#!/usr/bin/env bash
sudo chown -R 472:472 $BASE_VOLUME_DIRECTORY/grafana/data/
sudo chown -R 65534:65534 $BASE_VOLUME_DIRECTORY/prometheus/data/
Nexus by Sonatype is a repository manager that organizes, stores and distributes artifacts needed for development.
Network-wide Ad Blocking
Portainer is your container management software to deploy, troubleshoot, and secure applications across cloud, datacenter, and Industrial IoT use cases.
PostgreSQL is a powerful, open source object-relational database system
the most popular and feature rich Open Source administration and development platform for PostgreSQL
Note: With bind mounts, you may need to change the GUI and UID to 5050
.
See Permission denied: '/var/lib/pgadmin/sessions' in Docker for more information.
#!/usr/bin/env bash
sudo chown -R 5050:5050 "$BASE_VOLUME_DIRECTORY/admin/data"
the code quality tool for better code
Note: Ensure that the following key is set in the /etc/sysctl.conf
:
vm.max_map_count = 262144
Then reboot or run the following command:
#!/usr/bin/env bash
sysctl -w vm.max_map_count=262144
systemctl restart docker
See What is the parameter "max_map_count" and does it affect the server performance? and Elasticsearch: Max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] for more information.
Traefik is the leading open-source reverse proxy and load balancer for HTTP and TCP-based applications that is easy, dynamic and full-featured.
A process for automating Docker container base image updates.