This guide covers running ORLY in Docker containers for integration testing.
The Docker setup provides:
┌─────────────────────────────────────────────┐
│ Docker Network (orly-network) │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ ORLY Relay │ │ relay-tester │ │
│ │ (badger mode) │ │ (optional) │ │
│ │ │ │ │ │
│ │ :3334 (WS) │ │ │ │
│ └─────────────────┘ └─────────────────┘ │
│ │ │
└─────────┼───────────────────────────────────┘
│
Published
to host
# Build ORLY image only
./scripts/docker-build.sh
# Build ORLY + relay-tester
./scripts/docker-build.sh --with-tester
# Basic test (start containers, verify connectivity)
./scripts/test-docker.sh
# Run with relay-tester
./scripts/test-docker.sh --relay-tester
# Keep containers running after test
./scripts/test-docker.sh --keep-running
# Skip rebuild (use existing images)
./scripts/test-docker.sh --skip-build
# Start containers
cd scripts
docker-compose -f docker-compose-test.yml up -d
# View logs
docker-compose -f docker-compose-test.yml logs -f
# Stop containers
docker-compose -f docker-compose-test.yml down
# Stop and remove volumes
docker-compose -f docker-compose-test.yml down -v
Multi-stage build for ORLY:
Stage 1: Builder
CGO_ENABLED=0Stage 2: Runtime
Builds relay-tester for automated testing:
Orchestrates the full stack:
Services:
- Configured with ORLYDBTYPE=badger (default) - Health check via HTTP - Auto-restart on failure
- Profile: test (optional) - Runs tests against ORLY - Exits after completion
The docker-compose file sets:
# Server
ORLY_LISTEN: 0.0.0.0
ORLY_PORT: 3334
ORLY_DATA_DIR: /data
# Application
ORLY_LOG_LEVEL: info
ORLY_APP_NAME: ORLY-Test
ORLY_ACL_MODE: none
Override via environment or .env file:
# Create .env file in scripts/
cat > scripts/.env << EOF
ORLY_LOG_LEVEL=debug
ORLY_ADMINS=npub1...
EOF
Persistent Data:
orly-data:/data - ORLY database and metadataInspect Volumes:
docker volume ls
docker volume inspect scripts_orly-data
Custom Bridge Network:
./scripts/test-docker.sh
What it does:
./scripts/test-docker.sh --relay-tester
Additional steps:
# Start and keep running
./scripts/test-docker.sh --keep-running
# Make changes to code
vim pkg/database/save-event.go
# Rebuild and restart
docker-compose -f scripts/docker-compose-test.yml up -d --build orly
# View logs
docker logs orly-relay -f
# Test changes
go run cmd/relay-tester/main.go -url ws://localhost:3334
# Stop when done
cd scripts && docker-compose -f docker-compose-test.yml down
# All services
docker-compose -f scripts/docker-compose-test.yml logs -f
# Specific service
docker logs orly-relay -f
# Last N lines
docker logs orly-relay --tail 50
# ORLY version
docker exec orly-relay /app/orly version
# Check ORLY processes
docker exec orly-relay ps aux
# Inspect data directory
docker exec orly-relay ls -la /data
# List networks
docker network ls
# Inspect orly network
docker network inspect scripts_orly-network
# Check health
docker inspect orly-relay | grep -A 10 Health
# View health check logs
docker inspect --format='{{json .State.Health}}' orly-relay | jq
Error: Cannot find libsecp256k1.so
# Ensure library exists
ls -l libsecp256k1.so
# Library should be in repository root
Error: Go module download fails
# Clear module cache
go clean -modcache
# Try building locally first
CGO_ENABLED=0 go build
ORLY fails health check
# Check logs
docker logs orly-relay
# Common issues:
# - Port already in use: docker ps (check for conflicts)
# - Bad configuration: docker exec orly-relay env
WebSocket connection fails
# Test from host
websocat ws://localhost:3334
# Test from container
docker exec orly-relay curl -v http://localhost:3334
# Check firewall
sudo iptables -L | grep 3334
Slow startup
# Increase health check timeouts in docker-compose-test.yml
start_period: 60s # Default is 20-30s
# Pre-pull images
docker pull golang:1.25-alpine
High memory usage
# Check resource usage
docker stats
# Limit container resources
# Add to docker-compose-test.yml:
deploy:
resources:
limits:
memory: 2G
cpus: '2'
name: Docker Integration Tests
on: [push, pull_request]
jobs:
docker-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build images
run: ./scripts/docker-build.sh --with-tester
- name: Run integration tests
run: ./scripts/test-docker.sh --relay-tester
- name: Upload logs on failure
if: failure()
uses: actions/upload-artifact@v3
with:
name: container-logs
path: |
scripts/orly-relay.log
docker-test:
image: docker:latest
services:
- docker:dind
script:
- ./scripts/docker-build.sh --with-tester
- ./scripts/test-docker.sh --relay-tester
artifacts:
when: on_failure
paths:
- scripts/*.log
Create a custom docker-compose override:
# docker-compose.override.yml
version: '3.8'
services:
orly:
environment:
- ORLY_LOG_LEVEL=debug
- ORLY_ADMINS=npub1...
- ORLY_ACL_MODE=follows
ports:
- "3335:3334" # Different host port
Test multiple ORLY instances:
# docker-compose-multi.yml
services:
orly-1:
extends:
file: docker-compose-test.yml
service: orly
container_name: orly-relay-1
ports:
- "3334:3334"
orly-2:
extends:
file: docker-compose-test.yml
service: orly
container_name: orly-relay-2
ports:
- "3335:3334"
# Start with --keep-running
./scripts/test-docker.sh --keep-running
# Run stress test
go run cmd/stresstest/main.go -url ws://localhost:3334 -connections 100
# Monitor resources
docker stats
# Profile ORLY
docker exec orly-relay sh -c 'curl http://localhost:6060/debug/pprof/profile?seconds=30 > /tmp/cpu.prof'
# Stop and remove containers
cd scripts && docker-compose -f docker-compose-test.yml down
# Remove volumes (data)
docker-compose -f docker-compose-test.yml down -v
# Remove images
docker rmi orly:latest orly-relay-tester:latest
# Remove networks
docker network rm scripts_orly-network
# Prune everything (careful!)
docker system prune -a --volumes
# Just stop containers (keep data)
docker-compose -f docker-compose-test.yml stop
# Remove only one service
docker-compose -f docker-compose-test.yml rm -s -f orly
# Clear ORLY data
docker volume rm scripts_orly-data