Get started

In five minutes you will have a server, a database, a console and about three hundred simulated devices updating themselves, with nothing to configure and nothing to buy.

What Qawk is, in one paragraph

Qawk hands software to devices over the air. Devices call in on a schedule and ask "anything for me?"; Qawk answers with a link to download and install, and the device reports back how it went. That much is Eclipse hawkBit, whose protocols Qawk speaks exactly, so existing devices and tools work unchanged. On top of it Qawk adds the parts a real fleet needs: channels a release moves through under conditions, centres so you move a place rather than a list of machines, and an orchestrator for machines that only make sense updated together.

Try it in five minutes

You need docker, python3 and curl, and ports 8080 and 8090 free. Nothing is installed on your machine outside Docker, and the demo keeps no data.

git clone https://github.com/padovanl/qawk.git
cd qawk
demo/start.sh

That builds two images, starts PostgreSQL, the server and the console, loads sample data and starts simulated devices. When it settles, open http://localhost:8090 and sign in as admin / changeme.

What you just started

demo/start.sh seed     # load the sample data again
demo/start.sh down     # stop and remove everything
Note

Everything is configurable. QAWK_ADMIN_PASSWORD, QAWK_PORT, CONSOLE_PORT, PROD_DEVICES, SYSTEMS, USERS_FILE. The same thing with docker compose is in demo/compose.yml.

Run it yourself, with the smallest configuration there is

The demo above is a toy with sample data in it. This is the real thing: a server, a database and a console, and nothing else. Two commands' worth of configuration — a database URL and an administrator password.

A. From Docker Hub

Nothing to build. Two images, one network, one command each.

docker pull padovanl/qawk:0.1.0            # the server, with qawk-sim and qawk-load
docker pull padovanl/qawk-console:0.1.0    # the console
docker network create qawk

docker run -d --name qawk-db --network qawk --restart unless-stopped \
  -v qawk-db:/var/lib/postgresql/data \
  -e POSTGRES_USER=qawk -e POSTGRES_PASSWORD='db-secret' -e POSTGRES_DB=qawk \
  postgres:16-alpine

docker run -d --name qawk --network qawk --restart unless-stopped -p 8080:8080 \
  -v qawk-artifacts:/var/lib/qawk \
  -e QAWK_DATABASE_URL='postgres://qawk:db-secret@qawk-db:5432/qawk?sslmode=disable' \
  -e QAWK_ADMIN_PASSWORD='a-long-admin-password' \
  padovanl/qawk:0.1.0

docker run -d --name qawk-console --network qawk --restart unless-stopped -p 8090:8090 \
  -e HB_URL=http://qawk:8080 \
  padovanl/qawk-console:0.1.0

Open http://localhost:8090 and sign in as admin with the password you just set. On its first start Qawk creates its own schema, the built-in roles and hawkBit's default types — there is no migration step to run and no schema to load.

Careful

Set QAWK_ADMIN_PASSWORD. Without it the administrator's password is admin. That administrator is never stored in the database: it always works, which is how a new server is set up and how a lost password is fixed — and why the password must not be the default on anything reachable.

B. Built from this repository

You need only Docker. The server's image builds its own Go toolchain stage, and the console has nothing to install at all — no npm, no bundler, no build step.

git clone https://github.com/padovanl/qawk.git
cd qawk

docker build -t qawk:local server/
docker build -t qawk-console:local console/

Then run exactly the three docker run commands above, with qawk:local and qawk-console:local in place of the Docker Hub names.

To publish under your own namespace, give the server its version — it reports it at /qawk/v1/info and on the console's About page — and push both with the same tag:

V=0.1.0
docker build --build-arg VERSION=$V -t <you>/qawk:$V server/
docker build -t <you>/qawk-console:$V console/
docker push <you>/qawk:$V
docker push <you>/qawk-console:$V

C. With docker compose

A compose.yml with the same three services and nothing else:

name: qawk

