Tag: discord

  • Watchtower: automatic Docker updates, done safely

    Keeping a dozen Docker containers up to date by hand gets tedious. Watchtower does it for me: every night it checks for new images, updates the containers that need it, and tells me what it did. The trick is knowing what not to let it update.

    What Watchtower does

    Watchtower runs as a container with access to the Docker socket. On a schedule, it checks the registry for a newer version of each container’s image. If there is one, it pulls it and recreates the container with exactly the same settings, then optionally removes the old image.

    My setup

    services:
      watchtower:
        image: containrrr/watchtower:latest
        container_name: watchtower
        restart: unless-stopped
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
        environment:
          - TZ=Europe/Dublin
          - WATCHTOWER_SCHEDULE=0 0 4 * * *
          - WATCHTOWER_CLEANUP=true
          - WATCHTOWER_INCLUDE_STOPPED=true
          - WATCHTOWER_REVIVE_STOPPED=false
          - WATCHTOWER_NOTIFICATIONS=shoutrrr
          - WATCHTOWER_NOTIFICATION_URL=discord://<token>@<webhook-id>
          - WATCHTOWER_NOTIFICATIONS_HOSTNAME=homeserver
    • WATCHTOWER_SCHEDULE is a cron expression with a seconds field first. 0 0 4 * * * means 4 am every day, when nobody’s using anything.
    • WATCHTOWER_CLEANUP deletes the old image after updating, so your disk doesn’t slowly fill up.
    • INCLUDE_STOPPED / REVIVE_STOPPED update stopped containers too, but leave them stopped.
    • Notifications go to a Discord channel through Shoutrrr, so each morning I can see what changed. Shoutrrr also supports email, Telegram, ntfy and others. Treat the notification URL like a password: anyone with it can post to your channel.

    If Watchtower starts failing with a Docker API version error after a Docker upgrade, setting DOCKER_API_VERSION to a version your Docker engine supports fixes it.

    Choosing what not to auto-update

    Automatic updates are great for simple apps, but some containers shouldn’t change without you watching. Watchtower is controlled with labels on each container:

    labels:
      # never update this container automatically
      - com.centurylinklabs.watchtower.enable=false
    
      # check for updates and notify me, but don't apply them
      - com.centurylinklabs.watchtower.monitor-only=true

    How I use them:

    • Databases (Postgres for Immich; MariaDB for Nextcloud, WordPress and Joplin) are either excluded or monitor-only. Database upgrades can need migration steps, and a surprise major version bump can break the app that depends on it.
    • Immich’s database and Redis are excluded completely, because Immich pins specific versions for a reason.
    • Vaultwarden is excluded. My password vault gets updated deliberately, after I’ve read the release notes.
    • Everything else, such as dashboards, monitoring tools and media servers, updates automatically.

    Is auto-updating a good idea?

    For a home lab, I think so, with these exclusions. Most updates are security and bug fixes, and getting them automatically beats forgetting for months. The rules that keep it safe:

    1. Exclude anything stateful or critical.
    2. Get notifications, so you know what changed if something breaks.
    3. Have backups, so a bad update is an inconvenience, not a disaster. See my backup plan.