Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

240 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AkerDock

Self-hosted PaaS in Go. Deploy applications, databases and Docker Compose stacks to your own servers over SSH, with a managed reverse proxy, automatic HTTPS, PR previews, backups and monitoring — no vendor lock-in.

A single static Go binary. PostgreSQL is the only dependency — it holds both the state and the job queue (no Redis, no external bus). The API is spec-first (OpenAPI), and the control plane never runs your workloads: Docker operations ride an outbound channel opened by a small agent on each server (ADR-051/052), with SSH kept for bootstrap, repair, git clones and Nixpacks builds only.

Design docs (PRD, ADRs, specs), code, the CLI and this README are all in English.

What it does

  • Deploy apps from a Dockerfile, a git repo (Nixpacks / Dockerfile / static) or a Docker image; databases (Postgres, MySQL, Redis…) and Docker Compose stacks — with zero-downtime rolling switches when a health check is configured.
  • Reverse proxy + automatic HTTPS (Traefik + Let's Encrypt, HTTP-01 or DNS-01 wildcard), per server.
  • PR previews: every pull request gets its own isolated instance and URL, torn down on merge/close.
  • Backups of databases and volumes with local + S3 retention and restore drills.
  • Auth: password, passkeys (WebAuthn), OIDC SSO (Google, Entra…), enforced MFA, and SCIM 2.0 provisioning; granular team RBAC, with an invitee able to create their account straight from the invitation link.
  • Teams as the isolation boundary: a user can belong to several teams with a different role in each, and switches between them from the sidebar; everything else (servers, resources, tokens, notifications) is scoped per team.
  • Adopt containers and compose stacks already running on a server, without restarting them (migrate in place).
  • Scale to zero: idle apps stop and wake on the first request (ADR-036).
  • Bastion: declared external endpoints and audited TCP tunnels to them (ADR-045).
  • Local CLI for day-to-day debugging: logs, shell, TCP port-forward and typed DB consoles — see Using the CLI.
  • MCP server (read-only, opt-in) so an assistant can inspect the instance — akerdock mcp (ADR-043).

Run your own instance

Requirements: Docker Engine ≥ 24 with Compose v2, and openssl.

git clone https://github.com/deepteams/akerdock.git
cd akerdock
./install.sh

install.sh builds the image from the local Dockerfile (no published image needed), generates the master key (keys/master.keyback it up off the machine immediately) and the .env, starts the reference two-service stack (AkerDock + PostgreSQL), and prints the first root user's credentials. Customise the first run with AKERDOCK_PORT, AKERDOCK_INSTANCE_FQDN, AKERDOCK_ROOT_EMAIL, etc. (see the script header). Two variables matter for server onboarding since ADR-051: AKERDOCK_IMAGE (the instance's own image, from which the per-server agent helper is deployed — the compose derives it from AKERDOCK_TAG) and AKERDOCK_INSTANCE_URL (the base URL agents dial back; derived from the instance FQDN or host gateway when unset).

Update an existing instance: git pull && ./install.sh — the image is rebuilt, migrations apply at boot, and state persists in the named volumes. The manual install is documented in docs/runbooks/install.md.

Migrating from another platform

AkerDock adopts containers and compose stacks already deployed, without restarting them (PRD §20.7): scan the server, preview the mapping, adopt, then normalise on the first redeploy — volumes and domains kept, de-adoption possible at any time. For a Coolify server, scripts/migrate/coolify.sh drives the whole migration over the public API (dry-run by default).

Using the CLI

akerdock is the same binary as the server (Cobra subcommands). It talks only to your instance over HTTPS, opens no local port, and works from anywhere — behind a proxy, over SSH, in a container. This is what team members use to debug a resource without a manual SSH tunnel.

Get the CLI

# straight from the repo — installs `akerdock` into $GOBIN (usually ~/go/bin):
go install github.com/deepteams/akerdock/cmd/akerdock@latest

# or build from a checkout, or grab a release binary:
go build -o akerdock ./cmd/akerdock && sudo mv akerdock /usr/local/bin/

Make sure $GOBIN (or $(go env GOPATH)/bin) is on your PATH.

Log in

akerdock login --url https://manager.example.com

This opens your browser to authorise (SSO / password / passkey), then stores a named, revocable token under ~/.akerdock/ (directory 0700, files 0600; the token lives in credentials.yaml, apart from the inspectable config.yaml). No port is opened — the browser flow is a poll bound by PKCE, with a confirmation code you match on screen. The token defaults to read,write — never root, deploy or read:sensitive unless you ask for them with --scopes, and never more than the approving session holds — and expires after 30 days.

CI or headless? Paste an existing API token instead, or print the URL rather than opening a browser:

akerdock login --url https://manager.example.com --with-token < token.txt
akerdock login --url https://manager.example.com --no-browser

Everyday commands

