Operator Quickstart
Install pw-launcher on a Docker host and run your first deploy in under ten steps.
This guide takes you from a bare Docker host to a running pw-launcher instance and a successful first deploy. It assumes you have network access to registry.podwarden.com and a PodWarden instance already running on the same host.
Prerequisites
- Docker Engine 24+ with the Compose plugin. Confirm with
docker compose version— if it prints a version number, you are good. - Registry read credentials for
registry.podwarden.com. Obtain the username and token from your password manager or team credentials store. - A running PodWarden instance on the same host. pw-launcher needs its compose file path and database container name to manage deployments.
Steps
1. Clone the launcher repo
git clone https://git.mediablade.net/podwarden/pw-launcher.git ~/pw-launcher
cd ~/pw-launcher/infraThis gives you deploy.sh, docker-compose.yml, and .env.example under infra/.
2. Create and secure the environment file
cp .env.example .env
chmod 600 .envOpen .env in your editor. You need to fill in four values before the launcher will start: the image tag to run (PW_TAG), the registry credentials, the session secret, and the basic-auth credentials. The following steps generate the secrets.
3. Set the image tag
In .env, set PW_TAG to the CalVer release you want to run, for example:
PW_TAG=v2026.04.24.2Use the latest release tag from the registry. You can list available tags at any time from any system with Docker installed:
docker run --rm curlimages/curl -s \
https://registry.podwarden.com/v2/podwarden/pw-launcher-api/tags/list4. Generate the basic-auth password hash
pw-launcher protects all API routes with HTTP Basic auth. Generate a bcrypt hash of your chosen password:
docker run --rm httpd:2.4-alpine htpasswd -nbB -C 12 operator 'your-password-here' \
| cut -d: -f2The output is a string beginning with $2y$12$.... In .env, set:
PW_BASIC_AUTH_USER=operator
PW_BASIC_AUTH_PASSWORD_HASH='$2y$12$...'Wrap the hash value in single quotes in .env. The $ characters in a bcrypt hash will be expanded by the shell if the value is unquoted.
5. Generate the session secret
openssl rand -base64 32Paste the output after PW_SESSION_SECRET= in .env.
6. Configure your stack
Copy the example stack config and edit it for your environment:
mkdir -p config
cp services.yaml.example config/services.yamlOpen config/services.yaml. The file lists each stack (deployment target) the launcher will manage. At minimum you need:
name— a short slug for the stack (for example,podwarden)registry_repo— the image repository without the registry prefix (for example,podwarden/podwarden-api)compose_file— the absolute path to the Compose file on this hostcompose_service— the service name within that Compose file to restarthealth_check.url— the HTTP URL pw-launcher will poll after a deploy to confirm the service is healthybackup.type— set topostgresif the stack has a database (required for full rollback), ornone
A minimal entry for a PodWarden stack looks like:
stacks:
- name: podwarden
display_name: PodWarden Core
registry_repo: podwarden/podwarden-api
compose_file: /opt/podwarden/docker-compose.yml
compose_service: podwarden-api
health_check:
url: http://localhost:8000/health
timeout_s: 30
backup:
type: postgres
container: podwarden-db
database: podwarden
user: podwarden7. Log into the registry and deploy
# Log in once — credentials are cached by Docker
docker login registry.podwarden.com
# Start pw-launcher
./deploy.shdeploy.sh pulls the pw-launcher-api and pw-launcher-ui images, starts both containers, and waits for the health-check to pass. It is idempotent: running it again with the same PW_TAG is a no-op; running it with a new tag rolls both images.
Expected output ends with something like:
pw-launcher-api is healthy
pw-launcher-ui is healthy
pw-launcher is running at http://localhost:80808. Verify the API is responding
curl -fsS http://localhost:8080/api/health \
-u "operator:your-password-here"Expected response: {"status":"ok"}. If you receive a 401, check that PW_BASIC_AUTH_USER and PW_BASIC_AUTH_PASSWORD_HASH in .env match the credentials you are using here.
9. Open the UI and run your first deploy
Open http://<your-server-ip>:8080 in a browser. You will be prompted for your basic-auth credentials. After signing in you land on the Builds tab.
To run your first deploy:
- Find the build you want to deploy in the Builds list. Look for the row tagged
:productionor a specific CalVer tag. - Click the expand arrow on that row.
- Click Deploy.
- Watch the six-step progress sequence complete in the browser. When the status reads DEPLOYED, the new image is running and the health-check passed.
The Timeline tab now shows this deploy as your first history entry.
Optional: run under systemd
If you want pw-launcher to start automatically on boot and restart after crashes, install the included systemd unit:
sudo cp systemd/pw-launcher.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now pw-launchersystemctl status pw-launcher confirms it is running.
Next steps
- UI Walkthrough — understand every element in the Builds, Timeline, and Settings tabs
- What is pw-launcher? — the full concept page with rollback details