Skip to content

Docker

Docker provides an isolated, portable way to run NextDNS Blocker without installing Python.

Terminal window
# Clone repository
git clone https://github.com/aristeoibarra/nextdns-blocker.git
cd nextdns-blocker
# Copy configuration templates
cp .env.example .env
cp config.json.example config.json
# Edit configuration
nano .env # Add API credentials
nano config.json # Configure domains
# Start container
docker compose up -d
Terminal window
# Required
NEXTDNS_API_KEY=your_api_key_here
NEXTDNS_PROFILE_ID=your_profile_id
# Optional
API_TIMEOUT=10
API_RETRIES=3

Same format as native installation:

{
"version": "1.0",
"settings": {
"timezone": "America/New_York"
},
"blocklist": [...],
"allowlist": [...]
}
version: '3.8'
services:
nextdns-blocker:
build: .
container_name: nextdns-blocker
restart: unless-stopped
env_file:
- .env
volumes:
- ./config.json:/app/config.json:ro
- nextdns-data:/app/data
volumes:
nextdns-data:
Terminal window
docker compose up -d
Terminal window
docker compose down
Terminal window
# All logs
docker compose logs -f
# Recent logs
docker compose logs --tail 100
Terminal window
docker compose up -d --build
Terminal window
docker compose ps
Terminal window
# Check status
docker compose exec nextdns-blocker nextdns-blocker status
# Manual sync
docker compose exec nextdns-blocker nextdns-blocker config push -v
# View config
docker compose exec nextdns-blocker nextdns-blocker config show
Terminal window
docker run --rm \
--env-file .env \
-v $(pwd)/config.json:/app/config.json:ro \
nextdns-blocker nextdns-blocker status

The provided Dockerfile:

FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY src/ ./src/
COPY pyproject.toml .
# Install application
RUN pip install --no-cache-dir .
# Create data directory
RUN mkdir -p /app/data
# Set up cron
RUN apt-get update && apt-get install -y cron && rm -rf /var/lib/apt/lists/*
# Add cron job
RUN echo "*/2 * * * * nextdns-blocker config push >> /app/data/cron.log 2>&1" | crontab -
# Start cron in foreground
CMD ["cron", "-f"]

The nextdns-data volume persists:

  • Logs (/app/data/logs/)
  • State files (.panic)
  • Pending actions (pending.json)

Configuration is mounted read-only for safety:

volumes:
- ./config.json:/app/config.json:ro

To modify config:

  1. Edit locally: nano config.json
  2. Restart container: docker compose restart

Timezone is configured in config.json, not via environment variables:

{
"settings": {
"timezone": "America/New_York"
}
}

The container resolves DNS normally. Ensure your Docker network allows external DNS:

services:
nextdns-blocker:
dns:
- 1.1.1.1
- 8.8.8.8

NextDNS Blocker only makes outbound API calls. No ports need to be exposed.

Add a health check to docker-compose.yml:

services:
nextdns-blocker:
healthcheck:
test: ["CMD", "nextdns-blocker", "status"]
interval: 5m
timeout: 10s
retries: 3

Run multiple instances for different NextDNS profiles:

version: '3.8'
services:
nextdns-work:
build: .
env_file: .env.work
volumes:
- ./config-work.json:/app/config.json:ro
- work-data:/app/data
nextdns-home:
build: .
env_file: .env.home
volumes:
- ./config-home.json:/app/config.json:ro
- home-data:/app/data
volumes:
work-data:
home-data:
Terminal window
git pull
docker compose up -d --build
Terminal window
docker compose pull
docker compose up -d

Check logs:

Terminal window
docker compose logs --tail 50

Common causes:

  • Invalid credentials
  • Malformed config.json
  • Missing environment variables
Terminal window
# Check cron is running
docker compose exec nextdns-blocker ps aux | grep cron
# Check cron log
docker compose exec nextdns-blocker cat /app/data/cron.log
# Run sync manually
docker compose exec nextdns-blocker nextdns-blocker config push -v
Terminal window
# Restart container
docker compose restart
# Or recreate
docker compose up -d --force-recreate
Terminal window
# Check file permissions in container
docker compose exec nextdns-blocker ls -la /app/
# Fix volume permissions
docker compose down
sudo chown -R $USER:$USER ./
docker compose up -d

Add resource limits for production:

services:
nextdns-blocker:
deploy:
resources:
limits:
cpus: '0.5'
memory: 128M
reservations:
memory: 64M

Configure logging driver:

services:
nextdns-blocker:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Terminal window
# Stop and remove container
docker compose down
# Remove volume (loses data)
docker compose down -v
# Remove image
docker rmi nextdns-blocker
# Remove files
rm -rf config.json .env