ScreenshotNeo

BlogHow-to

How to Run Urlwatch in Docker and Persist Its Configuration

Run urlwatch as a scheduled Docker service and keep its jobs, settings, hooks, and cache in a host directory that survives container updates.

By the ScreenshotNeo team4 October 20267 min read

To run urlwatch in Docker and preserve its configuration, mount a host directory at /data/urlwatch. The mjaschen/urlwatch-docker image expects its working files there. With Docker Compose, the essential mapping is ./data:/data/urlwatch; keep that host-side data directory when recreating or updating the container. It holds the job list, global settings, hooks, and cache.

The walkthrough below follows the paths and commands documented by the urlwatch Docker project. Its documented default schedule runs every 15 minutes. Image tags, paths, and available urlwatch settings depend on the selected image version, so check that project’s README and use configuration documentation matching the urlwatch version in the image.

1. Create the persistent working directory

From a new project directory, create a host-side folder for urlwatch’s files:

mkdir -p urlwatch-docker/data
cd urlwatch-docker

Put the job definitions in data/urls.yaml. Start from the Docker project’s example file and consult urlwatch’s Jobs documentation for supported job syntax. The host directory is the durable copy: Docker can remove and recreate the container while these files remain on the host.

2. Configure urlwatch and a reporter

Copy the project’s template configuration and edit it before starting the scheduled service:

cp data/urlwatch.template.yaml data/urlwatch.yaml

Configure at least one reporter if you want notifications. Reporter-specific settings belong under the report key in the global configuration. Treat mail credentials and other secrets as sensitive: keep real credentials out of public repositories and restrict access to the host files that contain them.

The global configuration controls general behavior and reporting; individual job definitions live separately in urls.yaml. In the urlwatch 2.29 configuration manual, the defaults report new pages and errors but do not report unchanged pages. Check the manual for the version in your container before relying on a setting or default. You can edit a supported installation’s configuration with urlwatch --edit-config; for the container workflow, editing the mounted host-side data/urlwatch.yaml keeps the change persistent.

3. Run urlwatch with Docker Compose

Use the Compose file from the Docker project’s repository. Its key persistence setting is the bind mount from the project directory into the path used by the image:

services:
  urlwatch:
    image: ghcr.io/mjaschen/urlwatch
    volumes:
      - ./data:/data/urlwatch
      - /etc/localtime:/etc/localtime:ro

The image reference above follows the project’s documented example. The retrieved documentation does not establish an immutable tag or digest; check the project for its current image guidance before pinning a production deployment. Do not combine this image’s /data/urlwatch path with paths documented for a different community image.

Start the service and follow its logs:

docker compose up -d
docker compose logs -f

Stop the service with:

docker compose down

Compose manages the container lifecycle. The files under ./data remain on the host after stopping or recreating the service, as long as you do not delete that directory.

4. Run it directly with Docker instead

For a one-time interactive run, the project documents a bind mount and terminal allocation:

docker run --rm --interactive --tty \
  --volume "$(pwd)/data":/data/urlwatch \
  --volume /etc/localtime:/etc/localtime:ro \
  ghcr.io/mjaschen/urlwatch

For a background container that restarts unless explicitly stopped, use the documented restart policy and name:

docker run --detach \
  --restart unless-stopped \
  --name urlwatch \
  --volume "$(pwd)/data":/data/urlwatch \
  --volume /etc/localtime:/etc/localtime:ro \
  ghcr.io/mjaschen/urlwatch

Follow its output with docker logs --follow urlwatch. Both launch approaches mount the same host data directory, so the job definitions and runtime files remain available across container replacement. Compose is convenient when you want a project-level up, logs, and down workflow; direct docker run is concise for a single container. The source does not establish that either approach is faster or inherently safer.

5. Preserve all files the scheduled command uses

The Docker project’s scheduled command refers to four files in /data/urlwatch:

  • urls.yaml: monitored jobs.
  • urlwatch.yaml: global settings and reporters.
  • hooks.py: optional hooks.
  • cache.db: urlwatch cache.

Keep the entire mounted working directory, not only the YAML files. Persisting the folder keeps the job list, hooks, configuration, and cache together when the container is recreated. Back up this host-side directory according to your normal data-retention needs, and verify that the Docker process can read and write it.

6. Change the schedule if necessary

