DEV Community

Cover image for Your own agent, your own server: self-hosting drobek
Tomas Grasl
Tomas Grasl

Posted on

Your own agent, your own server: self-hosting drobek

The useful part of self-hosting drobek is deciding where those small AI-built apps live. Your colleagues can keep using their own coding agents. You run the place that compiles the frontend, serves it, and provides the backend modules.

You also take responsibility for the server, email delivery, backups, and updates. The setup below uses the v0.5.0 deployment files.

The stack is one drobek image plus Postgres, Redis, and Caddy. Caddy handles HTTPS. Only Caddy exposes public ports in the production Compose setup; the app server and databases stay on the internal network.

Start with DNS and email

For this release's prebuilt image, use a Linux amd64 server. Have Docker Engine, Compose v2, Git, OpenSSL, and Task v3 available. The repository's self-hosting guide includes installation steps for a clean Ubuntu 24.04 host.

Check the tools before proceeding:

docker compose version
task --version
Enter fullscreen mode Exit fullscreen mode

You need ports 80 and 443 reachable and two DNS records pointing at the server:

Record Example
Dashboard A/AAAA drobek.example.com
Wildcard app A/AAAA *.apps.example.net

Replace the example domains with domains you control. The separate registrable domain for apps is deliberate: those apps contain code generated for their owners and should be separated from the dashboard.

You also need working email delivery. This walkthrough uses SMTP. drobek sends sign-in codes by email, so a healthy web process with broken SMTP still leaves you unable to complete that login flow.

Get matching deployment files and image

On a new server, in a directory you can manage:

git clone --branch v0.5.0 --depth 1 \
  https://github.com/freema/drobek.git drobek
cd drobek
Enter fullscreen mode Exit fullscreen mode

Pinning the checkout and image to the same release makes the setup easier to reason about. These commands use v0.5.0; check the release notes before selecting a newer version.

Initialize the configuration with your real hosts and email settings:

DOMAIN=drobek.example.com \
APPS_DOMAIN=apps.example.net \
DROBEK_IMAGE_TAG=v0.5.0 \
TLS_ACME_EMAIL=you@example.com \
SUPERADMIN_EMAIL=you@example.com \
SMTP_HOST=smtp.example.com \
SMTP_PORT=587 \
SMTP_USER=no-reply@example.com \
EMAIL_FROM=no-reply@example.com \
task selfhost:init
Enter fullscreen mode Exit fullscreen mode

The initializer generates secrets, writes .env.production with mode 600, and renders the Caddy configuration. It can run again without replacing existing secrets.

Edit .env.production to supply SMTP_PASS. Keep the password out of a pasted shell command and out of Git. Follow the file's quoting instructions if a value contains characters such as $, #, or spaces.

Decide who can publish

Before sharing the instance, choose who may publish. The default publishing mode is open. If this is a server where workspaces should need operator approval before publishing, set these values in .env.production before starting it:

PUBLISH_APPROVAL=approval
OPERATOR_EMAIL=you@example.com
Enter fullscreen mode Exit fullscreen mode

This controls publishing. It does not turn registration off or block creation and previewing of apps. Existing live content also isn't removed just because a workspace is later blocked from publishing.

The publishing policy documentation explains the separate workspace states and takedown controls. Choose the behavior that matches how you intend to run the instance.

Bring the stack up

docker compose --env-file .env.production \
  -f docker-compose.production.yaml up -d --wait
Enter fullscreen mode Exit fullscreen mode

The first start pulls the images and applies database migrations. Check the dashboard endpoints using your actual hostname:

curl -fsS https://drobek.example.com/healthz
curl -fsS https://drobek.example.com/api/version
Enter fullscreen mode Exit fullscreen mode

The health response should report the database and Redis as up. The version endpoint lets you check which image is serving requests. These are expected checks, not output from your server until you run them.

With a real domain, the default TLS mode issues app certificates on demand through Caddy. The first request to a new app hostname can take longer while its certificate is issued. Both the DNS wildcard and reachable validation ports matter here.

Open the dashboard, sign in using SUPERADMIN_EMAIL, and enter the code sent by email.

Connect an agent and build something small

For Claude Code, the documented connection is:

claude mcp add --transport http drobek \
  https://drobek.example.com/mcp
Enter fullscreen mode Exit fullscreen mode

Complete its OAuth flow. To make an app live, the connection needs the publishing scope as well as the relevant workspace permission.

For a first app, keep the request easy to inspect:

Build a tip calculator on drobek.
Use a bill amount, tip percentage, and number of people.
Handle zero people and invalid amounts without dividing by zero.
Give me the preview URL before publishing.
Enter fullscreen mode Exit fullscreen mode

Open the preview and try the edge cases. Ask the agent to publish only once the result behaves as expected. The returned production URL belongs to the chosen published version; later edits can stay in preview.

This is frontend hosting with platform modules. It doesn't mean the agent now has permission to deploy arbitrary server code to your machine.

Back up the keys as well as the data

From the checkout, the supported backup task is:

task backup
Enter fullscreen mode Exit fullscreen mode

It creates an archive containing the database and the relevant file, asset, module, and Caddy data. Copy the archives off the host.

.env.production is not in that archive. Keep a protected copy separately. In particular, the master key is needed to decrypt restored upstream secrets. A database backup without the corresponding key isn't a complete recovery plan.

Redis is not backed up by this task, so users sign in again after a restore on a fresh machine. The backup runs online; if you need a quiesced snapshot across database and file operations, follow the guide's instructions for stopping writes.

Rehearse restoring to a separate empty stack before depending on the backups. The restore procedure checks the archive and key and normally refuses a non-empty database.

Keep upgrades deliberate

For an update, read the target release notes, move the deployment checkout to that tag, and set the matching DROBEK_IMAGE_TAG in .env.production. Then use:

task selfhost:upgrade
Enter fullscreen mode Exit fullscreen mode

The task takes a backup and runs migrations before bringing the updated application up. An app-code rollback and a server/database rollback are different operations; don't assume an older server image can understand a newer database schema.

Once the first app is live, keep checking email delivery and backup recovery. Review access as people join, and keep the server updated. The repository contains the deployment files and the full guide when you need custom domains, other TLS modes, or external modules.

Top comments (0)