This guide walks you through setting up your own Ethereum Sepolia testnet node with both execution and consensus layers. You will:
- Install Docker, Nginx, and Certbot
- Configure Geth (execution) and Prysm (consensus) clients
- Set up reverse proxy with SSL
- Monitor and maintain your node
This setup provides you with your own dedicated RPC endpoints for Sepolia (ETH & Beacon).
1. Hardware Requirements
| Component | Requirement | Recommended |
|---|---|---|
| CPU | 4 Core | 8 Core |
| RAM | 16 GB | 32 GB |
| Storage | 1 TB SSD | 2 TB NVMe SSD |
| Network | 10 Mbps stable | 25+ Mbps |
Check our Server Provider List for recommended options.
2. Installation
a. Install Dependencies
Ensure you have the required software installed:
Install Nginx:
sudo apt update -qy
sudo apt install nginx -y Start and enable Nginx:
sudo systemctl start nginx
sudo systemctl enable nginx Check status:
sudo systemctl status nginx Install Certbot for SSL:
sudo apt install certbot python3-certbot-nginx -y b. Setup Ethereum Node
Create project directory:
mkdir sepolia-rpc && cd sepolia-rpc Create Docker Compose file:
nano docker-compose.yml Add Docker Compose Configuration:
services:
geth:
image: ethereum/client-go:v1.15.11
container_name: geth-sepolia
restart: unless-stopped
ports:
- "127.0.0.1:8545:8545" # HTTP RPC (localhost only)
- "30303:30303" # P2P TCP
- "30303:30303/udp" # P2P UDP
volumes:
- ./data/geth-sepolia:/root/.ethereum
- ./data/jwt.hex:/root/jwt.hex
command: >
--sepolia
--http
--http.addr "0.0.0.0"
--http.port 8545
--http.api "eth,net,web3"
--http.corsdomain "*"
--http.vhosts "*"
--authrpc.addr "0.0.0.0"
--authrpc.port 8551
--authrpc.vhosts "*"
--authrpc.jwtsecret /root/jwt.hex
--cache 2048
--syncmode snap
deploy:
resources:
limits:
memory: 16G
reservations:
memory: 8G
networks:
- sepolia-network
prysm:
image: gcr.io/prysmaticlabs/prysm/beacon-chain:v6.0.1
container_name: prysm-sepolia
restart: unless-stopped
depends_on:
- geth
ports:
- "127.0.0.1:3500:3500" # HTTP API (localhost only)
- "127.0.0.1:4000:4000" # RPC (localhost only)
- "13000:13000" # P2P TCP
- "12000:12000/udp" # P2P UDP
volumes:
- ./data/prysm:/data
- ./data/jwt.hex:/root/jwt.hex
command: >
--datadir=/data
--sepolia
--execution-endpoint=http://geth:8551
--rpc-host=0.0.0.0
--rpc-port=4000
--grpc-gateway-host=0.0.0.0
--grpc-gateway-port=3500
--jwt-secret=/root/jwt.hex
--genesis-beacon-api-url=https://sepolia.checkpoint-sync.ethpandaops.io
--checkpoint-sync-url=https://sepolia.checkpoint-sync.ethpandaops.io
--accept-terms-of-use
--http-modules=beacon,config,node
--min-sync-peers=1
deploy:
resources:
limits:
memory: 10G
reservations:
memory: 6G
networks:
- sepolia-network
networks:
sepolia-network:
name: sepolia-network
driver: bridge
volumes:
geth-sepolia:
prysm: c. Initialize and Start Services
Create the JWT secret file:
mkdir -p data
openssl rand -hex 32 > data/jwt.hex Start the services:
docker compose up -d View Geth logs:
docker logs -f geth-sepolia View Prysm logs:
docker logs -f prysm-sepolia Monitor both services:
docker compose logs -f 3. Nginx Reverse Proxy Setup
a. Configure Nginx for Geth (Execution Layer)
Create Nginx configuration for Geth:
sudo nano /etc/nginx/sites-available/sepolia-eth-rpc Add the following configuration:
server {
server_name eth-sepolia.yourdomain.com;
access_log /var/log/nginx/sepolia_eth_rpc_access.log;
error_log /var/log/nginx/sepolia_eth_rpc_error.log;
location / {
# IP whitelist - replace with your actual IPs
allow 172.16.0.0/12; # Docker networks
allow 10.0.0.0/8; # Private networks
allow 192.168.0.0/16; # Private networks
allow 203.0.113.1; # Your specific IP
allow 198.51.100.0/24; # Your network range
# Deny all other traffic
deny all;
# Proxy configuration
proxy_pass http://127.0.0.1:8545;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_cache_bypass $http_upgrade;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Request size limits
client_max_body_size 1M;
# Rate limiting (optional)
limit_req zone=api burst=10 nodelay;
}
} b. Configure Nginx for Prysm (Consensus Layer)
Create Nginx configuration for Prysm:
sudo nano /etc/nginx/sites-available/sepolia-beacon-rpc Add the following configuration:
server {
server_name beacon-sepolia.yourdomain.com;
access_log /var/log/nginx/sepolia_beacon_rpc_access.log;
error_log /var/log/nginx/sepolia_beacon_rpc_error.log;
location / {
# IP whitelist - same as above
allow 172.16.0.0/12;
allow 10.0.0.0/8;
allow 192.168.0.0/16;
allow 203.0.113.1;
allow 198.51.100.0/24;
deny all;
# Proxy to Prysm HTTP API
proxy_pass http://127.0.0.1:3500;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_cache_bypass $http_upgrade;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
client_max_body_size 1M;
limit_req zone=api burst=10 nodelay;
}
} c. Enable Nginx Sites
Add rate limiting to main Nginx config:
sudo nano /etc/nginx/nginx.conf Add this inside the http block:
# Rate limiting zone
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; Create symbolic links:
sudo ln -s /etc/nginx/sites-available/sepolia-eth-rpc /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/sepolia-beacon-rpc /etc/nginx/sites-enabled/ Test configuration:
sudo nginx -t Reload Nginx:
sudo systemctl reload nginx d. Setup SSL with Certbot
Obtain SSL certificate for Geth endpoint:
sudo certbot --nginx -d eth-sepolia.yourdomain.com Obtain SSL certificate for Prysm endpoint:
sudo certbot --nginx -d beacon-sepolia.yourdomain.com Follow the prompts to configure SSL.
Test certificate renewal:
sudo certbot renew --dry-run 4. Service Configuration Details
a. Geth (Execution Client)
- Image:
ethereum/client-go:v1.15.11 - Network: Sepolia testnet
- Sync Mode: Snap sync (faster initial sync)
- RPC Endpoint:
https://eth-sepolia.yourdomain.com - Available APIs: eth, net, web3
- Memory: 8-16GB allocated
b. Prysm (Consensus Client)
- Image:
gcr.io/prysmaticlabs/prysm/beacon-chain:v6.0.1 - Network: Sepolia testnet
- HTTP API:
https://beacon-sepolia.yourdomain.com - RPC:
http://localhost:4000(internal only) - Memory: 6-10GB allocated
- Checkpoint Sync: Enabled for faster sync
c. Port Configuration
| Service | Port | Protocol | Purpose | Access |
|---|---|---|---|---|
| Geth | 8545 | HTTP | JSON-RPC API | Localhost + Nginx |
| Geth | 30303 | TCP/UDP | P2P networking | Public |
| Prysm | 3500 | HTTP | Beacon API | Localhost + Nginx |
| Prysm | 4000 | RPC | gRPC API | Localhost only |
| Prysm | 13000 | TCP | P2P networking | Public |
| Prysm | 12000 | UDP | P2P networking | Public |
5. Verification and Testing
a. Check Sync Status
Check Geth sync status: Direct (localhost)
curl -s -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ -H "Content-Type: application/json" http://localhost:8545 | jqThrough Nginx proxy
curl -s -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ -H "Content-Type: application/json" https://eth-sepolia.yourdomain.com | jqExpected output when synced:
{ "jsonrpc": "2.0", "id": 1, "result": false }Check Prysm sync status: Direct (localhost)
curl -s http://localhost:3500/eth/v1/node/syncing | jqThrough Nginx proxy
curl -s https://beacon-sepolia.yourdomain.com/eth/v1/node/syncing | jqExpected output when synced:
{ "data": { "head_slot": "7601769", "sync_distance": "0", "is_syncing": false, "is_optimistic": false, "el_offline": false } }
b. Health Checks
Geth version
curl -s -X POST --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}' -H "Content-Type: application/json" https://eth-sepolia.yourdomain.com | jq Prysm health
curl -s https://beacon-sepolia.yourdomain.com/eth/v1/node/health 6. Monitoring and Maintenance
a. Check Service Status
Docker containers status
docker compose ps Container resource usage
docker stats geth-sepolia prysm-sepolia Container logs
docker compose logs --tail=100 geth
docker compose logs --tail=100 prysm b. Service Management
Restart all services:
docker compose restart Restart individual services:
docker compose restart geth
docker compose restart prysm Update services:
docker compose pull
docker compose up -d c. Data Persistence
All blockchain data is persisted in the ./data directory:
./data/geth-sepolia/- Geth blockchain data./data/prysm/- Prysm beacon chain data./data/jwt.hex- JWT secret for client authentication
d. Backup Strategy
Create quick backup (while services running):
tar -czf sepolia-backup-$(date +%Y%m%d).tar.gz data/ Create full backup (consistent, services stopped):
docker compose down
tar -czf sepolia-full-backup-$(date +%Y%m%d).tar.gz data/
docker compose up -d Restore from backup:
docker compose down
tar -xzf sepolia-backup-YYYYMMDD.tar.gz
docker compose up -d 7. Troubleshooting
a. Common Issues
1. Port Conflicts
Check port usage:
netstat -tulpn | grep -E ':(8545|3500|4000|30303|13000|12000)' Kill processes using required ports:
sudo lsof -ti:8545 | xargs kill -9 2. Insufficient Memory
Check system memory:
free -h Check Docker memory limits:
docker stats Increase swap if needed:
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile 3. Sync Issues
Check network connectivity:
ping sepolia.checkpoint-sync.ethpandaops.io Reset and resync (WARNING: deletes data):
docker compose down
sudo rm -rf data/geth-sepolia data/prysm
docker compose up -d 4. SSL Certificate Issues
Check certificate status:
sudo certbot certificates Renew certificates manually:
sudo certbot renew Test Nginx configuration:
sudo nginx -t 5. Access Denied (403)
Check your IP:
curl https://ipinfo.io/ip Update Nginx IP whitelist and reload:
sudo nano /etc/nginx/sites-available/sepolia-eth-rpc
sudo systemctl reload nginx b. Log Analysis
Search for errors in container logs
docker compose logs geth | grep -i error
docker compose logs prysm | grep -i error Check Nginx logs
sudo tail -f /var/log/nginx/sepolia_eth_rpc_access.log
sudo tail -f /var/log/nginx/sepolia_eth_rpc_error.log Check system logs
sudo journalctl -f -u docker
sudo journalctl -f -u nginx c. Recovery Commands
Full service restart
docker compose down
docker compose up -d Full service restart with image updates
docker compose down
docker compose pull
docker compose up -d --force-recreate Emergency cleanup (removes all data)
docker compose down -v
sudo rm -rf data/
mkdir -p data
openssl rand -hex 32 > data/jwt.hex
docker compose up -d 8. Security Considerations
a. Network Security
- Local Binding: RPC endpoints bound to localhost only
- Reverse Proxy: Nginx provides controlled external access
- IP Whitelisting: Only specified IPs can access endpoints
- SSL/TLS: All external traffic encrypted
- Rate Limiting: Protection against abuse
b. Firewall Configuration
Allow SSH
sudo ufw allow ssh Allow Nginx (HTTP/HTTPS)
sudo ufw allow 'Nginx Full' Allow P2P ports for blockchain
sudo ufw allow 30303
sudo ufw allow 13000
sudo ufw allow 12000/udp Deny all other traffic
sudo ufw --force enable c. Access Control Best Practices
- Keep Docker images and system updated
- Use SSH keys, disable password auth
- Review Nginx logs regularly
- Encrypt backups, store securely
- Consider VPN for additional security
d. Monitoring Setup
Set up log rotation
sudo nano /etc/logrotate.d/sepolia-logs Add content:
/var/log/nginx/sepolia_*_rpc_*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 www-data www-data
postrotate
systemctl reload nginx
endscript
} 9. Sync Time Expectations
- Initial Sync: 4-8 hours depending on hardware and network
- Geth Snap Sync: Usually faster than full sync
- Prysm Checkpoint Sync: Starts from recent checkpoint, significantly faster
- Storage Growth: ~50-100GB per month for Sepolia
10. Post-Setup Checklist
Verify the following before considering your setup complete:
- Both Geth and Prysm are syncing successfully
- RPC endpoints respond to health checks
- SSL certificates are installed and working
- IP whitelist configured correctly
- Firewall rules are properly configured
- Log rotation is set up
- Backup strategy is implemented
- Monitoring is in place
11. Resources
- Faucet: Ethereum Sepolia Faucet
- Documentation: Geth Documentation ยท Prysm Documentation
- Explorer: Ethereum Beacon Chain Explorer
- Web Server: Nginx Documentation