Linux Server Setup - Production-Ready Configuration

Linux Server Setup - Production-Ready Configuration

This guide walks through setting up Update-Watcher on a Linux production server with proper security boundaries. The result is a dedicated system user with minimal permissions that runs automated update checks on a daily schedule.

Step 1: Create a Dedicated System User

Create a system user with no login shell and a home directory for storing state:

Terminal
sudo useradd -r -s /usr/sbin/nologin -m -d /var/lib/update-watcher update-watcher
FlagPurpose
-rCreate a system account (low UID, no aging).
-s /usr/sbin/nologinPrevent interactive login.
-m -d /var/lib/update-watcherCreate a home directory for the user.

Step 2: Configuration Directory and Permissions

Create the configuration directory and set ownership:

Terminal
sudo mkdir -p /etc/update-watcher
sudo chown update-watcher:update-watcher /etc/update-watcher
sudo chmod 755 /etc/update-watcher

If a configuration file already exists, move it and set restrictive permissions:

Terminal
sudo mv config.yaml /etc/update-watcher/config.yaml
sudo chown update-watcher:update-watcher /etc/update-watcher/config.yaml
sudo chmod 600 /etc/update-watcher/config.yaml
The 600 permission ensures only the update-watcher user can read the file, which is important because it may contain webhook URLs, API tokens, and SMTP credentials.

Step 3: Log File Setup (Optional)

If you want persistent logging beyond cron mail:

Terminal
sudo touch /var/log/update-watcher.log
sudo chown update-watcher:update-watcher /var/log/update-watcher.log
sudo chmod 644 /var/log/update-watcher.log

Then configure the log file path in your config:

config.yaml
settings:
  log_file: "/var/log/update-watcher.log"

Step 4: Sudoers Configuration

Most system package manager checkers need sudo to refresh package lists. Grant the update-watcher user passwordless sudo for only the specific commands it needs.

Create a sudoers drop-in file:

Terminal
sudo visudo -f /etc/sudoers.d/update-watcher

Add the rules for your distribution’s package manager. Only include the section for the package manager(s) you use.

APT (Debian, Ubuntu)

/etc/sudoers.d/update-watcher
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/apt-get update

DNF (Fedora, RHEL, Rocky, AlmaLinux)

/etc/sudoers.d/update-watcher
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/dnf check-update
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/dnf updateinfo

Pacman (Arch Linux, Manjaro)

/etc/sudoers.d/update-watcher
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/pacman -Sy

Zypper (openSUSE, SLES)

/etc/sudoers.d/update-watcher
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/zypper refresh
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/zypper list-updates
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/zypper list-patches

APK (Alpine Linux)

/etc/sudoers.d/update-watcher
update-watcher ALL=(ALL) NOPASSWD: /sbin/apk update

Multiple Package Managers

If you monitor multiple package managers on the same host (uncommon but possible), combine the rules in a single file:

/etc/sudoers.d/update-watcher
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/apt-get update
update-watcher ALL=(ALL) NOPASSWD: /usr/bin/snap refresh --list
Always validate the sudoers file syntax after editing to avoid locking yourself out of sudo access.
Terminal
sudo visudo -c -f /etc/sudoers.d/update-watcher

Step 5: Docker Access

If you are using the Docker checker to monitor running containers, add the update-watcher user to the docker group:

Terminal
sudo usermod -aG docker update-watcher
This grants access to the Docker socket (/var/run/docker.sock) without requiring sudo. The Docker checker queries image digests to detect newer versions but never pulls images or modifies containers.

Step 6: WordPress and Web Project Access

If you are monitoring WordPress sites or web projects, the update-watcher user needs read access to the project directories. Add the user to the web server group:

Terminal
sudo usermod -aG www-data update-watcher

On some distributions, the web server group may be nginx, apache, or http instead of www-data. Check with:

Terminal
stat -c '%G' /var/www

Ensure the project directories and wp-config.php are group-readable:

Terminal
sudo chmod -R g+r /var/www/mysite
Group membership is sufficient for WordPress and web project checkers — no sudo or sudoers configuration is needed. The checkers only perform read-only operations (checking for updates).

Step 7: Cron Scheduling

Install a cron job under the dedicated user:

Terminal
sudo crontab -u update-watcher -e

Add the following entry:

Crontab
# update-watcher: daily update check
0 7 * * * /usr/local/bin/update-watcher run --quiet --as-service-user

Alternatively, use the built-in cron management while running as the service user:

Terminal
sudo -u update-watcher update-watcher install-cron

For more scheduling options including twice-daily runs and logging, see Cron Scheduling.

Summary Table

ResourcePathPermissionsOwner
Binary/usr/local/bin/update-watcher755root:root
Config directory/etc/update-watcher/755update-watcher:update-watcher
Config file/etc/update-watcher/config.yaml600update-watcher:update-watcher
Log file/var/log/update-watcher.log644update-watcher:update-watcher
Home directory/var/lib/update-watcher/700update-watcher:update-watcher
Sudoers drop-in/etc/sudoers.d/update-watcher440root:root

Security Notes

Review these security properties to ensure your deployment meets your requirements.
  • No inbound ports – Update-Watcher does not listen on any ports. All network activity is outbound HTTPS to notification services and the GitHub API.
  • Read-only operations – Checkers never install updates, pull Docker images, or modify your system. They only query for available updates.
  • Minimal sudo – The sudoers configuration grants access only to the specific package manager commands needed for refreshing package lists.
  • Secret protection – The config file (which may contain webhook URLs, API tokens, and credentials) is readable only by the update-watcher user (chmod 600).

Verifying the Setup

💡
Run these verification commands after completing all setup steps to confirm everything is working correctly.

Run a test check as the service user to verify everything works:

Terminal
sudo -u update-watcher update-watcher run --verbose --notify=false

Check each component:

Terminal
# Verify config is readable
sudo -u update-watcher update-watcher validate

# Verify status
sudo -u update-watcher update-watcher status

# Verify cron is installed
sudo crontab -u update-watcher -l

Related