Self-hosted service
Quenary/tugtainer avatar
Quenary/tugtainer

Tugtainer: Docker Container Auto-Updates Behind a Web UI

An application for automated Docker container updates with a web UI

1,531 stars52 forksPythonMIT

At a glance

What is it?
Tugtainer watches and optionally recreates Docker containers from a self-hosted web UI, with an agent for remote hosts and a socket proxy to avoid mounting the Docker socket. It is explicitly not recommended for production, and its own README sets the boundary that matters most.
Who is it for?
Adopt Tugtainer if you run a homelab or a small set of self-hosted Docker hosts, want a browser UI for check-and-update decisions, and are willing to keep backups because the README itself says the app is distributed as-is and is not recommended for use in a production environment. Do not adopt it if you need updates to apply to the Tugtainer container, the Tugtainer Agent, or a socket proxy from within the same app; the README states those cannot be updated from inside it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap Tugtainer fills between watchtower-style daemons and full orchestration

A container that runs an image tag like latest keeps running whatever was pulled the last time someone pulled it. Nothing in Docker itself notices that the upstream image changed. Tugtainer exists to close that gap: it checks whether a newer image exists for your containers and, if you allow it, recreates them. The README lists the intended scope plainly: a web UI with authentication, multiple hosts, socket proxy support, crontab scheduling, notifications, per-container configuration for check-only or auto-update, manual and automatic image pruning, linked container support, private registries, basic container control such as start and stop, and container inspect and logs. That list describes a homelab operator or a small self-hosted deployment, not a fleet managed by a platform team. The README's own warning confirms the audience: the application is distributed as-is and is not recommended for use in a production environment, and it adds a reminder about regular backups of important data. If you need a scheduler that treats container updates as a governed change process, this is the wrong layer.

How the check and update path actually runs

Tugtainer is a Python backend with an Angular front end, and it talks to the Docker CLI rather than reimplementing the Docker API. That single design decision explains most of the rest. The app container mounts the Docker socket (the quick start example uses /var/run/docker.sock:/var/run/docker.sock:ro) or points at a socket proxy through DOCKER_HOST. When a check runs, the backend asks Docker about images and containers; when an update is approved, the container is stopped and recreated from the new image. Scheduling comes from crontab-style configuration, and automatic updates are off by default, so enabling them is a per-container decision rather than a global switch. The agent exists because a single instance cannot reach every Docker daemon: you deploy the agent next to the remote daemon, add it under Menu then Hosts in the UI, and supply an Agent secret that matches the AGENT_SECRET you gave the agent container. Backend and agent speak HTTP by default, with a reverse proxy in front for HTTPS.

Deployment commands, environment variables and the socket proxy variables that matter

The quick start is three commands. Create the volume with docker volume create tugtainer_data, pull ghcr.io/quenary/tugtainer:1, then run the container publishing port 9412 to port 80, with --restart=unless-stopped, a required AGENT_SECRET, the data volume mounted at /tugtainer, and the Docker socket mounted read-only. The README marks AGENT_SECRET as required and instructs you to set a strong, unique shared secret. The agent image is ghcr.io/quenary/tugtainer-agent:1, published on port 9413 to the agent's 8001, and it needs the same AGENT_SECRET value and the Docker socket. If you would rather not mount the socket at all, the provided compose files already use a socket proxy, and the manual route is to run linuxserver/socket-proxy and enable variables by feature: CONTAINERS, IMAGES, POST, INFO and PING for the base check feature; NETWORKS for updates; ALLOW_LOGS for logs; and ALLOW_START, ALLOW_STOP, ALLOW_RESTARTS, ALLOW_PAUSE and ALLOW_UNPAUSE for container controls. Then set DOCKER_HOST to tcp://my-socket-proxy:port on the Tugtainer or agent container. Two more environment variables govern remote agents: AGENT_ALLOW_NETWORKS accepts a CIDR such as 192.168.0.0/24 and AGENT_ALLOW_ENDPOINTS accepts something like 10.0.0.5:9413, because agent host URLs resolving to private or reserved networks are blocked by default. When AGENT_ENABLED is true, only the built-in endpoint 127.0.0.1:8001 is allowed until you widen those lists.

Labels and hooks: the parts that decide whether an update is safe

