Skip to main content
Background Image
  1. Posts/

A Summary of Pitfalls Encountered When Deploying Warpgate as a Rootless Container with Quadlet

··523 words·3 mins· loading · loading ·
yuzjing
Author
yuzjing
Table of Contents

This post documents the pitfalls encountered while deploying Warpgate as a rootless container using Podman.

Target Environment:

  • Container Engine: Podman (in rootless mode)
  • Service Management: Systemd / Quadlet
  • Reverse Proxy: Caddy (also as a rootless container)
  • Network: Caddy and Warpgate are in the same custom Podman network.

Pitfall 1: Service Fails to Start, Citing Missing warpgate.yaml Configuration File
#

This was the first obstacle during deployment. After starting the service with systemctl, the logs repeatedly showed that Warpgate was exiting because it couldn’t find the /data/warpgate.yaml configuration file.

Solution: Execute the one-time setup command using podman run
#

Warpgate is designed to generate its configuration file via an interactive setup command on its first run, rather than having it created manually. Since Quadlet is used for managing long-running services, this one-time setup task must be completed manually first using podman run.

  1. Execute the setup command: This command starts a temporary container, runs the interactive setup wizard, and stores the generated configuration in a Podman volume.

    1podman run -it --rm --name warpgate-setup -v warpgate-data:/data --network=caddy ghcr.io/warp-tech/warpgate:latest setup
    
    • -it: Enables an interactive terminal to answer the setup wizard’s questions.
    • --rm: Automatically removes this temporary container after the command finishes.
    • -v warpgate-data:/data: Uses a named volume warpgate-data to persist the configuration. This same volume will be used by the Quadlet service later.
  2. Run the service with Quadlet: After the setup is complete, the warpgate-data volume now contains the configuration file. The service started by systemctl can now find the configuration and run normally.


Pitfall 2: Service Runs Normally, but Caddy Reverse Proxy Reports a 502 Bad Gateway
#

The Warpgate container started successfully and was listening on its port, but when accessed through the Caddy reverse proxy, the browser showed a 502 error.

Solution: Change the Caddy Reverse Proxy Protocol from HTTP to HTTPS
#

After investigation, the root of the problem was that Warpgate’s internal port 8888 was listening for HTTPS traffic, not standard HTTP. This was likely because, during the interactive setup, a URL starting with https:// was entered when prompted for the Public URL, causing Warpgate to automatically enable internal TLS.

Caddy defaults to using HTTP to connect to backends, so the connection was being rejected by Warpgate, resulting in the 502 error.

The solution was to modify the Caddyfile to use HTTPS when connecting to Warpgate and to ignore verification errors from its internal self-signed certificate.

 1<your-domain> {
 2    # ... other configurations ...
 3
 4    # Reverse proxy to warpgate using https and skip TLS verification for internal traffic
 5    reverse_proxy https://warpgate:8888 {
 6        transport http {
 7            tls_insecure_skip_verify
 8        }
 9    }
10}
  • https://warpgate:8888: Tells Caddy that the upstream service is HTTPS.
  • tls_insecure_skip_verify: Tells Caddy to ignore certificate verification errors from the upstream, which is standard practice when proxying to internal services that use self-signed certificates.

Final Configuration Summary
#

~/.config/containers/systemd/warpgate.container
#

 1[Unit]
 2Description=Warpgate Secure Access Gateway
 3
 4
 5[Container]
 6ContainerName=warpgate
 7Image=ghcr.io/warp-tech/warpgate:latest
 8AutoUpdate=image
 9PodmanArgs=--network=caddy
10Volume=warpgate-data:/data
11
12[Service]
13Restart=on-failure
14
15[Install]
16WantedBy=default.target

Relevant configuration in Caddyfile
#

 1<your-domain> {
 2
 3
 4    encode zstd gzip
 5
 6    reverse_proxy https://warpgate:8888 {
 7        transport http {
 8            tls_insecure_skip_verify
 9        }
10    }
11}