Docker Deployment

Deploy Vendel using Docker Compose.

docker-compose.yml

Vendel runs as a single container serving both the API and the web dashboard on port 8090. Data is stored in an embedded SQLite database.

docker-compose.yml
services:
  app:
    image: ghcr.io/jimscope/vendel:latest
    environment:
      - ENVIRONMENT=production
      - FIRST_SUPERUSER=${FIRST_SUPERUSER}
      - FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD}
      - APP_URL=https://${DOMAIN}
      - FRONTEND_URL=https://${DOMAIN}
      - FIREBASE_SERVICE_ACCOUNT_JSON=${FIREBASE_SERVICE_ACCOUNT_JSON:-}
      - SMTP_HOST=${SMTP_HOST:-}
      - SMTP_PORT=${SMTP_PORT:-}
      - SMTP_USERNAME=${SMTP_USERNAME:-}
      - SMTP_PASSWORD=${SMTP_PASSWORD:-}
      - WEBHOOK_ENCRYPTION_KEY=${WEBHOOK_ENCRYPTION_KEY:-}
      - LITESTREAM_REPLICA_URL=${LITESTREAM_REPLICA_URL:-}
      - LITESTREAM_ACCESS_KEY_ID=${LITESTREAM_ACCESS_KEY_ID:-}
      - LITESTREAM_SECRET_ACCESS_KEY=${LITESTREAM_SECRET_ACCESS_KEY:-}
    ports:
      - "8090:8090"
    volumes:
      - vendel_data:/app/pb_data

volumes:
  vendel_data:

Environment variables

Create a .env file:

.env
FIRST_SUPERUSER=[email protected]
FIRST_SUPERUSER_PASSWORD=your-secure-password
DOMAIN=sms.yourdomain.com
FIREBASE_SERVICE_ACCOUNT_JSON={"type":"service_account",...}

Start the service

docker compose up -d

View logs

docker compose logs -f app

Backup with Litestream

For continuous SQLite backup to S3-compatible storage, add these to your .env:

LITESTREAM_REPLICA_URL=s3://my-bucket/vendel/data
LITESTREAM_ACCESS_KEY_ID=your-access-key
LITESTREAM_SECRET_ACCESS_KEY=your-secret-key

When set, Litestream automatically streams WAL changes and restores from the replica on startup.

Modem Agent (optional)

If you use USB GSM modems, the modem agent can run alongside the app as an opt-in Docker Compose service. Add these to your .env:

# Modem agent
MODEMS=dk_abc123:/dev/ttyUSB0:/dev/ttyUSB1
MODEM_DEVICE_0=/dev/ttyUSB0

Start with the modem profile:

docker compose --profile modem up -d

The modem-agent container waits for the app healthcheck to pass, then connects via Docker internal DNS. The host serial device is mapped into the container. See USB Modems for full setup instructions.

docker compose --profile modem logs -f modem-agent

Update

docker compose pull
docker compose up -d

Related