The image’s documented default schedule runs every 15 minutes. To run hourly, the project shows this cron entry:

0 * * * * cd /data/urlwatch && urlwatch --verbose --urls urls.yaml --config urlwatch.yaml --hooks hooks.py --cache cache.db

The modified crontab must be mounted into the container. Use the mount location and setup supported by the selected image, following the Docker project’s instructions; the cited README does not make this a universal urlwatch container convention. Confirm the resulting logs show the expected command and interval.

Configuration choices and tradeoffs

Choice What it controls Practical note
Compose or direct Docker How you start, inspect, and stop the container Both documented methods bind-mount the host data directory.
urls.yaml Which pages or other supported jobs urlwatch monitors Use the project’s example and the urlwatch Jobs documentation.
urlwatch.yaml General behavior and reporter configuration Reporter settings are under report; defaults can vary by version.
hooks.py Optional hooks loaded by the scheduled command Keep it in the mounted directory if your command references it.
Schedule How often the image runs urlwatch The image documents a 15-minute default and a mounted-crontab approach for hourly runs.
Host time mapping Container access to the host’s local time configuration The examples mount /etc/localtime read-only.

For job-wide defaults, urlwatch configuration supports job_defaults, including defaults for all jobs or selected job kinds such as URL, shell, and browser jobs. Consult the manual for the version in the container when adding or changing settings.

Reliability, performance, and operating cost

Reliability: the bind mount protects working files from container replacement, but it does not back them up. Back up the host directory, preserve permissions, and retain the same mounted path when updating the service. A container restart policy helps restart a stopped background container; it does not protect against host failure or a deleted data directory.

Performance: the cited Docker README documents a run interval, not performance benchmarks. The practical load depends on the monitored jobs and schedule. If you adjust the schedule, consider the number of jobs and the load your checks place on their target sites.

Cost: the cited sources provide no hosting price or resource estimate. Docker itself does not make the host free: account for whatever machine or server runs it, along with any notification service you configure. A local machine must be running for scheduled checks to happen.

Troubleshooting

Symptom Likely cause Fix
Jobs or settings disappear after recreating the container The host directory was not mounted, or you mounted a different host path. Check that the service maps ./data:/data/urlwatch and that you are editing the corresponding host-side files.
The container cannot find urls.yaml or configuration Files are missing, named differently, or stored outside the mounted directory. Confirm the files are under the host data directory and that the image uses /data/urlwatch.
Changes to configuration have no effect You edited a file outside the bind mount, or the setting is not supported by the included urlwatch version. Edit the mounted file and check the configuration manual matching the image’s urlwatch version.
Reporter notifications do not arrive Reporter settings may be missing, invalid, or under the wrong configuration key. Check the reporter configuration under report, verify its credentials and destination, and inspect container logs for errors.
Permission errors writing cache or other files The container process cannot write to the host-mounted directory. Inspect ownership and permissions on the host data directory and grant the container process the required access.
The hourly schedule does not take effect The modified crontab was not mounted or the container is still using its default schedule. Follow the image project’s instructions for mounting the changed crontab, then inspect logs to confirm the command and cadence.
Local timestamps differ from expectation The host time file is not mounted or the process uses a different timezone configuration. Check the read-only /etc/localtime mount shown in the project examples and the host’s timezone.
Commands fail after switching Docker images Another image may use different paths, defaults, or an included urlwatch version. Use that image’s own documentation and configuration manual; do not assume /data/urlwatch applies to it.

Or skip the browser setup

Urlwatch is for scheduled change monitoring. If you also need a rendered screenshot of a page, ScreenshotNeo is a website screenshot API and MCP server for developers. A single GET request returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for the request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say which verdict applied and whether the request was billed. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo and get 1,000 free screenshots a month, no card required.

FAQ

Does Docker Compose preserve data when I run down?

The documented bind mount stores the working files in the host’s ./data directory. Keep that directory to retain them when stopping or recreating the container.

Where do I add monitored URLs?

The Docker project’s setup uses data/urls.yaml. See its example and urlwatch’s Jobs documentation for the job format.

Can I use a different urlwatch Docker image?

Yes, but paths and included versions may differ. Follow that image’s own documentation and match settings to its urlwatch version.

What is the default check interval?

The cited mjaschen/urlwatch-docker README documents a 15-minute default for that image. It is not a guarantee for every urlwatch image or deployment.