Docker Deployment Guide
This guide explains how to deploy the full Solana starter stack using Docker and Docker Compose.
Overview
The Docker setup includes:
- PostgreSQL - Database for indexer
- Go Indexer - Blockchain indexer service
- Next.js Frontend - Web application
Note: The Solana validator runs on your host machine (localnet) or you can connect to devnet/mainnet.
Prerequisites
- Docker 20.10+
- Docker Compose 2.0+
- Running Solana validator (for localnet)
- Deployed Anchor programs
Quick Start
1. Configure Environment
cp .env.docker .env
Edit .env with your configuration:
- For localnet: Use
http://localhost:8899 - For devnet: Use
https://api.devnet.solana.com - For mainnet: Use
https://api.mainnet-beta.solana.com
Update program IDs:
cd starter_program
anchor keys list
# Copy the program IDs to .env
# NEXT_PUBLIC_STARTER_PROGRAM_ID=<your-starter-program-id>
# NEXT_PUBLIC_COUNTER_PROGRAM_ID=<your-counter-program-id>
2. Build and Start Services
docker-compose up -d
This will:
- Start PostgreSQL database
- Build and start Go indexer
- Build and start Next.js frontend
3. Verify Services
docker-compose ps
docker-compose logs indexer
docker-compose logs frontend
curl http://localhost:8080/health
curl http://localhost:3000
4. Access Applications
- Frontend: http://localhost:3000
- Indexer API: http://localhost:8080
- PostgreSQL: localhost:5432
Docker Compose Services
PostgreSQL (postgres)
Database for storing indexed blockchain data.
Ports: 5432 Volume: postgres_data (persistent storage) Health Check: Automatic with retry
Go Indexer (indexer)
High-performance blockchain indexer.
Ports: 8080 Depends on: PostgreSQL Configuration: Via environment variables in .env
Key environment variables:
SOLANA_RPC_URL- Solana RPC endpointSOLANA_WS_URL- Solana WebSocket endpointDATABASE_URL- PostgreSQL connection stringSTART_SLOT- Starting slot for indexingPOLL_INTERVAL_MS- Polling intervalBATCH_SIZE- Blocks per batchMAX_CONCURRENCY- Concurrent workers
Next.js Frontend (frontend)
Web application for interacting with Anchor programs.
Ports: 3000 Depends on: Indexer Build Args: Program IDs and network configuration
Development Workflow
Building Services
docker-compose build
docker-compose build indexer
docker-compose build frontend
Starting/Stopping Services
docker-compose up -d
docker-compose down
docker-compose restart indexer
Viewing Logs
docker-compose logs -f
docker-compose logs -f indexer
docker-compose logs -f frontend --tail 100
Executing Commands in Containers
docker-compose exec indexer sh
docker-compose exec postgres psql -U postgres -d solana_indexer
Localnet Development
When developing with localnet, the validator runs on your host machine, not in Docker.
Terminal 1: Start Validator
solana-test-validator \
--clone TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA \
--clone ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL \
--reset \
--quiet
Terminal 2: Deploy Programs
cd starter_program
solana config set --url localhost
anchor build && anchor deploy
Terminal 3: Start Docker Stack
docker-compose up -d
docker-compose logs -f
The indexer will connect to host.docker.internal:8899 to reach your local validator.
Production Deployment
Devnet
cp .env.docker .env
# Edit .env
SOLANA_RPC_URL=https://api.devnet.solana.com
SOLANA_WS_URL=wss://api.devnet.solana.com
NEXT_PUBLIC_SOLANA_RPC_HOST=https://api.devnet.solana.com
NEXT_PUBLIC_SOLANA_NETWORK=devnet
START_SLOT=latest
POLL_INTERVAL_MS=5000
docker-compose up -d
Mainnet-Beta
cp .env.docker .env
# Edit .env
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
SOLANA_WS_URL=wss://api.mainnet-beta.solana.com
NEXT_PUBLIC_SOLANA_RPC_HOST=https://api.mainnet-beta.solana.com
NEXT_PUBLIC_SOLANA_NETWORK=mainnet-beta
START_SLOT=latest
POLL_INTERVAL_MS=10000
BATCH_SIZE=5
docker-compose up -d
Note: For production, consider using:
- Dedicated RPC providers (QuickNode, Alchemy, Helius)
- Nginx reverse proxy
- SSL/TLS certificates
- Environment-specific .env files
- Health monitoring
- Log aggregation
Database Management
Connect to PostgreSQL
docker-compose exec postgres psql -U postgres -d solana_indexer
Run Migrations
docker-compose exec indexer sh -c "go run migrations/*.go"
Backup Database
docker-compose exec postgres pg_dump -U postgres solana_indexer > backup.sql
Restore Database
cat backup.sql | docker-compose exec -T postgres psql -U postgres -d solana_indexer
Troubleshooting
Indexer Can’t Connect to Validator
Problem: connection refused errors
Solution:
- Ensure validator is running
- For localnet, use
host.docker.internal:8899in Docker - Check firewall rules
- Verify RPC URL in
.env
Frontend Build Fails
Problem: Build errors during docker-compose up
Solution:
cd frontend
pnpm install
pnpm run type-check
docker-compose build frontend --no-cache
Database Connection Issues
Problem: Indexer can’t connect to PostgreSQL
Solution:
docker-compose exec postgres pg_isready -U postgres
docker-compose logs postgres
docker-compose down -v
docker-compose up -d
Port Already in Use
Problem: port 3000 already in use
Solution:
lsof -ti:3000 | xargs kill
# Or change ports in docker-compose.yml
ports:
- "3001:3000"
Monitoring
Check Service Health
curl http://localhost:8080/health
docker-compose ps
docker stats
View Performance Metrics
curl http://localhost:8080/debug/pprof/
docker-compose exec indexer sh
ps aux
top
Cleaning Up
Stop Services (Keep Data)
docker-compose down
Stop Services (Remove Volumes)
docker-compose down -v
Remove Images
docker-compose down --rmi all
Full Cleanup
docker-compose down -v --rmi all
docker system prune -a
Advanced Configuration
Custom Docker Compose File
Create docker-compose.override.yml:
version: '3.8'
services:
indexer:
environment:
LOG_LEVEL: debug
volumes:
- ./go_indexer:/app
frontend:
command: npm run dev
volumes:
- ./frontend:/app
- /app/node_modules
Multiple Environments
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Resource Limits
Edit docker-compose.yml:
services:
indexer:
deploy:
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G
CI/CD Integration
GitHub Actions Example
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build and Push
run: |
docker-compose build
docker-compose push
- name: Deploy to Server
run: |
ssh user@server 'cd /app && docker-compose pull && docker-compose up -d'