7.3 KiB
Docker Deployment Guide for BZOD
This guide covers deployment, upgrades, backup, restore, troubleshooting, and production best practices for BZOD (nx9-url-shortener) using Docker.
Overview
BZOD is a lightweight self-hosted URL shortener and landing page platform written in Rust.
Features include:
- URL shortening
- Human-readable custom slugs (
!office,!home, etc.) - Landing pages
- QR code generation
- Analytics
- Audit logging
- API access
- Backup and restore
- SQLite-based storage
- Docker deployment
BZOD is designed to remain simple:
- No PostgreSQL
- No Redis
- No external dependencies
- No vendor lock-in
Quick Start
Clone Repository
git clone https://github.com/thakares/nx9-url-shortener.git
cd nx9-url-shortener
Build and Start
docker compose up -d --build
Automated Administrator Bootstrap (First Start Only)
For fresh deployments, you can supply administrator credentials via environment variables so the container initializes the admin automatically:
environment:
ADMIN_USERNAME: "admin"
ADMIN_PASSWORD: "<your-secure-password>"
These credentials are used only when no administrator exists. If an administrator is already present, this step is safely skipped and existing accounts are preserved.
Manual Administrator Creation
Alternatively, if you prefer not to use environment variables, you can create the admin manually:
docker exec -it bzod bzod create-admin
Open:
http://SERVER-IP:8654
Admin panel:
http://SERVER-IP:8654/admin
Docker Compose
Example:
services:
bzod:
container_name: bzod
build: .
restart: unless-stopped
ports:
- "8654:8654"
volumes:
- ./data:/app/data
- ./config:/app/config
environment:
HOST: 0.0.0.0
PORT: 8654
DATA_DIR: /app/data
COOKIE_SECURE: "false"
healthcheck:
test: ["CMD", "./bzod", "doctor"]
interval: 30s
timeout: 10s
retries: 3
Start:
docker compose up -d
Verify:
docker ps
docker logs -f bzod
Directory Layout
Typical deployment:
bzod/
├── docker-compose.yml
├── Dockerfile
├── config/
├── data/
│ ├── admin.db
│ ├── content.db
│ ├── analytics.db
│ └── system.db
└── backups/
Root Landing Page
BZOD can serve a static landing page from:
www/index.html
This page is available at:
https://your-domain/
Examples:
https://bzo.in/
https://short.example.com/
The root landing page is packaged automatically inside the Docker image.
Reverse Proxy Configuration
BZOD is intended to run behind a reverse proxy.
Example Nginx configuration:
server {
server_name bzo.in;
location / {
proxy_pass http://127.0.0.1:8654;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Example deployment:
Internet
↓
Nginx Proxy Manager
↓
BZOD Docker Container
Environment Variables
| Variable | Description | Default |
|---|---|---|
| HOST | Bind address | 0.0.0.0 |
| PORT | Listen port | 8654 |
| DATA_DIR | Database directory | /app/data |
| COOKIE_SECURE | Secure cookies | false |
| RUST_LOG | Logging level | info |
Production recommendation:
COOKIE_SECURE=true
when HTTPS is enabled.
Analytics Export
Analytics pages support:
- Raw visitor logs
- CSV export
- JSON export
- Date filtering
Exports can be generated from:
Admin → Analytics
Backup
Web UI
Navigate to:
Admin → Settings → Maintenance & DB Utilities
Click:
Download Backup
A compressed archive containing all databases will be downloaded.
CLI Backup
Create backup:
docker exec -it bzod bzod backup
Example output:
backup-2026-06-14.tar.gz
Restore
Web UI Restore
Navigate to:
Admin → Settings → Maintenance & DB Utilities
Upload:
backup.tar.gz
Type:
RESTORE
Confirm restore.
The system will:
- Validate archive contents
- Restore databases
- Reinitialize database access
- Redirect to login
CLI Restore
Copy backup archive into container or mounted volume.
Run:
docker exec -it bzod bash
cd /app/data
bzod restore --file backup.tar.gz
Disaster Recovery
Example recovery procedure:
docker compose down
# Restore backup archive
docker compose up -d
Verify:
docker exec -it bzod bzod doctor
docker exec -it bzod bzod validate
Check:
- URLs
- Landing pages
- Analytics
- Audit logs
- Settings
Useful CLI Commands
Health:
docker exec -it bzod bzod doctor
Statistics:
docker exec -it bzod bzod stats
Validate databases:
docker exec -it bzod bzod validate
Create admin:
docker exec -it bzod bzod create-admin
Shorten URL:
docker exec -it bzod bzod shorten https://example.com
Custom slug:
docker exec -it bzod bzod shorten https://example.com --slug !office
Expand URL:
docker exec -it bzod bzod expand !office
Upgrading
Pull latest source:
git pull
Rebuild:
docker compose build --no-cache
Restart:
docker compose up -d
Verify:
docker logs -f bzod
Upgrading to v0.4.0
- Backup databases
- Pull latest source
- Rebuild container
- Restart service
git pull
docker compose build --no-cache
docker compose up -d
---
# Troubleshooting
## Read-Only SQLite Database
Symptoms:
```text
attempt to write a readonly database
Check ownership:
ls -lah data/
Fix permissions:
docker exec -u 0 -it bzod bash
chown -R bzod:bzod /app/data
docker exec -it bzod bzod doctor
Restart:
docker compose restart bzod
Missing Root Landing Page
Symptoms:
404 on /
Verify:
docker exec -it bzod ls -lah /app/www
Expected:
/app/www/index.html
Rebuild image if necessary:
docker compose build --no-cache
docker compose up -d
Health Check Failure
Inspect logs:
docker logs bzod
Run:
docker exec -it bzod bzod doctor
Port Already In Use
Change host port mapping:
ports:
- "8080:8654"
Access:
http://SERVER-IP:8080
Production Recommendations
- Use HTTPS
- Run behind Nginx Proxy Manager or Nginx
- Use strong administrator credentials
- Schedule regular backups
- Periodically test restore procedures
- Monitor disk space
- Keep Docker images updated
Validation Checklist
After deployment verify:
- Admin login works
- URL shortening works
- Custom slugs work
- Landing pages work
- QR generation works
- Analytics recorded
- Backup download works
- Restore workflow works
- Root landing page loads
bzod doctorreports healthy
A deployment should not be considered production-ready until backup and restore procedures have been successfully tested.