Production Deployment¶
Jinbocho is deployed as a self-hosted stack on your own server. Documented below: the fastest way to get a working stack, followed by the fully manual, step-by-step version for when you want to control every piece yourself.
All deployment tooling (compose files, env templates, scripts) lives in
jinbocho-install-community-v1.
Self-hosted deploy¶
Quick start¶
One command turns a fresh Debian/Ubuntu server into a fully running Jinbocho stack: one unified Postgres database, the three backend services, the frontend, and Caddy as a reverse proxy with automatic HTTPS.
git clone https://github.com/jinbocho/jinbocho-install-community-v1.git
cd jinbocho-install-community-v1
sudo ./scripts/setup-vps-community.sh \
--domain library.example.com \
--email you@example.com \
--google-books-key AIza...
Requirements:
- A fresh Debian/Ubuntu server with a public IP, run as
root(or viasudo). --domainmust already resolve to the server's IP — Caddy requests a Let's Encrypt certificate for it on first start. Omit--domain/--emailentirely to serve over plain HTTP on the bare IP instead (no TLS).- Any option not passed as a flag is asked interactively. Add
--non-interactiveto skip every prompt and rely only on flags/defaults — useful for unattended installs (e.g. cloud-init).
Within a couple of minutes the script prints the frontend URL, the API gateway URL, and where secrets were written. Open the frontend and register the first family — it becomes the admin account.
Re-running is safe
The script is idempotent: existing secrets, envs/*.env files, and the
generated Caddyfile are kept as-is on a second run, unless you delete
them first.
What the script does¶
scripts/setup-vps-community.sh runs docker/docker-compose.all.yml
end-to-end:
- Installs Docker (via
get.docker.com) if it isn't already present. - Optionally configures
ufwto open 22/80/443 (--enable-firewall). - Clones (or updates)
jinbocho-fenext to the infrastructure repo. - Generates
POSTGRES_PASSWORD,JWT_SECRET_KEY, andINTERNAL_SERVICE_TOKEN, and writes everyenvs/*.envfile from the*.exampletemplates. - Writes a
Caddyfilethat reverse-proxies/api/*to the gateway and everything else to the frontend, with automatic TLS if--domainwas set. - Pulls the backend images from GHCR, builds the frontend image from
source, and brings the whole stack up with
docker compose ... up -d. - Polls
/healththrough the gateway and reports whether the stack came up cleanly.
All script options¶
| Flag | Value | Default | Description |
|---|---|---|---|
--domain |
<fqdn> |
— (uses server IP, HTTP only) | Public domain already pointed at this server. Enables automatic HTTPS. |
--email |
<email> |
— | Let's Encrypt contact email. Required if --domain is set. |
--google-books-key |
<key> |
— | Google Books API key, used for catalog ISBN lookups. Can be added later by editing envs/catalog-service.env. |
--smtp-user |
<gmail address> |
— | Gmail address used to send invite/reset-password emails. SMTP host/port are set automatically. Leave unset to fall back to logging the link instead of sending it. |
--smtp-password |
<app password> |
— | Gmail App Password for --smtp-user — not your normal account password. |
--email-from |
<email> |
value of --smtp-user |
From-address shown on outgoing emails. |
--netdata-enabled |
true|false |
asked interactively | Enable the local Netdata dashboard (host + per-container metrics, :19999, localhost-only). No account or secrets needed. Optional, off by default. |
--frontend-base-url |
<url> |
derived from --domain/server IP |
Public frontend URL baked into email links. |
--fe-repo |
<git url> |
jinbocho/jinbocho-fe |
Frontend repository to clone. |
--fe-branch |
<branch> |
main |
Frontend branch to clone. |
--version |
<tag> |
latest |
Image tag to pull for the backend services. |
--enable-firewall |
flag | off | Configure and enable ufw, opening 22/80/443. |
--skip-docker-install |
flag | off | Don't attempt to install Docker (use if it's already provisioned by other tooling). |
--non-interactive |
flag | off | Never prompt; use only the flags/defaults given. |
-h, --help |
flag | — | Print the full flag list and exit. |
Verifying the deployment¶
./scripts/validate-api.sh
This registers a test family and exercises the main endpoints through the
gateway (http://localhost:8000, or your domain).
Useful day-2 commands (the script prints the exact invocation for your setup,
including --profile observability if Netdata is enabled):
docker compose -f docker/docker-compose.all.yml --env-file .env logs -f # tail logs
docker compose -f docker/docker-compose.all.yml --env-file .env ps # service status
docker compose -f docker/docker-compose.all.yml --env-file .env down # stop (volumes/data kept)
Manual install (no installer script)¶
If you'd rather not run the automated script — for example to review every
file before it's written, or because you already manage TLS with your own
reverse proxy — install piece by piece with docker-compose.community.yml
instead:
git clone https://github.com/jinbocho/jinbocho-install-community-v1.git
cd jinbocho-install-community-v1
cp .env.example .env
cp envs/auth-service.env.example envs/auth-service.env
cp envs/catalog-service.env.example envs/catalog-service.env
cp envs/api-gateway.env.example envs/api-gateway.env
# edit the files above — see the field tables below
docker compose -f docker/docker-compose.community.yml up -d
No TLS or reverse proxy in this mode
Unlike the one-shot script, docker-compose.community.yml does not run
Caddy. The gateway is exposed directly on port 8000. Put your own
reverse proxy (Caddy, nginx, Traefik, a load balancer) in front of it if
you need HTTPS or a domain name.
.env (repo root, read by Docker Compose itself):
| Variable | Default | Required | Description |
|---|---|---|---|
POSTGRES_PASSWORD |
change_me_local_dev |
Yes | Password for the local Postgres containers. Change it before exposing anything publicly. |
JINBOCHO_VERSION |
latest |
No | Image tag to pull for the backend services. |
envs/auth-service.env:
| Variable | Required | Description |
|---|---|---|
DEBUG |
No | Set false in production; true also enables SQL logging. |
DATABASE_URL |
Yes | postgresql+asyncpg://auth_role:<POSTGRES_PASSWORD>@postgres:5432/jinbocho — the postgres compose service, database jinbocho, schema auth. Password matches POSTGRES_PASSWORD from the root .env. |
JWT_SECRET_KEY |
Yes | Must be identical across auth-service, catalog-service, and api-gateway. Generate with openssl rand -hex 32. |
INTERNAL_SERVICE_TOKEN |
Yes | Must match catalog-service's value — authenticates catalog→auth calls (loan reminder emails). Generate with openssl rand -hex 32. |
FRONTEND_BASE_URL |
No | Used to build links in invite/reset-password emails. |
SMTP_USER / SMTP_PASSWORD |
No | Leave empty to print invite/reset links to logs instead of emailing them. |
envs/catalog-service.env:
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | postgresql+asyncpg://catalog_role:<POSTGRES_PASSWORD>@postgres:5432/jinbocho — schema catalog. |
JWT_SECRET_KEY |
Yes | Identical to auth-service's value. |
INTERNAL_SERVICE_TOKEN |
Yes | Identical to auth-service's value. |
GOOGLE_BOOKS_API_KEY |
Recommended | Free key at console.cloud.google.com. Without it the shared quota (1000 req/day) is exhausted quickly. |
envs/api-gateway.env:
| Variable | Required | Description |
|---|---|---|
JWT_SECRET_KEY |
Yes | Identical to auth-service's value. |
CORS_ORIGINS |
No | ["*"] by default — set to your frontend's real URL in production. |
Open http://<server-ip>:8000/docs to confirm the gateway is up, then
proceed as in Verifying the deployment above.
Optional: metrics (Netdata)¶
Off by default — skip this if you don't need it, the stack works exactly as
described above without it. When enabled (--netdata-enabled true, or by
hand later with --profile observability), a single Netdata container
monitors host + per-container CPU/RAM/disk/network with a built-in
dashboard. No external account, no secrets to configure. The dashboard
binds to 127.0.0.1:19999 only — reach it via
ssh -L 19999:localhost:19999 <host>, then http://localhost:19999. See
README.md (section 6) in jinbocho-install-community-v1 for the
full setup.
Next Steps¶
- Verify it's healthy: Monitoring & Logging
- Something not working?: Troubleshooting