Running Appdor on your own server

Self-hosting · 5 min read ·

If your team's records are not allowed to live on someone else's server, or you simply prefer to know where they are, the useful question is how much work it takes to run the thing yourself. For Appdor the answer is one container and one published port. Here is what that means in practice, including the part about the trial, which is easy to get wrong if you have only skimmed a pricing page.

What you need

A machine with a shell, curl, and Docker with Compose, which is all the commands below use. There is no separate database to install: according to the README, the one container holds the web app, the API gateway, authentication, the REST layer, PostgreSQL and file storage, together with the workflow worker and the other supporting processes. docs/deployment.md calls the quick-start database "embedded PostgreSQL".

The app and the API answer on the same address, so there is a single port to open. By default the compose file publishes it as 8080 on the host.

Starting it

These are the five lines from the README's Quick start, unchanged:

curl -fsSL https://get.appdor.com/appdor-latest.tar.gz | docker load
curl -fsSLO https://get.appdor.com/docker-compose.yml
docker run --rm ghcr.io/nebosa-company/appdor generate-keys > .env
docker compose up -d
docker compose exec appdor create-user you@example.com

The first two fetch the image and the compose file from a public download, with no registry login. The third writes a fresh set of secrets into .env. The fourth starts the stack. The fifth creates the first account; the README says signup ships closed and email confirmation on, and that create-user prints a generated password. Then open http://localhost:8080.

The third line deserves a second look. The example environment file ships with no keys at all, and a stack started without its own keys refuses to boot and says so. The README is blunt about why: an earlier version carried well-known demo keys behind a comment asking you to replace them, and a comment is not a control. Keep .env somewhere safe and out of version control, because the README states it is the only place those keys live.

Where your data goes, and what is still yours to do

The compose file mounts one volume, appdor-data, at /data. Its comment says that holds the database and the attachments. A scheduled backup program runs inside the container; docker/backup.sh writes a dump into /data/backups, verifies it by restoring it into a scratch database, and prunes by a default retention that its header gives as thirty days.

Read that carefully, because it is an honest limit. A backup on the same volume as the database protects you from a bad edit, not from losing the machine. docs/product-contract.md says off-host protection exists only when the operator configures and verifies an S3 target. The same page lists what stays with you: TLS, DNS, outbound mail credentials, off-host backups, monitoring and incident response. Self-hosting moves the data to your server and moves those chores with it.

Two optional settings are worth knowing. If you already run a managed PostgreSQL, docs/deployment.md shows how to point the container at it:

POSTGRES_HOST=db.example.internal POSTGRES_PORT=5432 docker compose up -d

And if the instance should only be reachable from an office or a VPN, the ALLOWED_IPS variable takes addresses and ranges; anything not listed gets a 403, and leaving it empty means no restriction.

What the trial means

This is the part to understand before you build anything on it. The README says a self-hosted install runs a thirty-day Business trial from first boot, then becomes read-only until a licence is installed, and that there is no free self-hosted plan. The release image sets the flag that starts the clock (Dockerfile.release).

Read-only is specific. The SQL that implements it describes data that stays readable and exportable while nothing can be created or edited. The plan screen tells you where you stand: while the trial runs it shows how many days are left, and afterwards it reads "The thirty-day trial has ended — this deployment is read-only until a licence is installed."

To end the lock, buy a plan on the homepage and install the licence you are sent. In the app, open Settings and the Plan & usage screen, choose Install licence, and paste the document into the field labelled Paste the licence document. Only the workspace owner can do this. Alternatively, mount the file at /appdor/license.json; the compose file says it is re-read on every check, so no restart is needed. The licence is a signed document checked against a key the deployment already holds, according to the comments in src/billing/lifecycle.js, so installing it does not depend on reaching our servers.

None of this is a reason to hurry or to avoid it. It is a reason to plan: use the thirty days on a real workflow, not a toy, and decide before day thirty whether the answer is a licence or an export.

If you want to see what the product does before you commit a server to it, start at the Appdor homepage.