• Dec. 2, 2025, 9:39 a.m.

    Managing a hybrid environment (like a YunoHost VPS with custom Docker containers) requires more than just basic start/stop commands. This note covers essential docker compose variants for maintenance and explores different strategies for ensuring containers launch automatically after a system reboot.


    1. The docker compose Toolkit

    While docker compose up -d is the standard command to launch services, the following variants are crucial for updates and troubleshooting.

    🛠️ Deployment & Updates

    These commands are used for deploying new configurations or pulling updates:

    • docker compose up -d --build

      • Function: Rebuilds images before starting.
      • Use Case: Use this after modifying a Dockerfile or local source code.
    • docker compose up -d --force-recreate

      • Function: Recreates containers from scratch.
      • Use Case: Useful when configuration changes (like environment variables) aren't applying, even if the image hasn't changed.
    • docker compose up -d --pull always

      • Function: Pulls the latest image versions.
      • Use Case: Ensures you are running the absolute latest version of an image (e.g., using the latest tag) from the registry.

    Typical Maintenance Routine:
    To update a stack completely:
    docker compose pull && docker compose up -d --force-recreate

    🩺 Diagnostics & Control

    • Logs: docker compose logs -f
      • (Follows the logs in real-time; essential for debugging startup crashes).
    • Shell Access: docker compose exec [service_name] bash
      • (Opens a terminal inside the container).
    • Status: docker compose ps
      • (Lists running containers in the current stack).

    💥 Teardown (Destructive Actions)

    These commands stop services and clean up resources:

    • Standard Stop: docker compose down

      • (Stops containers and removes the network).
    • Full Wipe: docker compose down -v

      • (Stops containers AND deletes named volumes).
      • Warning: This results in permanent data loss if your database uses named volumes.

    2. Strategies for Auto-Starting Containers

    When the VPS or server reboots, Docker needs instructions on which containers to revive.

    Strategy A: The Native Docker Policy (Recommended)

    The cleanest method is to define the auto-start behaviour directly in the docker-compose.yml file.

    Example Configuration:

    services:
      app:
        image: my-app
        restart: unless-stopped
    

    Restart Policy Options:

    • always: Restarts the container regardless of why it stopped (even if manually stopped).
    • unless-stopped: Restarts the container on boot only if it was running before the system shut down. It respects your manual decision to stop a service.

    Strategy B: The "Blanket" Wake-Up Call

    This strategy uses an OS-level script to force all stopped containers to start upon boot, regardless of their docker-compose.yml settings.

    The Command (Robust Version):

    A command using xargs is preferred over a simple docker start $(docker ps -aq) to avoid errors when the list is empty:

    docker ps -q -f status=exited | xargs --no-run-if-empty docker start
    

    Implementation via Cron:

    1. Run crontab -e.
    2. Add the following line to run at reboot (with a 30-second delay to ensure the Docker daemon is ready):

    <!-- end list -->

    @reboot sleep 30 && docker ps -q -f status=exited | xargs --no-run-if-empty docker start
    

    ⚖️ Critical Comparison: Native vs. Blanket Script

    The two strategies for auto-starting containers have significant differences:

    Native (restart: unless-stopped)

    • Granularity: Offers per-service control.
    • "Zombie" Risk: Low. If you manually stop a container, it stays stopped.
    • Boot Load: Docker manages the startup queue and dependencies efficiently.
    • Portability: The configuration travels with the yml file.

    Blanket Script (cron)

    • Granularity: Is global (all or nothing).
    • "Zombie" Risk: High. It will revive "garbage" or broken containers you intentionally stopped weeks ago.
    • Boot Load: Tries to launch everything simultaneously (potential CPU spike).
    • Portability: The configuration is tied to the specific server's OS settings.

    Conclusion: Use Strategy A for production services to maintain a clean state. Use Strategy B only if you need a fail-safe to ensure absolutely nothing remains offline after a power cycle.