Two labels carry real weight. dev.quenary.tugtainer.protected=true means the container cannot be stopped, so even if a newer image exists it will not be updated from the app. The README says this is primarily used for Tugtainer itself, the agent, and the socket proxy in the provided compose files, which is the honest answer to a self-referential problem: the tool cannot replace the components it uses to do its work. The second label, dev.quenary.tugtainer.depends_on, takes a comma-separated list of container names and declares a dependency even when the containers are not in the same compose project, which matters when an application container must be recreated alongside its database. Hooks go further: you can configure shell commands to run inside a container at pre_update, post_update, pre_stop, pre_rollback and post_rollback, each executed as sh -c "<command>" inside the target container through the agent. The README notes that Tugtainer has no built-in database or service-specific backup logic, so if you want a dump before a database container is replaced, the pre_stop hook is where you write it yourself. That is a deliberate omission, not an oversight, and it means the safety of an automated update depends on what you put in those hooks.

Where Tugtainer breaks down

The update mechanism has a hard boundary: the README states you cannot update an agent or a socket proxy from within the app because they are used to communicate with the Docker CLI. It goes further and warns against including those containers in a docker-compose file that also contains containers you want updated automatically, because the update will error out. The suggested workaround is to enable check only for them and recreate them manually or with another tool such as Portainer. Private registries have their own constraint: you must mount a Docker config file (for example $HOME/.docker/config.json to /root/.docker/config.json read-only) on whichever component holds the container with the private image, so on the agent when the image runs on a remote host. TLS on the agent without a reverse proxy is awkward too; the README says the image healthcheck uses http://localhost:8001 and may fail if uvicorn serves only HTTPS. And the largest limitation is stated at the top of the README rather than buried: not recommended for production. Anyone treating this as a replacement for a controlled release pipeline is reading against the project's own advice.

How it differs from Watchtower and from Portainer

Watchtower is the closest comparison in purpose: it also polls for new images and recreates containers. The difference here is the interface and the granularity of control. Tugtainer puts a web UI with authentication in front of the decision, keeps automatic updates disabled by default, and lets you set check-only or auto-update per container, which is a different posture from a daemon configured once and left to run. It also separates the checking component from the host through the agent, so one UI can cover several Docker daemons. Portainer sits at a different level: it is a general container management interface, and the Tugtainer README itself names it as an option for recreating protected containers manually. If you already run Portainer and only need occasional image updates with a human in the loop, adding Tugtainer duplicates surface area. Tugtainer earns its place when the recurring task is specifically image currency across more than one host and you want notifications and per-container policy attached to it.

Maintenance, licensing and what the release cadence implies

The repository is MIT licensed, which permits commercial and private use with the usual requirement to preserve the licence and copyright notice; that is a description of the licence text, not legal advice. The versioning visible in the material is aggressive: v1.38.0, v1.39.0 and v1.40.0 were published within four days of each other in early September 2026, and the image tag used in the deployment commands is the major-version tag 1 rather than a pinned patch. That combination means an unattended pull of ghcr.io/quenary/tugtainer:1 will move you across minor releases quickly. There is no homepage listed, so the repository and its docs directory are the documentation. The README links separate documents for notifications, check and update behaviour, screenshots, contributing and security, which suggests the security policy in particular is worth reading before you expose the UI or widen AGENT_ALLOW_NETWORKS. The cost of running it is low in resources but not in attention: you are responsible for the hooks that make updates safe, for keeping the agent and socket proxy current by hand, and for backups, which the README raises unprompted.

Editorial conclusion

Adopt Tugtainer if you run a homelab or a small set of self-hosted Docker hosts, want a browser UI for check-and-update decisions, and are willing to keep backups because the README itself says the app is distributed as-is and is not recommended for use in a production environment. Do not adopt it if you need updates to apply to the Tugtainer container, the Tugtainer Agent, or a socket proxy from within the same app; the README states those cannot be updated from inside it. Before trusting it with anything, verify that AGENT_SECRET is set to a strong unique value, that your socket proxy exposes only the variables for the features you enabled, and that automatic updates are switched on per container rather than globally, since they are disabled by default.

Official sources

  1. Issues
  2. License: MIT
  3. Quenary/tugtainer on GitHub
  4. README
  5. Releases
Community notes

Community notes