Docker Compose media server stack configuration. Credentials and settings are stored in .env (use default.env as template).
# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl mc net-tools smartmontools git
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq &&\
chmod +x /usr/local/bin/yqcp default.env .env- Replace
CHANGE_MEvalues in.env - Configure Docker daemon (see below)
- Mount backup destination
sudo ./scripts/deploy-cron-scripts.shdocker compose up -d
Configure log rotation and Cadvisor compatibility in /etc/docker/daemon.json:
{
"log-driver": "json-file",
"features": {
"cdi": true,
"containerd-snapshotter": false
},
"log-opts": {
"max-size": "300m",
"max-file": "1"
}
}Then restart Docker: sudo systemctl restart docker
Backups go to /media/router (SMB share). Add to /etc/fstab:
//SMB_IP_ADDRESS/PATH_TO_THE_SHARE /media/router cifs username=SMBUSER,password=SMBPASSWORD 0 0Then: sudo mkdir -p /media/router && sudo mount -a
Deploy with: sudo ./scripts/deploy-cron-scripts.sh
Or manually:
sudo cp scripts/dailyBackupCronjob /etc/cron.daily/
sudo cp scripts/hourlyBackupCronjob /etc/cron.hourly/
sudo cp scripts/upgradeComposeStack /etc/cron.weekly/
sudo chmod +x /etc/cron.daily/dailyBackupCronjob /etc/cron.hourly/hourlyBackupCronjob /etc/cron.weekly/upgradeComposeStack- dailyBackupCronjob - Full
/media/configbackup, 28-day retention - hourlyBackupCronjob - qBittorrent, Tautulli, Plex DBs, 24-hour retention
- upgradeComposeStack - upgrade Docker Compose stack and sends status report
Logs: /opt/backup.log
Generates default.env from .env - replaces sensitive values with CHANGE_ME.
Mark sensitive lines with #sensitive on the preceding line:
QB_PORT=8079 # Kept as-is
#sensitive
QB_PW="mypassword" # Becomes QB_PW=CHANGE_MERun: ./scripts/cleanup-env-file.sh
Upgrades services to latest stable versions automatically.
Prerequisites: yq, jq, curl
Features:
- Creates timestamped backup of
docker-compose.yaml - Queries Docker Hub, GHCR, GCR, Quay.io
- Filters out pre-release/platform-specific tags
- Skips
latesttags and prevents downgrades - Pulls new images and recreates containers
- Sends status report to Discord channel
Recovery:
cp docker-compose.yaml.bak.TIMESTAMP docker-compose.yaml
docker compose pull && docker compose up -dThe upgradeComposeStack script will automatically send a notification to your configured Discord webhook about the result of each upgrade (success or failure, with details on any failed containers). Set the DISCORD_WEBHOOK_URL variable in your .env file to enable this feature.
Some services require manual creation or editing of configuration files in addition to .env variables. Below are the main components and the files you may need to create or edit:
| Service | Config Path | Description/Action Required |
|---|---|---|
| Alertmanager | alertmanager/config.yml | Define routing, receivers, and rules |
| Grafana | grafana/config.monitoring | username, password for GUI access |
| PlexTraktSync | plextraktsync/config.yml, plextraktsync/servers.yml | Plex/Trakt tokens, server URLs |
For each service above, copy a sample config from the official documentation or your previous setup, and adjust as needed. Some services will auto-generate these files on first run, but you may want to pre-populate them for easier migration or backup.