Installation¶
Two paths: a quick local dev checkout, or a single-server install with generated secrets you can paste straight in.
Prerequisites¶
- Python 3.13 (installed via
uvin a project venv) - PostgreSQL 17 or 18 (
nulls_distinct=Falseneeds PG 15+) - Redis (for the RQ job queues)
- Linux for the user-level systemd services; the app itself runs anywhere Django runs
Install on a server¶
A start-to-finish install on a fresh Ubuntu/Debian box. Commands assume sudo.
Your secrets are generated below — in your browser
Every value in the blocks on this page (DJANGO_SECRET_KEY, the database
password, the admin password) is randomly generated in your browser when
the page loads, so no two installs share a "default". Hit ↻ Regenerate
for a fresh set. The same secret is reused consistently across the steps
(the DB password in the SQL matches the one in your .env), so you can copy
each block as-is. Store them somewhere safe — and you can always rotate
them later (see Rotating secrets).
1. System packages¶
sudo apt update
sudo apt install -y postgresql redis-server git curl
# uv (installs/manages Python 3.13)
curl -LsSf https://astral.sh/uv/install.sh | sh
2. PostgreSQL role + database¶
Creates the danbyte role with your generated password and its database:
sudo -u postgres psql <<SQL
CREATE ROLE danbyte LOGIN PASSWORD '…';
CREATE DATABASE danbyte OWNER danbyte;
SQL
3. Get the code + Python deps¶
Danbyte's systemd units are user-level and rooted at ~/danbyte, so clone
it into your home directory (not /opt):
git clone …/danbyte ~/danbyte && cd ~/danbyte
uv python install 3.13
uv venv --python 3.13 .venv
VIRTUAL_ENV=$PWD/.venv uv pip install -r requirements.txt
4. Configure .env¶
Write this to ~/danbyte/.env (set ALLOWED_HOSTS to your server's hostname
or IP). The secret key, DB password, and admin password are pre-filled with your
generated values:
DJANGO_SECRET_KEY=…
DEBUG=False
ALLOWED_HOSTS=your-server.example.com
DB_NAME=danbyte
DB_USER=danbyte
DB_PASSWORD=…
DB_HOST=127.0.0.1
DB_PORT=5432
REDIS_URL=redis://localhost:6379/0
# Admin user created by `make bootstrap` on first run:
DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_EMAIL=admin@your-org.example
DJANGO_SUPERUSER_PASSWORD=…
Change the admin password after first login
The generated DJANGO_SUPERUSER_PASSWORD gets you in safely on a fresh box.
It's still a single shared-with-your-clipboard secret — sign in, then change
it under User → Preferences, and drop the line from .env.
5. Migrate + first-run bootstrap¶
bootstrap is idempotent: it sets up the default Organization + built-in Status
catalog and, because the DJANGO_SUPERUSER_* vars are set, creates your admin
user.
6. Build the frontend + collect static¶
make frontend-install # one-time: node deps
make frontend-build # build the SSR frontend → frontend/dist
make collectstatic # gather Django admin/DRF static → staticfiles/
7. Run the production processes¶
Danbyte runs as a few small processes, each a user-level systemd unit:
| Process | Unit | Serves |
|---|---|---|
| gunicorn | danbyte-web |
HTTP (the Django WSGI app) on 127.0.0.1:8000 |
| daphne | danbyte-ws |
WebSockets (presence) on 127.0.0.1:8002 |
| node | danbyte-frontend-prod |
the built SSR frontend on 127.0.0.1:3000 |
| RQ worker | danbyte-workers |
background jobs (scans, deploys) |
| scheduled timers | danbyte-* |
drift dispatch, cleanup, materialise, … |
Why daphne and gunicorn
gunicorn serves all plain HTTP; daphne serves only the /ws/ routes.
Keeping the ASGI server off the HTTP path is deliberate — putting it in front
of everything wedges ordinary requests.
make install-services # workers + timers + the (dev) units
make install-prod-services # gunicorn + daphne + built-frontend units
make workers-up
systemctl --user enable --now danbyte-web danbyte-ws danbyte-frontend-prod
make status
8. nginx + TLS¶
Put everything behind one HTTPS origin with the production nginx template
(static served from disk, /ws/ → daphne, /api/ + /admin/ → gunicorn):
make proxy-install \
NGINX_TMPL=deploy/nginx/danbyte.prod.conf.template \
PROXY_HOST=danbyte.example.com
This generates a self-signed cert by default — fine for a LAN, but for a
public host install a real CA cert (e.g. Let's Encrypt / certbot) and re-point
CERT / KEY, or drop the cert paths into /etc/ssl/danbyte/.
Open https://danbyte.example.com/ and sign in as admin.
Shipping updates later
Backend: git pull && .venv/bin/python manage.py migrate && make collectstatic
then systemctl --user restart danbyte-web danbyte-ws danbyte-workers.
Frontend: make frontend-build && systemctl --user restart danbyte-frontend-prod.
Rotating secrets¶
Any of these can be changed later without a reinstall:
- Admin password — User → Preferences (or
manage.py changepassword). DJANGO_SECRET_KEY— edit.env,make restart. (Invalidates active sessions — everyone signs in again.)- DB password —
ALTER ROLE danbyte PASSWORD '…';in psql, update.env,make restart.
Security checklist¶
-
DEBUG=FalseandALLOWED_HOSTSset to your real host(s). - nginx + TLS in front; Danbyte not exposed directly on
:8000. - Admin password changed after first login; superuser line removed from
.env. -
.envischmod 600and never committed. - Postgres/Redis bound to localhost (or firewalled).
Local development¶
git clone …/danbyte && cd danbyte
uv python install 3.13
uv venv --python 3.13 .venv
VIRTUAL_ENV=$PWD/.venv uv pip install -r requirements.txt
# Postgres role + db (dev creds are fine locally)
sudo -u postgres psql <<'SQL'
CREATE ROLE danbyte LOGIN PASSWORD 'danbyte';
CREATE DATABASE danbyte OWNER danbyte;
SQL
DB_HOST=127.0.0.1 DB_USER=danbyte DB_PASSWORD=danbyte DB_NAME=danbyte \
.venv/bin/python manage.py migrate
# Optional: opt-in demo data
DB_HOST=127.0.0.1 DB_USER=danbyte DB_PASSWORD=danbyte DB_NAME=danbyte \
.venv/bin/python manage.py seed_demo
make install-services
make backend-up
Open http://localhost:8000/prefixes/.
Settings env vars¶
| Variable | Default | Purpose |
|---|---|---|
DB_HOST |
127.0.0.1 |
PostgreSQL host |
DB_PORT |
5432 |
PostgreSQL port |
DB_NAME |
danbyte |
Database name |
DB_USER |
danbyte |
DB role |
DB_PASSWORD |
danbyte |
DB password |
ALLOWED_HOSTS |
localhost,127.0.0.1 |
Comma-separated. Set on a server / VPN host |
DJANGO_SECRET_KEY |
dev-key-change-in-prod |
Required when DEBUG=False |
DEBUG |
True |
Disable in prod |
CORS_ALLOWED_ORIGINS |
http://localhost:3000 |
Frontend origin(s) |
DJANGO_SUPERUSER_USERNAME / _EMAIL / _PASSWORD |
— | bootstrap creates this admin when set |
See danbyte/settings.py for the full list.
Verifying¶
Expected: 200.