This repository contains the minimal set of files required to deploy LobeHub's
Server Database edition (Domain Mode, Email/Password + SMTP authentication) as a
Docker Compose Application on Coolify. It is derived from LobeHub's official
reference stack at lobehub/lobehub/docker-compose/deploy/, adapted for Coolify's
Git-based deployment model (magic SERVICE_FQDN_*/SERVICE_URL_* env vars, named
volumes instead of relative bind mounts for stateful data, pinned image tags, no
published host ports, required-secret guards).
This repo is intentionally NOT a fork of the full LobeHub monorepo — Coolify always
performs a full git clone of whatever repo it's pointed at on every deploy
(regardless of base_directory), so a minimal 3-config-file repo keeps every
deploy's clone small and fast.
| File | Origin | Purpose |
|---|---|---|
docker-compose.yml |
Adapted from upstream (Coolify-specific changes) | Defines all services: lobe, postgresql, redis, rustfs, rustfs-init, searxng |
bucket.config.json |
Verbatim copy from upstream | RustFS/S3 bucket anonymous-read policy, applied by rustfs-init on first boot |
searxng-settings.yml |
Verbatim copy from upstream | SearXNG engine config; must keep json in search.formats for LobeHub's online search to work |
README.md |
This file | Repo documentation |
These files must be periodically re-checked against LobeHub's upstream repo and re-copied if changed. There is no automated Coolify mechanism for this — it must be done manually or via your own CI job that diffs against upstream.
| File | Last synced from upstream (UTC) | Upstream commit SHA checked |
|---|---|---|
bucket.config.json |
2026-09-02 14:13 UTC | 0c1e4a0f9212015c5335cacf4e2ef4c80317748c |
searxng-settings.yml |
2026-09-02 14:13 UTC | 0c1e4a0f9212015c5335cacf4e2ef4c80317748c |
Upstream source (for future re-sync / diffing):
- https://raw.githubusercontent.com/lobehub/lobehub/HEAD/docker-compose/deploy/bucket.config.json
- https://raw.githubusercontent.com/lobehub/lobehub/HEAD/docker-compose/deploy/searxng-settings.yml
This file is NOT a verbatim upstream copy; it is actively maintained for this specific Coolify deployment. Update this table every time you edit it.
| File | Last modified (UTC) | Modified by | Summary of change |
|---|---|---|---|
docker-compose.yml |
2026-09-02 14:13 UTC | scaffolding agent | Initial Coolify adaptation: pinned lobe to 2.2.15, bumped redis to 8.8.2-alpine3.23, removed container_names and host ports, named postgres volume, added Coolify magic FQDN/URL vars, required-secret guards, and Email/Password + SMTP auth env vars |
Reference (base) upstream version this file was adapted from:
- https://raw.githubusercontent.com/lobehub/lobehub/a2dcef0792822edf0c0b8d94160046eadaa16428/docker-compose/deploy/docker-compose.yml
(pre-Elasticsearch state at commit
a2dcef0792822edf0c0b8d94160046eadaa16428, 2026-09-02 08:21 UTC)
Provenance chain (verified 2026-09-02):
- The base content this file was adapted from is the upstream
docker-compose.ymlat commita2dcef0792822edf0c0b8d94160046eadaa16428(2026-09-02 08:21 UTC) — the last commit touchingdocker-compose/deploy/before the optional Elasticsearch stack was added. Adiffof this repo'sdocker-compose.ymlagainst that commit shows only the Coolify-specific deltas (no ES-related differences), confirming this is the correct adaptation base. - The next commit to touch that path,
330c12a7601015a2a8692f511d1dc567b6446fab(2026-09-02 09:37 UTC, PR #19028, "feat(self-host): add optional Elasticsearch to Docker Compose"), added threeprofiles:-gated services (elasticsearch,fts-search-reindex,fts-search-sync) and two volumes (elasticsearch-data,fts-search-reindex-state). These are intentionally omitted from this minimal repo — see "Intentionally omitted upstream services" below. - HEAD at fetch time was
0c1e4a0f9212015c5335cacf4e2ef4c80317748c(2026-09-02 14:00 UTC); that commit does not touchdocker-compose/deploy/, so its compose content is byte-identical to330c12a7's. It is therefore not the correct provenance reference for this adapted file (an earlier version of this README cited it as such — corrected here). The verbatim files (bucket.config.json,searxng-settings.yml) were verified byte-identical to HEAD at this commit, so0c1e4a0remains the correct "checked against" SHA in the verbatim-sync table above.
Upstream's docker-compose.yml (as of 330c12a7, PR #19028) ships three
optional, profile-gated services for full-text search via Elasticsearch:
| Omitted service | Profile | Why omitted |
|---|---|---|
elasticsearch |
elasticsearch |
profiles:-gated — never starts with a plain docker compose up -d (what Coolify runs). Also requires a local ./elasticsearch/Dockerfile build context that cannot exist in this minimal 4-file repo. |
fts-search-reindex |
elasticsearch-reindex |
profiles:-gated — one-off backfill command, never starts with docker compose up. |
fts-search-sync |
elasticsearch-sync |
profiles:-gated — long-running sync worker, off by default. |
Their two named volumes (elasticsearch-data, fts-search-reindex-state) are
omitted for the same reason. This is a deliberate, behavior-preserving
omission: because all three services are profiles:-gated, a plain
docker compose up -d starts exactly the same 6 services whether or not these
definitions are present. LobeHub continues to use PostgreSQL pg_search (via
paradedb/paradedb:latest-pg17) for full-text search in this deployment.
If you later need the Elasticsearch path, re-sync docker-compose.yml from
upstream and add COMPOSE_PROFILES=elasticsearch (then
elasticsearch,elasticsearch-sync once the backfill completes) as a Coolify
environment variable. Note: upstream's Elasticsearch service builds from
./elasticsearch/Dockerfile, so you would also need to add that directory to
this repo.
- Deploy as a "Docker Compose" Application resource, pointing at this repo's root
as
base_directory. - Assign domains via the Domains tab or rely on
SERVICE_FQDN_LOBE/SERVICE_FQDN_RUSTFS_9000/SERVICE_FQDN_RUSTFS_9001magic vars — never manually type a domain with a trailing slash. - Set the following as Coolify Environment Variables (mark as secret/masked and
lock after first deploy):
KEY_VAULTS_SECRET,AUTH_SECRET,JWKS_KEY,LOBE_DB_NAME,POSTGRES_PASSWORD,RUSTFS_ACCESS_KEY,RUSTFS_SECRET_KEY,RUSTFS_LOBE_BUCKET,SMTP_HOST,SMTP_PORT,SMTP_SECURE,SMTP_USER,SMTP_PASS,SMTP_FROM. - Backups: use the Application's "Scheduled Tasks" tab (not "Scheduled Database
Backup," which only applies to Coolify-native Database/ServiceDatabase
resources) to run
pg_dump/redis-cli BGSAVE/RustFS mirror commands viadocker execon a cron schedule.
bucket.config.json is a static, non-templated file. Its bucket policy ARN
is hardcoded to the default bucket name lobe:
"Resource": ["arn:aws:s3:::lobe/*"]If you change the Coolify env var RUSTFS_LOBE_BUCKET from lobe to anything
else, you MUST update this ARN by hand to match — for example, for a bucket
named mybucket, edit bucket.config.json to
"Resource": ["arn:aws:s3:::mybucket/*"]. A mismatch here makes the anonymous
read policy apply to a non-existent bucket, so uploaded images/attachments served
from S3 will fail with 403.
Note also that the rustfs-init service's command: in docker-compose.yml
hardcodes the bucket name lobe in two places (mc mb "rustfs/lobe" and
mc anonymous set-json "/bucket.config.json" "rustfs/lobe"). If you rename the
bucket, update both of those occurrences in docker-compose.yml to the new
name as well, so rustfs-init creates and policy-attaches the correct bucket on
first boot.