Ctrl K
ComunidadGuías…

docker-compose.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
version: "3.8" # kept so the legacy docker-compose 1.x still reads the file; Compose v2 ignores it with a warning

services:
  actual-sync:
    build:
      context: .
      dockerfile: Dockerfile
    image: actual-sync:latest
    container_name: actual-sync
    restart: unless-stopped

    # Environment variables (optional, overrides config.json)
    environment:
      # PUID/PGID: run as this UID/GID and chown the data/logs volumes to match.
      # Defaults to 1001:1001. On Unraid set 99:100 (nobody:users).
      - PUID=1001
      - PGID=1001
      - TZ=Europe/Madrid
      - NODE_ENV=production

    # Mount config and data volumes
    volumes:
      # Configuration file
      - ./config/config.json:/app/config/config.json:ro

      # Persistent data directories
      - actual-sync-data:/app/data
      - actual-sync-logs:/app/logs

      # If using custom data directories for budget files
      # - ./budget-data:/budget-data

    # Dashboard, health and metrics port, published on this machine only:
    # nothing else on the network can reach it. To use the dashboard from
    # another machine, put a reverse proxy in front (docs/DOCKER_DEPLOYMENT.md,
    # "Behind a reverse proxy"), or change this to "3000:3000" and set
    # healthCheck.dashboard.auth (and healthCheck.auth for the metrics) in
    # config.json first. healthCheck.host stays "0.0.0.0" inside the container
    # either way; this line decides who can reach it.
    ports:
      - "127.0.0.1:3000:3000"

    # Container hardening (#253). Every Linux capability is dropped, then the
    # three the entrypoint needs are added back. It runs as root only to apply
    # PUID/PGID and chown the volumes, then drops to actualuser, which runs
    # with no capability at all. Verified by a container run against each
    # setting (see docs/DOCKER_DEPLOYMENT.md, "Container hardening").
    #   CHOWN:          chown -R of /app/data and /app/logs
    #   SETUID, SETGID: usermod/groupmod for PUID/PGID, and su-exec to the user
    # A bind-mounted data or logs directory that another user owns with mode
    # 700 also needs DAC_READ_SEARCH, or the chown cannot enter it.
    # Alternative: set `user: "1001:1001"` (the owner of your directories).
    # The entrypoint then skips its root phase and needs no capability, so
    # cap_add can be removed entirely.
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - SETUID
      - SETGID

    # No process in the container can gain privileges through a setuid binary,
    # whatever capabilities it holds.
    security_opt:
      - no-new-privileges:true

    # Optional: read-only root filesystem. It works with the default PUID/PGID
    # (1001:1001). Any other value needs usermod and groupmod to write
    # /etc/passwd and /etc/group, which a read-only root refuses, so the
    # container does not start. Uncomment both lines together.
    # read_only: true
    # tmpfs:
    #   - /tmp

    # Resource limits
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 128M

    # Health check
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1); }).on('error', () => process.exit(1));"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

    # Logging configuration (#451). stdout is the main log sink and the Docker
    # log driver keeps it; json-file has no size limit by default, so cap it here.
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

    # Network configuration
    networks:
      - actual-network

  # Optional: Actual Budget server
  # Uncomment if you want to run Actual Budget alongside sync service
  # actual-server:
  #   image: actualbudget/actual-server:latest
  #   container_name: actual-server
  #   restart: unless-stopped
  #   ports:
  #     - "5006:5006"
  #   volumes:
  #     - actual-server-data:/data
  #   networks:
  #     - actual-network

  # Optional: Monitoring with Prometheus
  # prometheus:
  #   image: prom/prometheus:latest
  #   container_name: prometheus
  #   restart: unless-stopped
  #   ports:
  #     - "9090:9090"
  #   volumes:
  #     - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
  #     - prometheus-data:/prometheus
  #   command:
  #     - '--config.file=/etc/prometheus/prometheus.yml'
  #     - '--storage.tsdb.path=/prometheus'
  #   networks:
  #     - actual-network

  # Optional: Grafana for visualization
  # grafana:
  #   image: grafana/grafana:latest
  #   container_name: grafana
  #   restart: unless-stopped
  #   ports:
  #     - "3001:3000"
  #   volumes:
  #     - grafana-data:/var/lib/grafana
  #   environment:
  #     - GF_SECURITY_ADMIN_PASSWORD=admin
  #   networks:
  #     - actual-network

networks:
  actual-network:
    driver: bridge

volumes:
  actual-sync-data:
    driver: local
  actual-sync-logs:
    driver: local
  # actual-server-data:
  #   driver: local
  # prometheus-data:
  #   driver: local
  # grafana-data:
  #   driver: local