services:
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes: ["db:/var/lib/postgresql/data"]
    environment:
      POSTGRES_USER: qawk
      POSTGRES_PASSWORD: db-secret
      POSTGRES_DB: qawk

  server:
    image: padovanl/qawk:0.1.0
    restart: unless-stopped
    ports: ["8080:8080"]
    volumes: ["artifacts:/var/lib/qawk"]
    environment:
      QAWK_DATABASE_URL: postgres://qawk:db-secret@db:5432/qawk?sslmode=disable
      QAWK_ADMIN_PASSWORD: a-long-admin-password
    depends_on: [db]

  console:
    image: padovanl/qawk-console:0.1.0
    restart: unless-stopped
    ports: ["8090:8090"]
    environment:
      HB_URL: http://server:8080
    depends_on: [server]

volumes: { db: {}, artifacts: {} }
docker compose up -d

The demo's own compose file, with the sample data and the simulated devices wired in, is demo/compose.yml in the repository.

D. Without Docker at all

The server is one static binary and the console is a Python script. If you have Go 1.25 and a PostgreSQL to point at:

cd server && go build -o qawk ./cmd/qawk
QAWK_DATABASE_URL='postgres://qawk:qawk@localhost:5432/qawk?sslmode=disable' \
QAWK_ADMIN_PASSWORD='a-long-admin-password' ./qawk

# in another terminal
python3 console/serve.py --port 8090 --hawkbit http://localhost:8080

The two things to back up

The database and the artifact directory (/var/lib/qawk in the image). Everything else is rebuilt from them. Full configuration, TLS, Kubernetes and upgrades are in Installing the server.

Your first update

Four things worth doing, in order. Each takes a minute and each shows you one of the ideas Qawk is built on.

  1. Watch a release reach a channel.
    Open Fleets. dev is running app:1.1.0 and its bar is filling as the simulated devices take it. Click dev to open its drawer: the members, what each runs, what each was given.
  2. Promote it to beta.
    Still in Fleets, press promote on beta. Qawk shows you the gate first — a ✓ or a ✗ per condition — and refuses if it is closed, telling you exactly which line failed. When it opens, promote, and watch beta fill in waves.
  3. Break something on purpose.
    Give dev the release app-broken:1.3.0. The simulated devices fail anything named broken. Within a minute the release halts by itself: failures passed dev's error threshold, and no further device is sent it. Press resume and the failures already seen stop counting — only new ones can halt it again.
  4. Update sixteen systems as sixteen wholes.
    Open Systems and deploy the manifest device-system-2.0. Each system's terminals go first, its lane computer second — the manifest's order — and one system that fails takes itself back to what it ran before while the other fifteen carry on. That is the orchestrator, and it is the part hawkBit has no answer for.

There is no hardware anywhere in this

Every device above is qawk-sim: a program that registers, reports the attributes a real device would, polls, takes what it is given, waits a random while and says how it went. It is not a mock inside the server — it speaks the real device API over the real network, so what you are watching is the real thing with the hardware replaced. All three hundred of them live in one container: there is no operating system and no application inside a simulated device, and it simulates only the installation and the rollback — it never downloads the artifact, it sleeps instead of installing, and a failed one simply says it rolled back. Everything the server decides is real; what is real and what is pretended is set out in full under Connecting devices.

You can point it at any Qawk server, not only the demo's:

# 50 devices reporting ring=lab, polling every 30 s
demo/simulate.sh --url http://localhost:8080 --token <gateway token> --fleet lab:50

# 16 systems -- a device1 with two device2 and a device3 -- in four centres
demo/simulate.sh --name centres --url http://localhost:8080 --token <token> --systems 16

demo/simulate.sh --list          # what is running
demo/simulate.sh --stop          # stop it all

More, including how to make devices fail on demand so you can watch halts, thresholds and rollbacks, is in Connecting devices.

Next

If you are going to use Qawk, read Using the console. If you are going to run it, read Installing the server. If you want to know how the pieces fit before either, read Concepts.