Dubly’s install script handles everything needed to run a production URL shortener: Go, Caddy for HTTPS, systemd service, firewall configuration, and optional S3 backups.
System requirements
- Ubuntu or Debian server
- Root access (via sudo)
- Domain pointed to your server via DNS A record
Quick install
Run the install script on a fresh server:
curl -fsSL https://raw.githubusercontent.com/scmmishra/dubly/main/scripts/install.sh | sudo bash
Or clone the repository first:
git clone https://github.com/scmmishra/dubly.git
cd dubly
sudo bash scripts/install.sh
The script will prompt you for:
- App name (defaults to “Dubly”)
- Admin domain (e.g.,
dubly.example.com)
- Redirect domains (comma-separated, can include admin domain)
- API password (leave blank to auto-generate)
- S3 backup configuration (optional but recommended)
- MaxMind GeoIP license key (optional, for geographic analytics)
What the script installs
System dependencies
Installs git, curl, and ufw (firewall) via apt.
Go toolchain
Downloads and installs Go 1.24.0 to /usr/local/go.# Architecture detection and download
ARCH="$(dpkg --print-architecture)"
GO_TAR="go1.24.0.linux-${ARCH}.tar.gz"
curl -fsSL "https://go.dev/dl/$GO_TAR" -o "/tmp/$GO_TAR"
tar -C /usr/local -xzf "/tmp/$GO_TAR"
Litestream
Installs Litestream 0.3.13 for continuous SQLite replication to S3 (if configured).LITESTREAM_DEB="litestream-v0.3.13-linux-${ARCH}.deb"
curl -fsSL "https://github.com/benbjohnson/litestream/releases/download/v0.3.13/${LITESTREAM_DEB" -o "/tmp/${LITESTREAM_DEB}"
dpkg -i "/tmp/${LITESTREAM_DEB}"
Caddy web server
Installs Caddy from the official apt repository for automatic HTTPS.curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt-get update
apt-get install caddy
Dubly repository
Clones the repository to /opt/dubly and builds the binary.git clone https://github.com/scmmishra/dubly.git /opt/dubly
cd /opt/dubly
go build -o dubly ./cmd/server
Environment configuration
Creates /opt/dubly/.env with your settings:DUBLY_PASSWORD=your-password
DUBLY_DOMAINS=dubly.example.com,short.io
DUBLY_PORT=8080
DUBLY_DB_PATH=./dubly.db
DUBLY_APP_NAME=Dubly
DUBLY_GEOIP_PATH=./GeoLite2-City.mmdb
# Optional S3 backups
LITESTREAM_S3_BUCKET=my-bucket
LITESTREAM_S3_ENDPOINT=https://s3.amazonaws.com
LITESTREAM_S3_REGION=us-east-1
LITESTREAM_ACCESS_KEY_ID=...
LITESTREAM_SECRET_ACCESS_KEY=...
File permissions are set to 600 for security. Systemd service
Creates /etc/systemd/system/dubly.service:[Unit]
Description=Dubly URL Shortener
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/dubly
EnvironmentFile=/opt/dubly/.env
Environment="PATH=/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/opt/dubly/dubly
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
When S3 backups are enabled, ExecStart points to /opt/dubly/scripts/start.sh instead, which wraps the binary with Litestream replication. Caddyfile
Creates /etc/caddy/Caddyfile for automatic HTTPS:dubly.example.com short.io {
reverse_proxy localhost:8080
header {
X-Frame-Options "DENY"
X-Content-Type-Options "nosniff"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
Firewall rules
Configures UFW to allow HTTP/HTTPS and block direct access to port 8080:ufw allow 80/tcp
ufw allow 443/tcp
ufw deny 8080/tcp
ufw allow OpenSSH
ufw enable
Service startup
Enables and starts both services:systemctl daemon-reload
systemctl enable dubly
systemctl restart dubly
systemctl enable caddy
systemctl restart caddy
Post-installation
Once complete, the script displays:
- Admin URL (e.g.,
https://dubly.example.com)
- API password (if auto-generated)
- Useful systemd commands
- Example API test command
If you auto-generated your password, save it immediately. It’s stored in /opt/dubly/.env but won’t be shown again in the terminal.
Updating Dubly
To pull the latest changes and rebuild:
sudo /opt/dubly/scripts/install.sh --update
This runs:
git pull origin main
go build -o dubly ./cmd/server
systemctl restart dubly
Adding domains
To add a new domain to an existing installation:
sudo bash /opt/dubly/scripts/add-domain.sh newdomain.com
This updates .env and Caddyfile, then restarts both services. You still need to point a DNS A record to your server.
Manual installation
If you prefer not to use the install script:
Clone repository
git clone https://github.com/scmmishra/dubly.git
cd dubly
Build binary
go build -o dubly ./cmd/server
Configure environment
Create a .env file with required variables:DUBLY_PASSWORD=your-secret-key
DUBLY_DOMAINS=short.io,go.example.com
See Configuration for all available options. Set up reverse proxy
Configure your web server (Caddy, nginx, etc.) to proxy to localhost:8080 with HTTPS.
Run Dubly
Or create a systemd service for production.
Troubleshooting
Check service status
systemctl status dubly
systemctl status caddy
View logs
journalctl -u dubly -f
journalctl -u caddy -f
Test without Caddy
If Caddy is misconfigured, test Dubly directly:
curl http://localhost:8080/api/links -H "X-API-Key: your-password"
The install script is idempotent and safe to re-run. It skips already-installed dependencies and prompts before overwriting configuration files.