Ready-to-use compose.yaml files for your homelab
A collection of compose.yaml files for programs that many people run in a homelab. Copy a file to its own folder (for example ~/adguard/compose.yaml), adjust the marked sections and start with docker compose up -d. New to Docker? Read our Docker guides first.
Before you start
- Fixed versions. Many examples use
latestorstablefor convenience. For serious use, set a fixed version in the tag so an update doesn’t suddenly change something, and read the release notes before updating. - Check the current instructions. Programs change. When in doubt, check the project documentation; sources are listed at the bottom.
- Don’t share passwords. Put secrets in a
.envfile rather than in the compose file itself. - Ports can conflict. If a port is already in use, choose a different number to the left of the colon (for example
8082:80). - Backups. Save the folder with your data: see the 3-2-1 rule.
Home Assistant
Home Assistant in a container, for those not running Home Assistant OS. USB devices (like a Zigbee stick) work with privileged; also see the Zigbee guide.
services:
homeassistant:
image: ghcr.io/home-assistant/home-assistant:stable
container_name: homeassistant
restart: unless-stopped
privileged: true
network_mode: host
volumes:
- ./config:/config
- /etc/localtime:/etc/localtime:ro
Mosquitto (MQTT)
An MQTT broker for sensors and Home Assistant. First create mosquitto/config/mosquitto.conf:
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 1883
allow_anonymous false
password_file /mosquitto/config/passwd
services:
mosquitto:
image: eclipse-mosquitto:2
container_name: mosquitto
restart: unless-stopped
ports:
- "1883:1883"
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
Create a user (replace user), then restart the container:
docker run --rm -it -v "$(pwd)/mosquitto/config:/mosquitto/config" eclipse-mosquitto:2 mosquitto_passwd -c /mosquitto/config/passwd user
Node-RED
services:
nodered:
image: nodered/node-red:latest
container_name: nodered
restart: unless-stopped
ports:
- "1880:1880"
environment:
- TZ=Europe/Amsterdam
volumes:
- ./nodered:/data
Does Node-RED give a permissions error when writing to ./nodered? Make the folder owned by user 1000: sudo chown -R 1000:1000 nodered.
Uptime Kuma
Monitors whether your websites and services are reachable and sends a notification. Check the project page for the current version tag.
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- ./data:/app/data
Vaultwarden (password manager)
A lightweight, self-hosted server that works with the Bitwarden apps. Use it only behind https (see reverse proxy with https): the web vault doesn’t work well without it. After creating your account, disable new account creation.
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
- DOMAIN=https://wachtwoorden.jouwdomein.nl
- SIGNUPS_ALLOWED=true # set to false after your account exists
ports:
- "8081:80"
volumes:
- ./data:/data
Portainer
A web interface to manage Docker. Note: access to the Docker socket is equivalent to administrator rights on the server. Don’t expose the interface to the internet.
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
ports:
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/data
Pi-hole
Block ads for your entire network (see Pi-hole or AdGuard Home). In recent versions you set the password with FTLCONF_webserver_api_password. If port 53 is already in use (on some Ubuntu systems by systemd-resolved), you need to adjust that first.
services:
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "8082:80/tcp"
environment:
TZ: Europe/Amsterdam
FTLCONF_webserver_api_password: "choose-a-password"
volumes:
- ./etc-pihole:/etc/pihole
cap_add:
- NET_ADMIN
AdGuard Home
The alternative to Pi-hole. The first time you open http://IP-address:3000 for the installation wizard.
services:
adguardhome:
image: adguard/adguardhome:latest
container_name: adguardhome
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "3000:3000/tcp"
volumes:
- ./work:/opt/adguardhome/work
- ./conf:/opt/adguardhome/conf
Syncthing
Keeps folders synchronized between devices, without cloud. Note: synchronizing is not a backup.
services:
syncthing:
image: syncthing/syncthing:latest
container_name: syncthing
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
ports:
- "8384:8384"
- "22000:22000/tcp"
- "22000:22000/udp"
- "21027:21027/udp"
volumes:
- ./data:/var/syncthing
Homepage (start page with your services)
A start page for your homelab. Recent versions need to know under which address you’re opening it: fill that in at HOMEPAGE_ALLOWED_HOSTS.
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
restart: unless-stopped
ports:
- "3002:3000"
environment:
- HOMEPAGE_ALLOWED_HOSTS=192.168.1.20:3002
volumes:
- ./config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro
ESPHome
The ESPHome builder in a container. See the ESPHome guide.
services:
esphome:
image: ghcr.io/esphome/esphome
container_name: esphome
restart: unless-stopped
network_mode: host
volumes:
- ./config:/config
- /etc/localtime:/etc/localtime:ro
Not listed here?
For Immich, Jellyfin and Nextcloud, and for Nginx Proxy Manager and Caddy, you’ll find examples in this guide and in that one about reverse proxies. Use docker compose config to check a file before starting it.
Sources and attribution
This article is written in our own words. The settings come from the project documentation; look there for the most current version: