Docker Installation
BugPin is a self-hosted visual bug reporting tool that can be installed with Docker in under 2 minutes. This guide covers Docker Compose setup, bind mounts and named volumes, file permissions, data persistence, backup, and updating to new releases.
Prerequisites
- Docker Engine 20.10+ and Docker Compose v2+ installed
- CPU: 1 core minimum (2 cores recommended for production)
- RAM: 512MB minimum, 1GB recommended for production
- Disk: 1GB minimum for the application; additional space depends on screenshot and attachment volume (plan for 10–50MB per 1,000 reports)
- A Linux, macOS, or Windows host
Quick Start
Docker (Recommended)
mkdir bugpin && cd bugpin
curl -O https://raw.githubusercontent.com/aranticlabs/bugpin/main/docker-compose.yml
docker compose up -d
BugPin is now running at http://localhost:7300
Docker Command
docker run -d --restart=always -p 7300:7300 -v bugpin-data:/data --name bugpin registry.arantic.cloud/bugpin/bugpin:latest
Bun
Requirements:
- Bun v1.1 or later
- Git
git clone https://github.com/aranticlabs/bugpin.git
cd bugpin
bun install
bun run build
bun run start
BugPin is now running at http://localhost:7300
File Permissions for Bind Mounts
If you're using a bind mount (./data:/data), you need to set proper permissions for the data directory:
# Option 1: If you know the UID (usually 1000 for bun user)
sudo chown -R 1000:1000 ./data
# Option 2: Check the exact UID first (to be sure)
docker run --rm registry.arantic.cloud/bugpin/bugpin:main id bun
# This will show: uid=1000(bun) gid=1000(bun) groups=1000(bun)
# Then use that UID:
sudo chown -R 1000:1000 ./data
If you don't want to manage permissions, use a named volume instead of a bind mount in your docker-compose.yml:
volumes:
- bugpin-data:/data
volumes:
bugpin-data:
driver: local
Named volumes are managed by Docker and don't require manual permission setup.
Manual Docker Compose Setup
1. Create the Docker Compose file
Create a file named docker-compose.yml:
services:
bugpin:
image: registry.arantic.cloud/bugpin/bugpin:latest
container_name: bugpin
restart: unless-stopped
ports:
- "7300:7300"
volumes:
- ./data:/data
environment:
- LOG_LEVEL=info
healthcheck:
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:7300/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
2. Start BugPin
docker compose up -d
3. Login and change password
Open http://localhost:7300 and login with:
- Email:
admin@example.com - Password:
changeme123
Change the default password immediately after first login in Settings → Users.
That's it! BugPin is now running.
What's Configured Automatically
- Session key: Generated automatically and stored in the data volume
- Database: SQLite, stored in the data volume
- Admin account: Created on first run with default credentials
Data Persistence
BugPin uses Docker volumes to persist data. Understanding how volumes work is important for backups, migrations, and troubleshooting.
Volume Configuration
The default configuration uses a bind mount:
volumes:
- ./data:/data
What this means:
./data- Directory on your host machine (same location as docker-compose.yml)/data- Directory inside the container where BugPin stores data
Example:
If you place docker-compose.yml in /home/user/bugpin/, Docker will create /home/user/bugpin/data/ and mount it to /data inside the container.
What Gets Stored
Inside the ./data directory, you'll find:
./data/
├── bugpin.db # SQLite database (all reports, users, settings)
├── .secret # Auto-generated session encryption key
└── uploads/ # User-uploaded files
├── screenshots/ # Bug report screenshots
├── attachments/ # File attachments
└── branding/ # Custom logo and branding assets
Bind Mount vs Named Volume
Option 1: Bind Mount (Default, Recommended)
volumes:
- ./data:/data
Advantages:
- Easy to find and access (right next to docker-compose.yml)
- Simple to backup (just copy the folder)
- Easy to inspect files directly
- Simple to migrate (move the entire directory)
Disadvantages:
- Can be accidentally deleted
- Permissions can be tricky on some systems
Option 2: Named Volume
volumes:
- bugpin-data:/data
volumes:
bugpin-data:
driver: local
Advantages:
- Managed by Docker (stored in
/var/lib/docker/volumes/) - Better isolation and permissions
- Less likely to be accidentally deleted
Disadvantages:
- Harder to find and access directly
- More complex backup process
- Need to use
docker volumecommands
Backup
For bind mounts (default):
# Stop the container
docker compose down
# Backup the data directory
tar -czf bugpin-backup-$(date +%Y%m%d).tar.gz ./data
# Restart
docker compose up -d
For named volumes:
# Stop the container
docker compose down
# Backup the named volume
docker run --rm \
-v bugpin-data:/data \
-v $(pwd):/backup \
alpine tar -czf /backup/bugpin-backup-$(date +%Y%m%d).tar.gz /data
# Restart
docker compose up -d
Restore
For bind mounts:
docker compose down
rm -rf ./data
tar -xzf bugpin-backup-20260103.tar.gz
docker compose up -d
For named volumes:
docker compose down
docker volume rm bugpin-data
docker volume create bugpin-data
docker run --rm \
-v bugpin-data:/data \
-v $(pwd):/backup \
alpine tar -xzf /backup/bugpin-backup-20260103.tar.gz -C /
docker compose up -d
Migration to Another Server
With bind mount (easiest):
# On old server
docker compose down
tar -czf bugpin-full.tar.gz docker-compose.yml data/
# Copy to new server
scp bugpin-full.tar.gz user@newserver:/opt/bugpin/
# On new server
tar -xzf bugpin-full.tar.gz
docker compose up -d
Custom Data Location
To store data in a different location:
volumes:
- /path/to/your/data:/data
For example, to use a dedicated data partition:
volumes:
- /mnt/data/bugpin:/data
Troubleshooting Volumes
Check what's stored in the volume:
# For bind mount
ls -lah ./data
# For named volume
docker run --rm -v bugpin-data:/data alpine ls -lah /data
Check disk usage:
# For bind mount
du -sh ./data
# For named volume
docker system df -v | grep bugpin
Fix permissions (if container can't write to bind mount):
sudo chown -R 1000:1000 ./data
Update
Before updating, make sure to back up your data so you can roll back if needed.
Pull and Restart
docker compose pull && docker compose up -d
Database migrations run automatically on startup — no manual steps are needed.
Verify the Update
Check the container is running and healthy
docker compose ps
Check logs for any migration or startup errors
docker compose logs --tail 50
Rolling Back
If something goes wrong, revert to the previous image:
docker compose down
# Restore your data backup
cp -r ./data-backup-YYYYMMDD ./data
Pin the previous version in docker-compose.yml and restart
docker compose up -d
Custom Port
To use a different port, edit the ports section:
ports:
- "8080:7300" # Access on port 8080
Reverse Proxy
For production deployments, place BugPin behind a reverse proxy with SSL.
Nginx Example
server {
listen 443 ssl http2;
server_name bugs.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:7300;
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;
client_max_body_size 10M;
}
}
Traefik Example
Add labels to your docker-compose.yml:
services:
bugpin:
# ... existing configuration ...
labels:
- "traefik.enable=true"
- "traefik.http.routers.bugpin.rule=Host(`bugs.yourdomain.com`)"
- "traefik.http.routers.bugpin.entrypoints=websecure"
- "traefik.http.routers.bugpin.tls.certresolver=letsencrypt"
- "traefik.http.services.bugpin.loadbalancer.server.port=7300"
Health Check
BugPin includes automatic health monitoring:
docker inspect --format='{{.State.Health.Status}}' bugpin