IPv4 & IPv6 Leasing - Any RIR, Any LocationOrder Now
Hostperl

Docker Watchtower on a Hostperl VPS in 2026

By Raman Kumar

Share:

Updated on Aug 11, 2026

Docker Watchtower on a Hostperl VPS in 2026

Why Docker Watchtower fits a small VPS

Docker Watchtower updates running containers on a schedule, so you do not have to log in for every patch cycle. On a Hostperl VPS, that matters when you run a customer site, a staging stack, or a small internal app and want fewer manual restarts.

This tutorial walks you through the full setup, from the first SSH login to a working Watchtower install. You will check the firewall, create a Docker Compose file, verify logs, and keep a clear rollback path. If you are also deciding whether to run your app on a managed stack, a Hostperl VPS gives you the room to test this cleanly before you move production traffic.

If you are choosing a deployment style, the related guide on Docker Compose deployment on VPS is a useful companion. It covers the base app layout; this article adds automated updates on top.

Connect to the VPS and check the operating system

On your local computer:

ssh root@203.0.113.10

203.0.113.10 is a reserved documentation example. Replace it with the public IP assigned to your Hostperl server. If your provider gives you a non-root login, use that first and keep the same server IP.

Once you are in, detect the OS before you install anything.

On the VPS as root:

cat /etc/os-release

You should see either Ubuntu/Debian or AlmaLinux/Rocky Linux. The next steps are split so you use the correct package manager and service names.

Prepare the server for Docker Watchtower

Start with a non-root admin, system updates, time sync, and swap if the VPS is small. That gives you a steadier host before you let containers auto-update.

Ubuntu and Debian

On the VPS as root:

apt update && apt -y upgrade

This refreshes package lists and installs current patches. Reboot now if the kernel was updated.

adduser deploy

Create the deploy account when you want a normal admin login. Set a strong password when prompted.

usermod -aG sudo deploy

This grants sudo access. Keep your root session open until the new login works.

apt -y install ca-certificates curl gnupg openssh-server chrony ufw

These packages provide HTTPS trust roots, package signing support, SSH, time sync, and a firewall. chrony is the current default time-sync choice on many installs.

systemctl enable --now chrony

Time sync helps with logs and TLS checks.

AlmaLinux and Rocky Linux

On the VPS as root:

dnf -y update

Install current patches first. Reboot if the kernel changed.

useradd -m -G wheel deploy

Create the deploy user and add it to the sudo-capable wheel group.

passwd deploy

Set the initial password if you want password-based access. If you plan to use SSH keys only, you can lock it later.

dnf -y install ca-certificates curl gnupg2 openssh-server chrony firewalld

These provide the same core setup on RHEL-compatible systems.

systemctl enable --now chronyd firewalld

Enable time sync and the firewall.

Create and test the non-root SSH login

Do not disable root until you verify the new account from a second terminal. That avoids lockout.

On your local computer:

ssh-keygen -t ed25519 -C "deploy@example.com"

This creates a key pair on your workstation if you do not already have one.

ssh-copy-id deploy@203.0.113.10

Replace the IP with your server’s public address. This copies your public key to the new account.

On the VPS as root:

mkdir -p /home/deploy/.ssh && chown -R deploy:deploy /home/deploy/.ssh && chmod 700 /home/deploy/.ssh

This is the manual fallback if you need to place the key yourself.

touch /home/deploy/.ssh/authorized_keys && chown deploy:deploy /home/deploy/.ssh/authorized_keys && chmod 600 /home/deploy/.ssh/authorized_keys

After the key is in place, open a second terminal and test the account.

On your local computer:

ssh deploy@203.0.113.10

Then confirm sudo works.

On the VPS as the non-root sudo user:

sudo -v

If that succeeds, leave the root session open only for emergency recovery.

Install Docker Engine and Compose

Watchtower needs Docker running cleanly first. Use the official repository so you get current packages.

Ubuntu and Debian

On the VPS as root:

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg

If you are on Debian, replace ubuntu with debian in the Docker repository line below.

. /etc/os-release && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable" > /etc/apt/sources.list.d/docker.list
apt update && apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker

AlmaLinux and Rocky Linux

On the VPS as root:

dnf -y install dnf-plugins-core
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker

Check the version before you continue.

On the VPS as the non-root sudo user:

docker --version && docker compose version

You should see current Docker and Compose output. If you want the deploy user to run Docker without sudo, add it to the docker group and log in again.

On the VPS as root:

usermod -aG docker deploy

Then reconnect as deploy and confirm docker ps works.

Open the firewall before exposing the service

Watchtower itself does not need an inbound port, but Dockerized apps usually do. Allow SSH first, then the web ports you actually use.

Ubuntu and Debian with UFW

On the VPS as root:

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
ufw status verbose

Keep SSH allowed before you enable the firewall. The status output should list OpenSSH and any HTTP ports you opened.

AlmaLinux and Rocky Linux with firewalld

On the VPS as root:

firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
firewall-cmd --list-all

On SELinux-enabled hosts, leave it enforcing unless your app needs a specific policy change. Watchtower itself does not need a special SELinux exception.

Create the Watchtower stack

Use a dedicated directory so the container definition is easy to back up and inspect.

