Home server Docker Compose stack
Find a file
padriano a0272c2c10 add Home Assistant 2024.5.4 → 2026.5.0 upgrade plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 14:24:34 +01:00
caddy add Caddy HTTPS reverse proxy with Let's Encrypt via DuckDNS DNS-01 2026-05-11 22:30:47 +01:00
plans add Home Assistant 2024.5.4 → 2026.5.0 upgrade plan 2026-06-04 14:24:34 +01:00
samba fix samba write permissions and document UID requirement 2026-05-09 22:34:52 +01:00
timemachine Initial commit 2026-05-09 15:45:56 +01:00
.env.example add samba SMB share container on macvlan network 2026-05-09 21:45:01 +01:00
.gitignore Initial commit 2026-05-09 15:45:56 +01:00
docker-compose.yml add Caddy HTTPS reverse proxy with Let's Encrypt via DuckDNS DNS-01 2026-05-11 22:30:47 +01:00
README.md add Caddy HTTPS reverse proxy with Let's Encrypt via DuckDNS DNS-01 2026-05-11 22:30:47 +01:00

Docker Compose — Home Server

Services

Container Image Purpose
duckdns lscr.io/linuxserver/duckdns Dynamic DNS — keeps *.duckdns.org pointed at the home IP
caddy caddy (custom build) HTTPS reverse proxy with automatic Let's Encrypt certificates via DuckDNS DNS-01
homeassistant homeassistant/home-assistant Home automation, reachable at https://ha-padriano.duckdns.org
timemachine mbentley/timemachine:smb Time Machine backup server over SMB
samba dperson/samba General SMB file share for Mac and Linux clients
forgejo codeberg.org/forgejo/forgejo Self-hosted Git server at https://git-padriano.duckdns.org, SSH at :2222

Initial Setup

  1. Copy and fill in the environment file:

    cp .env.example .env
    nano .env
    
  2. Register the required DuckDNS subdomains at duckdns.org: ha-padriano, padrianoha, padriano, git-padriano.

  3. Create the required host directories if they don't exist:

    mkdir -p /home/padriano/projects/forgejo
    mkdir -p /home/padriano/share
    

    The Samba container runs as UID/GID 1001 internally, so the share directory must be owned by that user:

    sudo chown 1001:1001 /home/padriano/share
    
  4. Add the reverse proxy trusted header config to Home Assistant:

    sudo tee -a /home/padriano/projects/ha/config/configuration.yaml > /dev/null << 'EOF'
    
    http:
      use_x_forwarded_for: true
      trusted_proxies:
        - 172.16.0.0/12
    EOF
    
  5. Bring the full stack up (first run builds the custom Caddy image):

    cd /home/padriano/projects/composer
    docker compose up -d --build
    

Common Docker Compose Commands

Stack management

# Start all services (detached)
docker compose up -d

# Stop all services (containers remain)
docker compose stop

# Stop and remove all containers (data volumes are preserved)
docker compose down

# Restart all services
docker compose restart

# Restart a single service
docker compose restart homeassistant

Viewing status and logs

# Show running containers and their status
docker compose ps

# Follow logs for all services
docker compose logs -f

# Follow logs for a single service
docker compose logs -f forgejo

# Show last 50 lines for a service
docker compose logs --tail=50 timemachine

Updating images

# Pull latest images for all services
docker compose pull

# Pull for a single service
docker compose pull forgejo

# Recreate containers that have a newer image
docker compose up -d --pull always

# Recreate a single service after pulling
docker compose up -d --force-recreate forgejo

Inspecting containers

# Open a shell inside a running container
docker exec -it homeassistant bash
docker exec -it forgejo sh        # alpine-based, use sh not bash

# Show resource usage (CPU, RAM, network)
docker stats

# Inspect container configuration
docker inspect forgejo

Service Notes

duckdns

  • Config stored at /home/padriano/projects/duckdns/config
  • Domains managed: ha-padriano, padrianoha, padriano, git-padriano (all .duckdns.org)
  • Subdomains must be registered manually at duckdns.org before they can be updated

