Manual Installation
Prefer not to use containers, or running on ARM64? You can run Delivr directly with Bun and let systemd keep it running. This guide uses Debian/Ubuntu commands; other distributions work the same way.
Prerequisites
git,curl,openssl, andunzip- A reverse proxy for HTTPS
- Two DNS names — we use
mail.example.com(web) andapi.mail.example.com(API)
1. Install Bun system-wide
Installing Bun into /usr/local makes it available to the service user:
sudo apt install -y git curl openssl unzip
curl -fsSL https://bun.sh/install | sudo BUN_INSTALL=/usr/local bash
bun --version
2. Create a service user
sudo useradd --system --create-home --home-dir /opt/delivr --shell /usr/sbin/nologin delivr
3. Install the API
Clone and install dependencies
sudo -u delivr git clone https://github.com/Delivr-Project/Delivr-API.git /opt/delivr/api
cd /opt/delivr/api
sudo -u delivr git checkout "$(sudo -u delivr git describe --tags --abbrev=0 2>/dev/null || echo main)"
sudo -u delivr bun install
The checkout line switches to the latest release tag when there is one.
Configure
sudo -u delivr cp example.env .env
sudo -u delivr chmod 600 .env
sudo -u delivr nano .env
Set at least these values:
DLA_APP_URL=https://mail.example.com
DLA_ENCRYPTION_KEY=<output of: openssl rand -hex 32>
# Only listen on localhost — the reverse proxy is the public entry point
DLA_API_HOST=127.0.0.1
DLA_API_PORT=14123
# Only the local reverse proxy can reach the API, so trust the client address it forwards
DLA_TRUST_PROXY=true
DLA_DB_CONNECTION_URL=./data/db.sqlite
DLA_DB_MIGRATION_DIR=./drizzle/migrations/sqlite
See the Configuration Reference for every option, including system email.
DLA_ENCRYPTION_KEY somewhere other than this server. Without it, stored mail-account credentials cannot be decrypted.Create the systemd service
[Unit]
Description=Delivr API
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=delivr
Group=delivr
WorkingDirectory=/opt/delivr/api
ExecStart=/usr/local/bin/bun run start
Restart=on-failure
RestartSec=5
# Hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.target
Bun loads .env from the working directory automatically. bun run start always applies pending database migrations before the server starts.
Start it
sudo systemctl daemon-reload
sudo systemctl enable --now delivr-api
curl http://127.0.0.1:14123/health
4. Install the web client
Clone, install, and build
sudo -u delivr git clone https://github.com/Delivr-Project/Delivr-Web.git /opt/delivr/web
cd /opt/delivr/web
sudo -u delivr git checkout "$(sudo -u delivr git describe --tags --abbrev=0 2>/dev/null || echo main)"
sudo -u delivr bun install
sudo -u delivr bun run build
The build output lands in .output/.
Create the systemd service
The web client is configured at runtime with NUXT_PUBLIC_* variables, so one build works for any domain:
[Unit]
Description=Delivr Web
After=network-online.target delivr-api.service
Wants=network-online.target
[Service]
Type=simple
User=delivr
Group=delivr
WorkingDirectory=/opt/delivr/web
Environment=NUXT_PUBLIC_API_URL=https://api.mail.example.com/v1
Environment=NUXT_PUBLIC_APP_URL=https://mail.example.com
Environment=NUXT_PUBLIC_IS_SIGNUP_ENABLED=false
Environment=NITRO_HOST=127.0.0.1
Environment=NITRO_PORT=14128
ExecStart=/usr/local/bin/bun run .output/server/index.mjs
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.target
Start it
sudo systemctl daemon-reload
sudo systemctl enable --now delivr-web
curl -I http://127.0.0.1:14128
5. Finish up
- Configure your reverse proxy for both domains.
- Find the one-time admin setup link:
sudo journalctl -u delivr-api | grep reset-password # or sudo cat /opt/delivr/api/config/initial_admin_password_reset_token.txt - Continue with First Run & Admin Setup.
Updating a manual installation
# API
cd /opt/delivr/api
sudo -u delivr git fetch --tags
sudo -u delivr git checkout <new-version-tag>
sudo -u delivr bun install
sudo systemctl restart delivr-api
# Web
cd /opt/delivr/web
sudo -u delivr git fetch --tags
sudo -u delivr git checkout <new-version-tag>
sudo -u delivr bun install
sudo -u delivr bun run build
sudo systemctl restart delivr-web
Back up first — see Updates & Backups.