Running in Docker
The official image is runwisp/runwisp, for amd64 and arm64. It contains
the same release binary as the install script and the npm package.
Quick start
Section titled “Quick start”services: runwisp: image: runwisp/runwisp:latest restart: unless-stopped ports: - "9477:9477" environment: - RUNWISP_PASSWORD=change-me volumes: - ./runwisp.toml:/etc/runwisp/runwisp.toml:ro - runwisp-data:/var/lib/runwisp
volumes: runwisp-data:Run docker compose up -d, open http://localhost:9477, and log in with the
password. The same with docker run:
docker run -d --name runwisp \ -p 9477:9477 \ -e RUNWISP_PASSWORD=change-me \ -v ./runwisp.toml:/etc/runwisp/runwisp.toml:ro \ -v runwisp-data:/var/lib/runwisp \ runwisp/runwisp:latestImage variants and tags
Section titled “Image variants and tags”| Base | Tags | Notes |
|---|---|---|
| Alpine (default) | latest, X.Y.Z, X.Y, X, and the same four with -alpine |
Smaller; busybox and apk |
| Debian slim | latest-debian, X.Y.Z-debian, X.Y-debian, X-debian |
glibc and apt-get |
| Alpine + Docker | latest-docker, and -alpine-docker / X.Y.Z / X.Y / X variants |
Adds a Docker CLI + Compose plugin, ~100MB more |
| Debian + Docker | latest-debian-docker, X.Y.Z-debian-docker, X.Y-debian-docker, X-debian-docker |
Same, on the Debian base |
- Pick Debian if your tasks need glibc or a Debian-only package, otherwise Alpine.
- Pick a
-dockertag only if your tasks rundockerthemselves (see Docker tasks). X.Y.Zis the only tag that never changes.X.Y,X, andlatestmove with new releases. Breaking changes only ship in a new major version, so1is safe to follow.- A prerelease gets only its exact
X.Y.Ztag, solatestnever points at a release candidate.
Required settings
Section titled “Required settings”The entrypoint refuses to start the daemon unless both of these are set, and exits 1 with a message saying what’s missing.
An auth setting. Set either RUNWISP_PASSWORD or RUNWISP_AUTH=off (no
login, trusted networks only). Without one, the daemon would generate a new
random password on every start, which nobody could read from a container. See
Authentication.
A config file mounted at /etc/runwisp/runwisp.toml. Read-only is fine;
RunWisp never writes it. There is no scaffold prompt in a container.
Both checks apply to anything that starts a daemon: daemon, station,
restart, demo, bare runwisp, and any subcommand the entrypoint doesn’t
know. One-shot commands such as validate, run, list, status, reload,
import, and tui skip them:
docker run --rm -v ./runwisp.toml:/etc/runwisp/runwisp.toml:ro \ runwisp/runwisp:latest runwisp validateEnvironment defaults
Section titled “Environment defaults”The image sets these. Override any of them with -e.
| Variable | Image default | Purpose |
|---|---|---|
RUNWISP_CONFIG |
/etc/runwisp/runwisp.toml |
Where the config is read from. |
RUNWISP_DATA |
/var/lib/runwisp |
SQLite database, run logs, and the control socket. |
RUNWISP_HOST |
0.0.0.0 |
Listen on all interfaces, so port mapping works. |
RUNWISP_TLS |
unset (daemon defaults to off) |
See Plain HTTP by default. |
RUNWISP_LOG_FORMAT |
text |
Readable docker logs. Set json if a log collector parses them. |
Use -e RUNWISP_DATA=… rather than the --data flag. The healthcheck reads
only the environment, so a flag makes it look in the wrong place. The
entrypoint warns if you pass --data or --socket.
Volumes
Section titled “Volumes”/etc/runwisp/runwisp.toml: your config, read-only. It must be a file. To split config across files, mount a directory at/etc/runwispwithrunwisp.tomlinside, and load the rest withinclude./var/lib/runwisp: the database and run logs. Without a volume here, every container recreate deletes your run history and logs you out.
Tasks run inside this container
Section titled “Tasks run inside this container”When a task runs, RunWisp runs its run command with /bin/sh -c inside the
RunWisp container. So every tool your tasks call must be in the image. The
image has bash, tzdata, and ca-certificates, and nothing else: no curl,
no git, no database clients, no Docker CLI. Add what you need with a
Dockerfile, or run the task in another container. See
Docker tasks.
Healthcheck
Section titled “Healthcheck”The image has a HEALTHCHECK that runs runwisp status, so docker ps and
compose’s depends_on: condition: service_healthy work without setup.
It talks to the control socket, which it finds from RUNWISP_DATA or
RUNWISP_SOCKET. A --data flag on the command line isn’t visible to it, and
the container then reports unhealthy although the daemon is fine. Use the
environment variables, or --no-healthcheck to supply your own.
Plain HTTP by default
Section titled “Plain HTTP by default”The daemon serves plain HTTP. Either:
- put a reverse proxy in front for TLS and set
RUNWISP_TRUSTED_PROXIESto its CIDR, so session cookies are still markedSecure(trusted_proxies); or - set
-e RUNWISP_TLS=autoand RunWisp serves HTTPS with a self-signed certificate.
Timezone
Section titled “Timezone”The timezone database is built into the binary, so
[daemon] timezone works on both bases
without extra packages. The image also installs tzdata for your tasks, so
date, PHP, Python, and similar tools get real zone data.
To use the host’s local time in tasks, set -e TZ=Europe/Helsinki or mount
/etc/localtime:/etc/localtime:ro.
Running as non-root
Section titled “Running as non-root”The image runs as root, because running a task as another
user needs root. If no task sets user, you
can run the container as another UID with user: in compose (or --user).
That UID must be able to write the /var/lib/runwisp volume; the entrypoint
tells you if it can’t.
Operating the container
Section titled “Operating the container”The CLI inside the container talks to the daemon over the control socket and needs no password:
docker exec runwisp runwisp statusdocker exec runwisp runwisp listdocker exec runwisp runwisp run helloAfter editing runwisp.toml on the host, run
docker exec runwisp runwisp reload (see Reload).