# Development containers, these should only be used if you are developing. # The database is SQLite inside the media directory (./test/config/wrolpi.db); no db service. version: '3' services: controller: # WROLPi Controller Service build: context: . dockerfile: docker/controller/Dockerfile restart: unless-stopped ports: - "8080:80" volumes: # Controller code (for development hot-reload) - ./controller:/app/controller # Docker socket for container management - /var/run/docker.sock:/var/run/docker.sock # Host system info (read-only) - /proc:/host/proc:ro - /sys:/host/sys:ro # Media directory (needed for Samba share path validation) - ${MEDIA_DIRECTORY:-./test}:/media/wrolpi environment: - DOCKERIZED=true - MEDIA_DIRECTORY=/media/wrolpi # Override CMD to enable auto-reload for development command: ["python", "-m", "controller.serve"] healthcheck: test: [ 'CMD-SHELL', 'curl -f http://127.0.0.1:80/api/health || exit 1' ] interval: 30s timeout: 5s start_period: 10s retries: 3 api: depends_on: controller: condition: service_started build: context: . dockerfile: docker/api/Dockerfile environment: # Sanic 25.x wants 'spawn' but our code uses 'fork' for multiprocessing. # This tells Sanic to accept the existing start method. - SANIC_START_METHOD_SET=1 volumes: - './main.py:/opt/wrolpi/main.py' - './wrolpi:/opt/wrolpi/wrolpi' - './modules:/opt/wrolpi/modules' - './scripts:/opt/wrolpi/scripts' - './test:/opt/wrolpi/test' - './test:/media/wrolpi' - './alembic:/opt/wrolpi/alembic' - './alembic.ini:/opt/wrolpi/alembic.ini' ports: - ${REACT_APP_API-0.0.0.0:8081}:8081 user: '${UID-1000}:${GID-1000}' healthcheck: test: [ 'CMD-SHELL', 'curl http://127.0.0.1:8081/api/echo' ] interval: 2m archive: # Python/Sanic wrapper around Singlefile and Readability. build: context: . dockerfile: docker/archive/Dockerfile volumes: - './docker/archive/main.py:/app/main.py' ports: - '8083:8080' healthcheck: test: [ 'CMD-SHELL', 'curl http://127.0.0.1:8080/' ] interval: 2m app: # React App depends_on: - api build: context: . dockerfile: docker/app/Dockerfile volumes: - './app/public:/app/public' - './app/src:/app/src' - './app/package.json:/app/package.json' - '.env:/app/.env' command: 'npm run start' stdin_open: true healthcheck: test: [ 'CMD-SHELL', 'curl http://127.0.0.1:3000' ] interval: 1m user: '${UID-1000}:${GID-1000}' environment: # Force React to use Caddy port to connect to it's websocket. - WDS_SOCKET_PORT=0 # react-scripts lints in-process on every incremental rebuild, which costs time on each # save and buries the compile result under a few hundred warnings the repo has carried # for years. This container only serves; linting still happens where it is acted on -- # `npm run build` and CI both run it, and both fail on a real error. # # NOT a memory fix, though it was tried as one after the dev server was OOM-killed three # times in an afternoon. Measured either way, the container settles anywhere between # 3.0GB and 3.7GB and the spread between two runs of the SAME configuration is wider # than the spread between configurations. Raising Docker Desktop's VM limit is what # actually stopped the kills. - DISABLE_ESLINT_PLUGIN=true web: # Caddy reverse proxy - handles HTTPS for all services. depends_on: - app - zim - help build: context: . dockerfile: docker/web/Dockerfile ports: - ${WEB_HOST-0.0.0.0}:${WEB_HTTPS_PORT-8443}:443 - '8084:8084' - '8085:8085' - '8086:8086' volumes: - './docker/web/Caddyfile:/etc/caddy/Caddyfile' - './icon.ico:/etc/caddy/favicon.ico' - './icon.png:/etc/caddy/icon.png' - './test:/opt/media' - './modules/map/static:/opt/wrolpi/modules/map/static:ro' # No mount over /opt/wrolpi-blobs. A bind mount REPLACES the image's directory rather # than merging with it, and the host './blobs' this used to mount is git-ignored -- so # it was empty on every clone and hid the blobs the image provides. The web image bakes # map-overview.pmtiles in; see docker/web/Dockerfile. environment: - MEDIA_DIRECTORY=/opt/media # Set EXTRA_SANS to include the host's LAN IP in the TLS certificate. # Example: EXTRA_SANS=IP:10.0.0.5 - EXTRA_SANS=${EXTRA_SANS:-} # Caddy is PID 1 and reaps nothing; busybox wget's ssl_client helper from the healthcheck is # orphaned to it and stays a zombie (one per check). init runs tini as PID 1 to reap them. init: true healthcheck: test: [ 'CMD-SHELL', 'wget --spider --no-check-certificate https://127.0.0.1:443 || exit 1' ] interval: 1m zim: # kiwix-serve build: context: . dockerfile: docker/zim/Dockerfile volumes: - './test:/media/wrolpi' - './docker/zim/entrypoint.sh:/entrypoint.sh' healthcheck: test: [ 'CMD-SHELL', 'curl http://127.0.0.1:80' ] interval: 1m samba: # Samba file sharing - started/stopped by the controller based on configured shares. build: context: . dockerfile: docker/samba/Dockerfile restart: "no" depends_on: controller: condition: service_healthy ports: - "445:445" volumes: - ${MEDIA_DIRECTORY:-./test}:/media/wrolpi help: # The WROLPi Help documentation. build: context: . dockerfile: docker/help/Dockerfile volumes: - './docker/help/wrolpi-help:/opt/wrolpi-help' healthcheck: test: [ 'CMD-SHELL', 'curl http://127.0.0.1:80' ] # mkdocs serves on 80; 8086 is Caddy's proxy. interval: 1m