caddy

  • Custom image built from caddy/Dockerfile — adds the DuckDNS DNS provider plugin to the official Caddy image
  • Config at caddy/Caddyfile; TLS certificates stored in the caddy_data Docker volume
  • Obtains free Let's Encrypt certificates via DNS-01 challenge (no extra ports needed, no cost)
  • Listens on :80 (redirects to HTTPS) and :443
  • Routes:
    • ha-padriano.duckdns.org → Home Assistant :8123
    • git-padriano.duckdns.org → Forgejo :3000
  • To reload config without restarting: docker exec caddy caddy reload --config /etc/caddy/Caddyfile

homeassistant

  • Config stored at /home/padriano/projects/ha/config
  • Web UI: https://ha-padriano.duckdns.org (via Caddy) or http://server:8123 on the LAN
  • Runs on the internal bridge network so Caddy can reach it by container name
  • configuration.yaml must include http.use_x_forwarded_for: true and trusted_proxies for the Docker bridge range so HA accepts forwarded headers from Caddy
  • Has a healthcheck — status shows (health: starting) for ~60s on first boot

timemachine

  • Backup data stored at /home/padriano/backup/timemachine
  • Uses network_mode: host and a fixed hostname: timemachine — the stable hostname prevents macOS from losing the backup destination after container restarts
  • On your Mac: System Settings → General → Time Machine → Add Backup Disk

samba

  • Shared directory on the host: /home/padriano/share — must be owned by 1001:1001 (the UID/GID the container uses internally); without this, the share mounts on the Mac but files cannot be written
  • Uses a macvlan network with static IP 192.168.1.247 — avoids port 445 conflict with the timemachine container
  • Config stored at samba/smb.conf; the [Share] section is the only exported share
  • Avahi service file at samba/avahi-smb.service advertises the share for Finder sidebar discovery (installed to /etc/avahi/services/samba.service on the host)
  • Connecting from a Mac: open Finder → Go → Connect to Server → smb://192.168.1.247/Share
  • Connecting from Linux: smbclient //192.168.1.247/Share -U samba or mount with mount -t cifs //192.168.1.247/Share /mnt/share -o username=samba
  • Username and password are set via SAMBA_USERNAME / SAMBA_PASSWORD in .env

forgejo

  • All data (repos, config, SQLite DB) stored at /home/padriano/projects/forgejo
  • Backing up this single directory is sufficient for a full restore
  • Port 3000 is no longer exposed on the host — access is via Caddy only

First-run setup

Visit http://server:3000 on first start (LAN only) and complete the install wizard:

  • Base URL: https://git-padriano.duckdns.org
  • SSH domain: git-padriano.duckdns.org
  • SSH port: 2222

Access

Method Local network External (via DuckDNS)
Web UI http://server:3000 https://git-padriano.duckdns.org
Git SSH ssh://git@server:2222 ssh://git@git-padriano.duckdns.org:2222

For external access, forward these ports on your router to the server IP:

  • TCP 443 → Caddy (HTTPS — serves both HA and Forgejo)
  • TCP 2222 → Forgejo SSH

Git remote URL examples

# Add remote via HTTPS
git remote add origin https://git-padriano.duckdns.org/padriano/my-repo.git

# Add remote via SSH
git remote add origin ssh://git@git-padriano.duckdns.org:2222/padriano/my-repo.git

# Clone via SSH (local)
git clone ssh://git@server:2222/padriano/my-repo.git

Disk Space

# Free space on the main filesystem
df -h /

# Free space on all mounted filesystems
df -h

# Space used by each service's data directory
du -sh /home/padriano/projects/* /home/padriano/backup/*

Data & Backup Summary

Service Host path Notes
duckdns /home/padriano/projects/duckdns/config Token cache, not critical
caddy Docker volume caddy_data Issued TLS certificates — auto-reissued if lost
homeassistant /home/padriano/projects/ha/config All HA config and automations
timemachine /home/padriano/backup/timemachine Mac backup sparsebundles
samba /home/padriano/share General file share — back up as needed
forgejo /home/padriano/projects/forgejo All repos, DB, config