Files
nx9-url-shortener/docs/DOCKER-Deploy.md
T
thakares 8e0bcbe580
Rust CI / Test & Quality Checks (push) Canceled after 0s
Rust CI / Build Docker Image (push) Canceled after 0s
feat: add Docker first-start admin bootstrap
2026-08-12 14:13:09 +05:30

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:

  1. Validate archive contents
  2. Restore databases
  3. Reinitialize database access
  4. 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

  1. Backup databases
  2. Pull latest source
  3. Rebuild container
  4. 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 doctor reports healthy

A deployment should not be considered production-ready until backup and restore procedures have been successfully tested.