A resource is addressed by a REF of the form type/name, where the name is the resource's name or its UUID: app/…, db/…, svc/…, preview/…, and endpoint/… for a declared external target.

akerdock ls                              # apps, databases and services in the team
akerdock ls servers                      # or one kind: apps|databases|services|servers
akerdock logs app/varuna -f              # follow container logs
akerdock logs app/varuna -n 500          # snapshot, last N lines (default 200)
akerdock logs app/varuna --deployment    # logs of the latest build/deploy
akerdock shell app/varuna                # interactive shell in the container
akerdock shell app/varuna -c postgres    # a specific compose service

# Tunnel a container port to localhost through the manager (never exposes it):
akerdock port-forward db/pg 15432:5432
akerdock port-forward app/varuna 15432:5432 -c postgres --pr 8   # a PR preview

# …or to a declared external endpoint — a managed DB, an internal API (ADR-045).
# No remote port to give: the endpoint froze its own host and port. Without a
# local port either, the OS picks a free one and the CLI prints it.
akerdock port-forward endpoint/prod-replica
akerdock port-forward endpoint/prod-replica 15432   # …on a chosen local port

# Typed console: opens a forward + the right client
# (psql / mysql / redis-cli / mongosh, picked from the engine):
akerdock db db/pg

Output is human tables by default; add -o json for scripting, --quiet for bare output. Exit codes: 0 success, 1 error, 2 usage.

Give a local assistant read-only access (MCP)

akerdock mcp bridges the instance's MCP server over stdio, using the current context's credentials. The tools are read-only, and the server-side surface is off by default — enable it in the instance settings first (ADR-043).

Contexts (multiple instances, multiple teams)

Each login creates a context: one instance, and the team its token belongs to. Switch between them without re-typing the URL:

akerdock context list
akerdock context use staging
akerdock context current
akerdock logout --context staging --revoke   # also revoke the server-side token

An API token is bound to one team when it is created, so a context acts in that team and nothing else — --team does not move it (it only tells logout --revoke where to look for the token to delete). To work in another team, log in again into a separate context with a token of that team. The dashboard's team switcher moves a session; the CLI holds a token, and tokens do not move.

Per-directory defaults (.akerdock)

Drop a committable .akerdock file in a repo to set defaults for that directory tree — no more repeating --context or the target on every command (found by walking up, like .git; it never holds secrets):

# .akerdock — every field optional
context: prod          # a context created by `akerdock login`
application: varuna    # default target for logs / shell
component: web         # default compose service
project: platform
environment: production

Then, from that repo:

akerdock logs -f          # follows the default app on the configured instance
akerdock shell            # shell into it

Resolution precedence (most specific wins): flags > AKERDOCK_* env vars > .akerdock > ~/.akerdock (global) — with AKERDOCK_CONTEXT, AKERDOCK_APPLICATION, AKERDOCK_COMPONENT, AKERDOCK_PROJECT, AKERDOCK_ENVIRONMENT, AKERDOCK_TEAM.

Server modes

The same binary runs the control plane, which is why akerdock --help lists more than the client commands:

akerdock serve            # all-in-one (default, or $AKERDOCK_MODE)
akerdock serve api        # HTTP API only …  worker | scheduler for the others
akerdock healthcheck      # probe used by the compose healthcheck
akerdock agent            # server agent helper container (ADR-051/056; `waker` is a deprecated alias)
akerdock version

The full contract is in docs/specs/cli.md.

Documentation

Directory Contents
docs/PRD.md Product spec: functional scope and verifiable requirements
docs/adr/ Architecture Decision Records (accepted)
docs/specs/ Technical specs: OpenAPI v1, CLI, ERD, threat model, RBAC matrix, proxy contract, deployment engine…
docs/runbooks/ Operational runbooks (install, failures, key rotation, upgrades…)

Key architecture decisions

  • Transport: SSH first, outbound agent on the target (ADR-001)
  • Durable queue in PostgreSQL, no external bus (ADR-002)
  • Standalone Docker runtime — Kubernetes and Swarm ruled out (ADR-004)
  • Go core: pgx + sqlc, chi + oapi-codegen, spec-first (ADR-025)
  • Distribution: minimal two-service compose (AkerDock + PostgreSQL) (ADR-021)
  • Real-time: SSE, WebSocket reserved for the terminal and tunnels (ADR-024)
  • Single-binary CLI (Cobra), client and server modes (ADR-033)

Development

Requirements: Go ≥ 1.26 and golangci-lint v2 (the other tools — sqlc, oapi-codegen, goose — are pinned in go.mod and run via go tool).

make generate   # regenerate code from the OpenAPI spec and sqlc queries
make build      # compile bin/akerdock
make test lint  # tests and lint

Conventions (commits, spec-first workflow, migrations) are in CONTRIBUTING.md.

License

Apache 2.0 (ADR-020).

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages