Skip to Content
Docker

Docker

The public qaws image is:

ghcr.io/nulldoubt/qaws

The image is multi-architecture for linux/amd64 and linux/arm64. It uses a source-build stage and a scratch runtime image.

Tags

Use an explicit version in production:

ghcr.io/nulldoubt/qaws:0.2.7

Use latest only when you intentionally want the newest pushed release:

ghcr.io/nulldoubt/qaws:latest

Run the sample site

The image includes a sample /public directory:

docker run --rm -p 8080:80 ghcr.io/nulldoubt/qaws:0.2.7

Test it:

curl -i http://127.0.0.1:8080/

Serve your own files

Mount your local public directory over /public:

docker run --rm \ -p 8080:80 \ -v "$PWD/public:/public:ro" \ ghcr.io/nulldoubt/qaws:0.2.7

The container workdir is /, so the default ./public resolves to /public.

Pass CLI flags

Arguments after the image name are passed to qaws:

docker run --rm \ -p 18086:18086 \ -v "$PWD/public:/public:ro" \ ghcr.io/nulldoubt/qaws:0.2.7 \ --host 0.0.0.0 --port 18086 --serve /public --no-access-log

Mount a config file

docker run --rm \ -p 8080:80 \ -v "$PWD/public:/public:ro" \ -v "$PWD/qaws.json:/qaws.json:ro" \ ghcr.io/nulldoubt/qaws:0.2.7 \ --config /qaws.json

Example config:

qaws.json
{ "listen": { "host": "0.0.0.0", "port": 80 }, "serve": "/public", "logging": { "format": "plain", "access": true }, "http": { "keep_alive": true, "sendfile": true, "etag": true, "range_requests": true, "precompressed": true } }

qaws documentation image

The qaws documentation repository provides a separate image that builds the static Next.js/Nextra export and serves it with qaws 0.2.7:

ghcr.io/nulldoubt/qaws-docs:0.2.7

Run it locally:

docker run --rm -p 8080:80 ghcr.io/nulldoubt/qaws-docs:0.2.7

The final image contains only qaws and the generated /public documentation. It does not include Bun, Node.js, source files, TLS termination, or deployment routing.

Docker Compose

compose.yaml
services: qaws: image: ghcr.io/nulldoubt/qaws:0.2.7 restart: unless-stopped ports: - "8080:80" volumes: - ./public:/public:ro - ./qaws.json:/qaws.json:ro command: ["--config", "/qaws.json"]

Start it:

docker compose up -d docker compose logs -f qaws

Stop it:

docker compose down

Logs

Container logs go to stderr/stdout by default:

docker logs -f qaws

For quieter production containers, disable access logs:

docker run --rm -p 8080:80 ghcr.io/nulldoubt/qaws:0.2.7 --no-access-log

Or use JSON-lines logs:

docker run --rm -p 8080:80 ghcr.io/nulldoubt/qaws:0.2.7 --log-format jsonl

Common Docker mistakes

  • Mounting the wrong directory: qaws needs the directory that contains index.html, not its parent.
  • Publishing the wrong port: the default container port is 80.
  • Binding to localhost inside the container: use --host 0.0.0.0 when overriding the host.
  • Relying on -d inside Docker: let Docker manage the process instead of qaws daemon mode.

Inspect the image

docker buildx imagetools inspect ghcr.io/nulldoubt/qaws:0.2.7
qaws docs. Built for static hosting.