A production-ready Nostr relay server.
638
This guide covers running a production-ready Nostr Relay Server with Postgres and Redis, using Docker Compose. It also covers optional NIP-96 file storage, environment configurations, and monitoring.
Before starting, ensure you have:
docker --version)docker compose version)Create a project directory, e.g., nostr-relay, with the following structure:
nostr-relay/
├─ docker-compose.yml
├─ .env # optional file to store environment variables
└─ data/
└─ postgres/ # PostgreSQL persistent storage
You can set variables in the docker-compose.yml directly, or store them in a .env file:
# .env
NODE_ENV=production
PORT=8080
DATABASE_URL=postgres://user:password@postgres:5432/nostr
REDIS_URL=redis://redis:6379
RELAY_NAME=My Nostr Relay
RELAY_DESCRIPTION=Secure Nostr relay server
REQUIRE_AUTH_FOR_WRITE=false
RUN_MIGRATIONS=1
MAX_MESSAGE_SIZE=1048576
STORAGE_METHOD=local # optional, for NIP-96
BASE_URL=http://your-domain.com/files
MAX_FILE_SIZE=104857600 # optional 100 MB max file size
Here’s a full docker-compose.yml for production:
version: "3.9"
services:
nostr-relay:
image: taksa1990/nostr-relay:latest
container_name: nostr-relay
environment:
NODE_ENV: ${NODE_ENV}
PORT: ${PORT}
DATABASE_URL: ${DATABASE_URL}
REDIS_URL: ${REDIS_URL}
RELAY_NAME: ${RELAY_NAME}
RELAY_DESCRIPTION: ${RELAY_DESCRIPTION}
REQUIRE_AUTH_FOR_WRITE: ${REQUIRE_AUTH_FOR_WRITE}
RUN_MIGRATIONS: ${RUN_MIGRATIONS}
MAX_MESSAGE_SIZE: ${MAX_MESSAGE_SIZE}
STORAGE_METHOD: ${STORAGE_METHOD}
BASE_URL: ${BASE_URL}
MAX_FILE_SIZE: ${MAX_FILE_SIZE}
ports:
- "8080:8080"
depends_on:
- postgres
- redis
restart: unless-stopped
networks:
- nostr-net
volumes:
- nostr-files:/app/files # for NIP-96 local file storage
postgres:
image: postgres:13
container_name: nostr-postgres
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: nostr
volumes:
- nostr-postgres-data:/var/lib/postgresql/data
networks:
- nostr-net
restart: unless-stopped
redis:
image: redis:6
container_name: nostr-redis
networks:
- nostr-net
restart: unless-stopped
volumes:
nostr-postgres-data:
nostr-files:
networks:
nostr-net:
docker compose pull
docker compose up -d
docker compose logs -f nostr-relay
http://HOST:8080/healthhttp://HOST:8080/readyhttp://HOST:8080/.well-known/nostr.jsonhttp://HOST:8080/metricsnostr-files volume.STORAGE_METHOD=s3 and add S3 credentials:S3_BUCKET=your-bucket-name
S3_REGION=your-region
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
${BASE_URL}/filename.RUN_MIGRATIONS=1 on the first run to initialize the database.RUN_MIGRATIONS=0 to prevent accidental schema changes./metrics.scrape_configs:
- job_name: nostr-relay
static_configs:
- targets: ['YOUR_HOST:8080']
pg_dump:docker exec nostr-postgres pg_dump -U user nostr > nostr_backup.sql
nostr-files volume.8080 is free.nostr-files volume.MAX_MESSAGE_SIZE or limit events stored.Content type
Image
Digest
sha256:11a72bb2e…
Size
68.8 MB
Last updated
6 months ago
Requires Docker Desktop 4.37.1 or later.