4.2 KiB
Deployment Guide
Requirements
- Docker 24.0+
- Docker Compose 2.20+
- A reverse proxy that terminates TLS for the public hostname
- A writable checkout directory for
./dataand./content
Fresh Deployment
git clone https://github.com/your-org/cairnquire.git
cd cairnquire
cp .env.example .env
Edit .env and set the HTTPS origin that users will open in their browser:
CAIRNQUIRE_PUBLIC_ORIGIN=https://cairnquire.example.com
Start the application and verify the local container health endpoint:
docker compose up -d --build
docker compose ps
curl http://127.0.0.1:8080/health
Compose starts Mailpit for local SMTP capture. Open http://127.0.0.1:8025
to inspect password-reset and notification messages. SMTP is also exposed on
127.0.0.1:1025 for host-run development servers.
Then open https://cairnquire.example.com/setup. On an empty database the
first-run wizard:
- Creates the initial administrator account.
- Sets its password.
- Records whether visitors may create their own accounts.
- Signs the administrator in.
The setup endpoint is only available until the first administrator has been created. The signup setting can be changed later from the administrator's account page.
Environment Variables
The checked-in Compose file sets the container paths. For a normal single-host
deployment, only CAIRNQUIRE_PUBLIC_ORIGIN must be supplied in .env.
| Variable | Required | Compose default | Description |
|---|---|---|---|
CAIRNQUIRE_PUBLIC_ORIGIN |
Yes | None | Exact external HTTPS origin. Passkeys and device-flow URLs depend on this value. |
CAIRNQUIRE_EMAIL_SMTP_HOST |
No | mailpit |
SMTP server used for notifications. |
CAIRNQUIRE_EMAIL_SMTP_PORT |
No | 1025 |
SMTP server port. |
CAIRNQUIRE_EMAIL_FROM |
No | notifications@cairnquire.local |
Notification sender address. |
CAIRNQUIRE_LOG_LEVEL |
No | INFO |
Application log level. |
The server also accepts these lower-level overrides when it is run outside the checked-in Compose deployment:
| Variable | Default | Description |
|---|---|---|
CAIRNQUIRE_SERVER_ADDR |
:8080 |
Listen address. |
CAIRNQUIRE_DATABASE_PATH |
../../data/db.sqlite |
Local SQLite/libsql database path. |
CAIRNQUIRE_DATABASE_PRIMARY_URL |
Empty | Optional remote libsql primary URL for embedded-replica mode. |
CAIRNQUIRE_DATABASE_AUTH_TOKEN |
Empty | Optional auth token for the remote libsql primary. |
CAIRNQUIRE_CONTENT_SOURCE_DIR |
../../content |
Writable Markdown source directory. |
CAIRNQUIRE_CONTENT_STORE_DIR |
../../data/files |
Content-addressed attachment store. |
CAIRNQUIRE_CONFIG |
Empty | Optional JSON configuration file. Environment variables override it. |
CAIRNQUIRE_DEV_MODE |
false |
Local-only auth shortcut. Never enable this on a deployed server. |
Persistent Data
Compose mounts:
./data:/workspace/datafor the database and attachments./content:/workspace/contentfor editable Markdown source
Both mounts must remain writable because uploads, browser edits, and sync writebacks modify them.
Reverse Proxy
Expose container port 8080 through a TLS-terminating reverse proxy. Preserve
the original hostname and forwarded client address headers. The configured
CAIRNQUIRE_PUBLIC_ORIGIN must exactly match the external origin, including
https://.
Backup And Restore
Stop writes or stop the app container before copying a fully consistent local database backup:
docker compose stop app
tar czf cairnquire-backup.tgz data content
docker compose up -d app
Restore by stopping the app, replacing data and content from the archive,
and starting the app again.
Upgrade
docker compose stop app
tar czf cairnquire-backup-before-upgrade.tgz data content
git pull
docker compose up -d --build
curl http://127.0.0.1:8080/health
Database migrations run automatically on startup.
Troubleshooting
docker compose logs -f app
docker compose ps
curl http://127.0.0.1:8080/health
If passkey creation fails after deployment, confirm that the browser URL and
CAIRNQUIRE_PUBLIC_ORIGIN are the same HTTPS origin.