|
<div class="docs-content" data-render>
|
|
# Deploy and update
|
|
|
|
First deploy, updates, environment, and rollback for the production stack. See also [Production overview](/docs/production.html) and [nginx and networking](/docs/production-nginx.html).
|
|
|
|
## Prerequisites
|
|
|
|
- Docker with the Compose plugin.
|
|
- The repository checked out on the **same host** that runs (or will run) the development server, so they share one database.
|
|
|
|
## Environment
|
|
|
|
Configuration is a single `.env` file in the project root (git-ignored), loaded both by Compose (`env_file`) and by the app at startup (`python-dotenv`). Copy the committed template and edit it.
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
| Variable | Default | Purpose |
|
|
|----------|---------|---------|
|
|
| `SECRET_KEY` | insecure placeholder | Session signing. **Change this.** |
|
|
| `DEVPLACE_DATABASE_URL` | unset | Leave unset to share `data/devplace.db`. Set only to point elsewhere. |
|
|
| `DEVPLACE_DATA_DIR` | `<repo>/data` | Single root for all runtime data (DB, uploads, keys, locks, bot state, staging, workspaces). Point at a volume in production. |
|
|
| `DEVPLACE_SITE_URL` | empty | Public origin for absolute URLs (SEO, canonical, push). Empty derives from the request. |
|
|
| `PORT` | `10500` | Host port the nginx front door binds. |
|
|
| `NGINX_MAX_BODY_SIZE` | `50m` | nginx upload ceiling. Must be >= `max_upload_size_mb`. |
|
|
| `NGINX_CACHE_ENABLED` | `false` | Enable the nginx micro-cache for proxied GETs. |
|
|
| `NGINX_CACHE_MAX_SIZE` | `1g` | Cache size cap when enabled. |
|
|
| `DEVPLACE_UID` / `DEVPLACE_GID` | `1000` | Host user the app container runs as, so shared files keep dev ownership. Match `id -u` / `id -g`. |
|
|
|
|
Operational behavior (rate limits, registration, maintenance mode, upload size, news cadence) is tuned live from **Admin -> Settings** and stored in `site_settings`; it needs no redeploy.
|
|
|
|
## First deploy
|
|
|
|
```bash
|
|
cp .env.example .env # set SECRET_KEY, PORT, DEVPLACE_SITE_URL
|
|
make docker-build # build the image (installs the docker CLI)
|
|
make docker-up # start (creates ./data, mounts the socket)
|
|
```
|
|
|
|
Open `http://<host>:<PORT>`. Useful targets: `make docker-logs` (tail), `make docker-down` (stop), `make docker-clean` (down).
|
|
|
|
The make targets always apply the `docker-compose.containers.yml` overlay, so the admin-only Container Manager works with no extra setup. Always update through them: a plain `docker compose up -d` drops the overlay and silently removes the docker socket and CLI the manager needs.
|
|
|
|
The healthcheck gives the app a 120s start window before any failure counts (`start_period: 120s` in `docker-compose.yml`). The full startup (DB init, background service registration, uvicorn workers) takes roughly 110s, so the start period must stay well above that. If you add heavyweight init work, verify the app boots within 120s or bump the start period to match.
|
|
|
|
## Updating
|
|
|
|
Code is bind-mounted, so most updates need no rebuild:
|
|
|
|
```bash
|
|
git pull
|
|
make docker-up # restart workers on the new code
|
|
```
|
|
|
|
Rebuild the image only when dependencies change:
|
|
|
|
```bash
|
|
make docker-build && make docker-up
|
|
```
|
|
|
|
## Release branch
|
|
|
|
`make deploy` fast-forwards the release branch:
|
|
|
|
```bash
|
|
git checkout production && git merge master && git push origin production
|
|
```
|
|
|
|
On the server, pull `production` and run the update steps above. CI (`.gitea/workflows/test.yaml`) runs the full test suite on every push/PR to `master`, so only tested commits reach `production`.
|
|
|
|
## Rollback
|
|
|
|
Because the container runs host source, rolling back is a git operation:
|
|
|
|
```bash
|
|
git checkout <previous-good-commit>
|
|
make docker-up
|
|
```
|
|
|
|
Back up `data/devplace.db` (and its `-wal`/`-shm`) before a risky change; the schema auto-syncs forward but is not auto-downgraded.
|
|
|
|
## Bare-metal alternative
|
|
|
|
`make prod` runs the same app without containers (`uvicorn ... --workers $(WEB_WORKERS) --proxy-headers`, where `WEB_WORKERS` defaults to the box core count via `nproc`) from the project root, sharing the same database and files. It binds port 10500 directly, conflicting with the Docker front door on that port - run one or the other, or set a different `PORT`. Keep `DEVPLACE_WEB_WORKERS` in lockstep with `--workers`; see [Multi-worker and concurrency](/docs/production-concurrency.html) for why.
|
|
</div>
|