A four-container automation stack on one Raspberry Pi
One door in — Nginx
Ordered startup with healthchecks
Secrets and state outside the images
A snippet from the implementation
Straight from the example as deployed on the Raspberry Pi (Docker) — copy it freely:
services:
# ---- Reverse proxy: the only container exposed to the outside --------------
nginx:
image: nginx:stable-alpine
container_name: irrigation-nginx
restart: unless-stopped
ports:
- "80:80" # only port published on the Raspberry Pi
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- laravel_public:/var/www/html/public:ro
depends_on:
- laravel
- nodered
networks: [irrigation]
# ---- Laravel frontend (multi-company login, alarm history) -----------------
laravel:
build: ./laravel # Dockerfile with php-fpm + composer
container_name: irrigation-laravel
restart: unless-stopped
environment:
APP_ENV: production
DB_HOST: mysql
DB_DATABASE: irrigation
DB_USERNAME: irrigation
DB_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- laravel_public:/var/www/html/publicThe full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.
Frequently asked questions
Is a Raspberry Pi powerful enough for four containers?
Comfortably, on a Pi 4 with 4 GB. Node-RED and MySQL are the only meaningful consumers; Nginx and PHP-FPM idle in the low tens of megabytes. Use a 64-bit OS and a quality SD card or SSD for the MySQL volume.
How do I update one service without touching the rest?
docker compose pull nodered followed by docker compose up -d nodered recreates only that container. Flows, credentials and installed palette nodes live in the nodered_data volume, so they survive the upgrade.
Why set the timezone in the Node-RED container?
The irrigation schedulers fire at local civil time, morning and evening. Without TZ=Europe/Madrid the container runs in UTC and the cycles drift one or two hours depending on daylight saving — irrigating at the wrong time of day.