-
Notifications
You must be signed in to change notification settings - Fork 3
Docker Deployment
Run D1 Database Manager in Docker containers.
D1 Manager can be deployed using Docker for local development, testing, or self-hosted environments. The Docker setup provides an isolated, reproducible environment.
Important Notes:
- Docker deployment is primarily for the frontend interface
- The Cloudflare Worker backend still requires deployment to Cloudflare's edge network for production use with real D1 databases
- You must set up the d1-manager-metadata database in Cloudflare D1 (see below)
- R2 Backup/Restore and Scheduled Backups require the Worker + R2; Docker deployments can still use download/import for local backups
Docker is suitable for:
- β Local development and testing
- β Self-hosted frontend with Cloudflare Worker backend
- β Custom deployment environments
- β Isolated testing environments
Docker is NOT suitable for:
- β Complete standalone operation (requires Cloudflare Worker)
- β Replacing Cloudflare Worker deployment
- Docker installed (download)
- Docker Compose (included with Docker Desktop)
- Cloudflare Account with D1 access
- Wrangler CLI for metadata database setup
Verify Installation:
docker --version # Should show Docker version
docker compose version # Should show compose version
wrangler --version # Should show wrangler versionBefore running the Docker container, you must create and initialize the metadata database in Cloudflare D1:
# 1. Login to Cloudflare
wrangler login
# 2. Create the metadata database
wrangler d1 create d1-manager-metadata
# 3. Clone the repository to get schema.sql
git clone https://github.com/neverinfamous/d1-manager.git
cd d1-manager
# 4. Initialize the schema
wrangler d1 execute d1-manager-metadata --remote --file=worker/schema.sqlNote for existing users upgrading: If you're upgrading from an earlier version, run the schema command again to add new tables (like undo_history for the rollback feature). Existing tables won't be affected:
# Safe to run on existing metadata database
wrangler d1 execute d1-manager-metadata --remote --file=worker/schema.sqlVerify:
wrangler d1 execute d1-manager-metadata --remote \
--command="SELECT name FROM sqlite_master WHERE type='table';"You should see: query_history, saved_queries, and undo_history
docker pull writenotenow/d1-manager:latestdocker run -d \
--name d1-manager \
-p 8080:80 \
-e VITE_WORKER_API=https://your-worker.workers.dev \
writenotenow/d1-manager:latestAccess: http://localhost:8080
git clone https://github.com/neverinfamous/d1-manager.git
cd d1-managerdocker build -t d1-manager .Dockerfile:
# Build stage
FROM node:24-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
RUN npm ci
# Copy source code
COPY . .
# Build application
RUN npm run build
# Production stage
FROM nginx:alpine
# Copy built files
COPY --from=builder /app/dist /usr/share/nginx/html
# Copy nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]docker run -d \
--name d1-manager \
-p 8080:80 \
d1-managerservices:
d1-manager:
image: writenotenow/d1-manager:latest
container_name: d1-manager
ports:
- "8080:80"
environment:
- VITE_WORKER_API=https://your-worker.workers.dev
restart: unless-stoppedStart:
docker compose up -dStop:
docker compose downView Logs:
docker compose logs -fRebuild:
docker compose up -d --buildVITE_WORKER_API:
- Cloudflare Worker API endpoint
- Required for production use
- Format:
https://your-worker.your-account.workers.dev - Or custom domain:
https://api.yourdomain.com
Example:
docker run -d \
-p 8080:80 \
-e VITE_WORKER_API=https://d1-api.example.com \
writenotenow/d1-manager:latestIf VITE_WORKER_API is not set:
- Uses
window.location.origin - Expects worker at same domain
- Suitable for proxied setups
Default:
-p 8080:80Custom Port:
-p 3000:80 # Access on http://localhost:3000HTTPS with Reverse Proxy:
# Use nginx or Caddy as reverse proxy
# See Reverse Proxy section belowOption 1: Cloud Worker (Recommended)
Docker Container (Frontend)
β HTTPS
Cloudflare Worker (Backend)
β HTTPS
Cloudflare D1 (Databases)
Option 2: Docker Network (Local Dev)
Docker Container (Frontend)
β HTTP
Docker Container (Worker Dev)
β Mock Data
nginx.conf:
server {
listen 80;
server_name d1.yourdomain.com;
location / {
proxy_pass http://localhost:8080;
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;
}
}With HTTPS:
server {
listen 443 ssl;
server_name d1.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Caddyfile:
d1.yourdomain.com {
reverse_proxy localhost:8080
}
Benefits:
- Automatic HTTPS
- Automatic certificate renewal
- Simple configuration
docker-compose.yml with Traefik:
services:
traefik:
image: traefik:v2.10
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
d1-manager:
image: writenotenow/d1-manager:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.d1.rule=Host(`d1.yourdomain.com`)"
- "traefik.http.routers.d1.entrypoints=websecure"
- "traefik.http.routers.d1.tls=true"Note: Frontend is stateless (no data stored in container).
All data resides in:
- Cloudflare D1 databases (via Worker)
- Browser localStorage (theme preference)
No volumes needed for data persistence.
1. Use Specific Version Tag:
docker pull writenotenow/d1-manager:<version>2. Enable Health Checks:
services:
d1-manager:
image: writenotenow/d1-manager:<version>
healthcheck:
test:
["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost"]
interval: 30s
timeout: 10s
retries: 33. Set Resource Limits:
services:
d1-manager:
image: writenotenow/d1-manager:<version>
deploy:
resources:
limits:
cpus: "0.5"
memory: 512M4. Use Restart Policy:
services:
d1-manager:
restart: unless-stopped5. Enable Logging:
services:
d1-manager:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"1. Run as Non-Root:
# In Dockerfile
USER nginx2. Read-Only Filesystem:
services:
d1-manager:
read_only: true
tmpfs:
- /tmp
- /var/cache/nginx3. Drop Capabilities:
services:
d1-manager:
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE4. Use HTTPS:
- Always use reverse proxy with HTTPS
- Never expose directly to internet without TLS
Check status:
docker ps
docker inspect d1-managerView logs:
docker logs d1-manager
docker logs -f d1-manager # Follow logsResource usage:
docker stats d1-managerHTTP Health Check:
curl http://localhost:8080/Expected: HTML page loads successfully.
docker pull writenotenow/d1-manager:latest
docker stop d1-manager
docker rm d1-manager
docker run -d \
--name d1-manager \
-p 8080:80 \
-e VITE_WORKER_API=https://your-worker.workers.dev \
writenotenow/d1-manager:latestdocker compose pull
docker compose up -d# Start new container with different name
docker run -d \
--name d1-manager-new \
-p 8081:80 \
writenotenow/d1-manager:latest
# Test new container
curl http://localhost:8081/
# Switch traffic (update reverse proxy or port mapping)
# Stop old container
docker stop d1-manager
docker rm d1-manager
# Rename new container
docker rename d1-manager-new d1-managerCheck logs:
docker logs d1-managerCommon issues:
- Port already in use
- Invalid environment variables
- Insufficient resources
Check container is running:
docker ps | grep d1-managerCheck port mapping:
docker port d1-managerTest locally:
docker exec -it d1-manager wget -O- http://localhostVerify VITE_WORKER_API:
docker inspect d1-manager | grep VITE_WORKER_APITest worker endpoint:
curl https://your-worker.workers.dev/api/databasesCheck CORS settings in worker configuration.
Check stats:
docker stats d1-managerSet memory limit:
docker run -d \
--name d1-manager \
-p 8080:80 \
--memory="512m" \
writenotenow/d1-manager:latestapiVersion: apps/v1
kind: Deployment
metadata:
name: d1-manager
spec:
replicas: 3
selector:
matchLabels:
app: d1-manager
template:
metadata:
labels:
app: d1-manager
spec:
containers:
- name: d1-manager
image: writenotenow/d1-manager:<version>
ports:
- containerPort: 80
env:
- name: VITE_WORKER_API
value: "https://your-worker.workers.dev"
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "250m"
memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
name: d1-manager
spec:
selector:
app: d1-manager
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancerkubectl apply -f deployment.yamlOfficial Image: writenotenow/d1-manager
Available Tags:
-
latest- Latest stable release -
<version>- Specific version -
dev- Development builds
Pull:
docker pull writenotenow/d1-manager:latest- Production Deployment - Deploy Worker to Cloudflare
- Configuration - Configure environment
- Local Development - Development setup
- Troubleshooting - Common issues
Need Help? See Troubleshooting or open an issue.
- Database Management
- R2 Backup Restore
- Scheduled Backups
- Table Operations
- Query Console
- Schema Designer
- Column Management
- Bulk Operations
- Job History
- Time Travel
- Read Replication
- Undo Rollback
- Foreign Key Visualizer
- ER Diagram
- Foreign Key Dependencies
- Foreign Key Navigation
- Circular Dependency Detector
- Cascade Impact Simulator
- AI Search
- FTS5 Full Text Search
- Cross Database Search
- Index Analyzer
- Database Comparison
- Database Optimization