Self-Hosting
This guide covers deploying Ding to production.
1. Prepare the environment
Clone the repository on your server:
git clone https://github.com/UncleTeslim/ding
cd ding
Create production secrets:
npm install
npm run setup
This generates a .env file with a bcrypt password hash, JWT secret, and IP hashing salt.
Review the generated .env:
DING_ADMIN_USERNAME=admin
DING_ADMIN_PASSWORD_HASH=...
DING_JWT_SECRET=...
DING_IP_SALT=...
DING_DB_PATH=/app/data/ding.db
DING_TRUST_PROXY=true
PORT=3000
NODE_ENV=production
2. Run with Docker Compose
docker compose up --build -d
Check health:
curl http://localhost:3000/health
Expected response:
{ "ok": true, "db": "connected" }
3. Configure a reverse proxy
Ding expects HTTPS to be handled by your reverse proxy.
Caddy
ding.example.com {
reverse_proxy localhost:3000
}
Nginx
server {
server_name ding.example.com;
location / {
proxy_pass http://localhost:3000;
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;
}
}
4. Embed the widget
After the instance is reachable over HTTPS, embed the widget:
<script
src="https://ding.example.com/widget.js"
data-position="bottom-right"
data-color="#155eef"
data-trigger="both"
async
></script>
5. Backups
Ding stores data in SQLite. Back up the database file regularly.
docker compose stop
cp /path/to/ding.db /path/to/backups/ding-$(date +%Y-%m-%d).db
docker compose up -d
For busier installations, use SQLite online backup tooling or snapshot the volume at the infrastructure layer.
6. Upgrades
git pull
docker compose up --build -d
Migrations run automatically on startup.
7. Operational checks
- Confirm
/healthreturnsok - Confirm the admin dashboard loads
- Confirm
/widget.jsreturns JavaScript - Confirm the widget appears in a test page
- Confirm announcements remain after container restart