Automated Docker Deployments on the Raspberry Pi: Local-First Dev Environments
Part 3 of 4 in the series Homelab on the Raspberry Pi

Contents
Operating self-hosted services—such as Home Assistant, Node-RED, and local analytics tracking environments—on a Raspberry Pi often involves manual software updates and ad-hoc configuration adjustments. This traditional approach consumes significant maintenance time and introduces operational risks, including configuration drift, dependency conflicts, and unexpected downtime.
To establish a resilient, deterministic local infrastructure, services must be decoupled from the host operating system. Containerizing the entire smart home and analytics tool landscape via Docker Compose paired with automated deployment pipelines—using local Watchtower setups or structured CI/CD workflows via GitHub Actions—ensures reproducible, zero-downtime edge environments.
1. Containerizing the Edge Landscape with Docker Compose
Docker Compose serves as the declarative baseline for local-first edge architectures. By defining all services, persistent volume mounts, and network bridges within a single version-controlled configuration file, infrastructure state becomes fully reproducible.
# docker-compose.yml: Integrated Smart Home & Local Tracking Stack
services:
homeassistant:
container_name: homeassistant
image: ghcr.io/home-assistant/home-assistant:stable
volumes:
- /opt/homeassistant/config:/config
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
network_mode: host
nodered:
container_name: nodered
image: nodered/node-red:latest
environment:
- TZ=Europe/Warsaw
volumes:
- /opt/nodered/data:/data
ports:
- "1880:1880"
restart: unless-stopped
watchtower:
container_name: watchtower
image: containrrr/watchtower:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_SCHEDULE=0 0 4 * * *
restart: unless-stopped
A note on the maintenance status: the upstream project containrrr/watchtower was archived on 17 December 2025 and has been read-only since then, so the image receives no further updates or security fixes. The original maintainers have not designated a successor. Development continues in community forks — nickfedor/watchtower (also published as ghcr.io/nicholas-fedor/watchtower) is configuration-compatible and still ships regular releases. The update path for this service should therefore be reviewed before productive use.
In this architecture, persistent data directories reside on reliable external storage (such as a NAS share or SSD), ensuring that container updates never overwrite critical configurations or historical metrics.
2. Automated Maintenance: Watchtower vs. CI/CD Pipelines
Automating deployment and lifecycle management can be achieved through two primary architectural patterns, depending on system complexity and governance requirements:
| Deployment Pattern | Execution Mechanism | Best Suited For | Key Advantage |
|---|---|---|---|
| Local Automation (Watchtower) | A background daemon polls image registries daily and restarts updated containers automatically. | Standard off-the-shelf images (Home Assistant, Node-RED, Eclipse Mosquitto). | Zero external infrastructure required; fully autonomous edge maintenance. |
| GitOps / CI/CD (GitHub Actions) | Code commits trigger remote build pipelines that SSH into the Raspberry Pi and execute deployments. | Custom software builds, proprietary analytics tools, or multi-node infrastructures. | Deterministic version control, automated testing before deployment, and easy rollbacks. |
3. Implementing a GitHub Actions Deployment Pipeline
For custom edge applications or structured infrastructure-as-code (IaC) repositories, deploying via GitHub Actions provides an audit trail of every configuration change. When updates are pushed to the main branch, a workflow connects securely to the Raspberry Pi over SSH to pull changes and reconstruct the stack.
# .github/workflows/deploy-edge.yml
name: Deploy Stack to Raspberry Pi
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Execute Remote Deployment via SSH
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.RPI_HOST }}
username: ${{ secrets.RPI_USER }}
key: ${{ secrets.RPI_SSH_KEY }}
script: |
cd /opt/edge-stack
git pull origin main
docker compose pull
docker compose up -d --remove-orphans
docker system prune -f
Summary
Transitioning a Raspberry Pi from a manually configured single-board computer into an automated, containerized edge server minimizes administrative overhead. Whether deploying autonomous updates via Watchtower or deterministic GitOps workflows via GitHub Actions, containerization guarantees a stable, secure, and low-maintenance operational environment for smart home and analytics infrastructures.
Homelab on the Raspberry Pi
- Raspberry Pi 4 and 5: Booting From an SSD by Changing the Bootloader
- Uninterruptible Power Supply (UPS) for Raspberry Pi 4 and 5: Top 5 Solutions for High-Load Setups
- Automated Docker Deployments on the Raspberry Pi: Local-First Dev Environments
- Local CI/CD for Raspberry Pi: Automating Docker Compose Deployments
One comment
Declaring the whole stack in one file and keeping persistent data outside the containers is the arrangement that makes a rebuild boring — which is the highest praise infrastructure can get.
An addition from a Pi that filled its disk twice: container logs. The default driver writes JSON files that grow without limit, and a chatty container — one restarting in a loop, or Zigbee traffic at debug level — can produce gigabytes in a weekend. Neither
duon the data directory nor the compose file gives any hint, because the files live under Docker’s own path. Two lines per service fix it permanently: a logging section withmax-sizeandmax-file. Worth adding to the template before the first incident rather than after it.