On the VPS as the non-root sudo user:

sudo mkdir -p /opt/myapp/watchtower && sudo chown -R deploy:deploy /opt/myapp

This gives the deploy user ownership of the deployment files.

cd /opt/myapp/watchtower && pwd

Create the Compose file.

nano docker-compose.yml

Paste this file content, then save and exit with Ctrl+O, Enter, and Ctrl+X.

services:
  watchtower:
    image: containrrr/watchtower:1.7.1
    container_name: watchtower
    restart: unless-stopped
    command: --interval 300 --cleanup --label-enable
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/localtime:/etc/localtime:ro
    environment:
      - TZ=Pacific/Auckland

This checks for updates every five minutes, removes old image layers, and only updates containers that carry the Watchtower label. Adjust TZ if your server uses another timezone.

Start the stack.

docker compose up -d

Then confirm the container is running.

docker compose ps

Label a container for automatic updates

Watchtower ignores unlabeled containers in this setup. That keeps control in your hands.

Here is a simple example app container you can adapt to your own service.

On the VPS as the non-root sudo user:

nano /opt/myapp/watchtower/docker-compose.yml

Replace the file with this example that adds a test app and a Watchtower label. Save and exit when done.

services:
  app:
    image: nginx:1.27-alpine
    container_name: app
    restart: unless-stopped
    labels:
      - com.centurylinklabs.watchtower.enable=true
    ports:
      - "8000:80"
  watchtower:
    image: containrrr/watchtower:1.7.1
    container_name: watchtower
    restart: unless-stopped
    command: --interval 300 --cleanup --label-enable
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/localtime:/etc/localtime:ro
    environment:
      - TZ=Pacific/Auckland

Bring the stack back up.

docker compose up -d

Now test the app from the server and from your computer.

On the VPS as the non-root sudo user:

curl -I http://127.0.0.1:8000

On your local computer:

curl -I http://203.0.113.10:8000

Replace the IP with your real server address. You should get an HTTP 200 or 304 response from Nginx.

Check logs, updates, and runtime behavior

Watchtower writes clear logs when it scans and updates containers. Read them before you trust it in production.

On the VPS as the non-root sudo user:

docker logs --tail 50 watchtower

Look for messages about scanned containers, skipped unlabeled containers, or successful image checks. If you see permission errors on the Docker socket, verify the user is in the docker group and re-login.

To simulate an update safely, change the image tag of the test app or run a container you control with a newer tag. Watchtower should pull the new image and recreate only the labeled container.

Check whether the container restarted cleanly.

docker ps --format 'table {{.Names}}	{{.Status}}	{{.Image}}'

Make it survive a reboot

Docker restart policies cover the container side. You should also confirm the host services start on boot.

On the VPS as root:

systemctl is-enabled docker
systemctl is-enabled sshd

On Ubuntu and Debian, the SSH service name is usually ssh. On AlmaLinux and Rocky Linux, it is sshd. Check the one your OS uses.

After a controlled reboot, verify the stack comes back.

reboot

Then reconnect and run:

docker compose -f /opt/myapp/watchtower/docker-compose.yml ps

Troubleshooting the common failures

Docker does not start: check the unit and the journal.

systemctl status docker --no-pager
journalctl -u docker -n 50 --no-pager

If the logs mention storage or cgroup issues, fix the underlying host problem before retrying.

Watchtower cannot read the Docker socket: confirm permissions and group membership.

id deploy

If docker is missing from the groups list, run usermod -aG docker deploy as root and log out and back in.

Your app stops responding after an update: inspect the container logs and roll back to the previous image tag.

docker logs --tail 100 app
docker compose pull app && docker compose up -d app

If you pinned the last working tag in your Compose file, restore that tag and bring the service up again. That is the safest rollback path for a small VPS.

Final verification

Before you close the ticket or hand the server to a client, check the host, the containers, and the web endpoint.

On the VPS as the non-root sudo user:

docker compose -f /opt/myapp/watchtower/docker-compose.yml ps
docker logs --tail 20 watchtower
ss -tulpn | grep 8000

On your local computer:

curl -I http://203.0.113.10:8000

If you are using this for a client site, pair it with an app backup schedule and a restore test. The article on PostgreSQL backup and restore on a Hostperl VPS is useful if your stack depends on a database.

If you want a VPS that gives you room to test container updates without crowding production traffic, Hostperl can help. A Hostperl VPS is a practical fit for Docker-based sites, internal tools, and small client deployments.

For teams that need steadier resources or more headroom for several services, see dedicated server hosting as well.

FAQ

Does Watchtower update every container automatically?
Not with the setup above. It only updates containers that carry the Watchtower label, which is safer for production.

Can I use this on a fresh Hostperl VPS?
Yes. Start with the OS check, Docker install, firewall rules, and a labeled test container before you attach real services.

Will this work behind Nginx?
Yes. Watchtower updates containers underneath Nginx, so your reverse proxy usually stays in place. Just keep your app health checks in mind.

How do I stop an unwanted update?
Pin the working image tag in your Compose file, redeploy that tag, and confirm the container returns to the previous version.

Should I use it for every workload?
No. Use it for low-risk services first. For customer-facing apps, keep backups, a rollback tag, and a short maintenance window plan.