Ledgr — the whole application in one container
910
nginx, the web UI and the API in a single image — around 94 MB compressed, less than the API image alone, because it carries no build toolchain. For deployments that would rather run one thing than three.
Postgres, Redis and object storage. They hold your data. Baking a database into an application image is how people lose it on the next redeploy, so point the environment variables below at real ones.
The MS SQL driver and the MongoDB tools. Several hundred megabytes between
them, for DATABASE_DIALECT=mssql and parts of the DB Manager. Postgres and
MySQL both work here — their drivers are pure Python. If you need MS SQL, run
the separate ledgr-api image instead.
docker run -d --name ledgr -p 8080:80 \
-e DATABASE_DIALECT=postgresql \
-e DATABASE_HOST=... -e DATABASE_USER=... \
-e DATABASE_PASSWORD=... -e DATABASE_NAME=... \
-e REDIS_URL=redis://redis:6379/0 \
-e MINIO_ENDPOINT=minio:9000 \
-e MINIO_ROOT_USER=... -e MINIO_ROOT_PASSWORD=... \
-e JWT_SECRET="$(openssl rand -base64 48)" \
-e SETTINGS_ENC_KEY="$(openssl rand -base64 32)" \
-e [email protected] \
-e SUPERADMIN_PASSWORD='a real password' \
-e APP_BASE_URL=https://ledgr.example.com \
yavadmin/ledgrr-app:latest
Nothing runs Alembic for you, and the container will not half-create the schema behind your back either. On an upgrade it comes up, notices the database is behind, logs which revisions are pending, and waits:
Database is behind this build by 6 migration(s) (…). Leaving the schema to
alembic so `alembic upgrade head` can run cleanly — run it now; the app is not
fully functional until you do.
So the order is: pull, start, migrate.
docker exec ledgr alembic upgrade head
Safe to run when there is nothing to do. On a genuinely empty database the app builds the schema itself on first boot and records it as current, so a fresh install needs no migration step at all.
| Variable | Why |
|---|---|
JWT_SECRET | Signs every access token. The default is a published placeholder and the app logs a CRITICAL warning while it is in use. |
SETTINGS_ENC_KEY | Encrypts stored SMTP and OAuth secrets. Without it the key is derived from JWT_SECRET, which couples two unrelated rotations. |
APP_BASE_URL | The URL a browser opens this at. CORS, OAuth callbacks and email links all derive from it. |
PORT | Listen port. Defaults to 80. |
UVICORN_WORKERS | API worker processes. Defaults to 1. |
nginx does not start until the API answers its own health endpoint, so the first request after a deploy is not a 502. If either process exits, the container exits — an orchestrator can restart a dead container, but not a live one that is quietly half-working.
yavadmin/ledgr-api, yavadmin/ledgr-web and yavadmin/ledgr-nginx are the
same application as three images. Prefer them when you want to scale the API
independently, roll one piece forward at a time, or put your own proxy in
front.
Content type
Image
Digest
sha256:47cdadc39…
Size
96.7 MB
Last updated
about 1 month ago
docker pull yavadmin/ledgrr-app