wiretastix

Installation with Docker Compose

How to install Wiretastix using Docker Compose for containerized deployment.

Wiretastix can be deployed using Docker Compose, providing a containerized, reproducible environment. This method is ideal for development, testing, and production deployments where container orchestration is preferred.

Why Use Docker Compose?

Docker Compose deployment offers several advantages:

  • Isolation: Runs in its own container namespace
  • Portability: Easy to move between hosts
  • Reproducibility: Consistent environment across deployments
  • Quick setup: Fast deployment with pre-configured settings
  • Easy updates: Simple container image updates
  • Development-friendly: Ideal for testing and development

Deployment Architecture

Wiretastix Docker deployment supports two network modes:

  1. Host Network Mode: Container shares the host’s network namespace (simpler, recommended for most cases)
  2. Bridge Mode with Helper Container: Uses a sidecar container for network isolation (more complex but more isolated)

And two database options:

  1. SQLite: Simpler, single-file database (recommended for small deployments)
  2. PostgreSQL: More robust, better for production with high load

Prerequisites

Before you begin, ensure you have:

  • Docker Engine: Version 20.10 or newer
  • Docker Compose: Version 2.0 or newer (or Docker Compose V1 with version 1.29+)
  • Host Requirements:
    • Linux kernel with WireGuard support (kernel 5.6+ or WireGuard kernel module)
    • Root or sudo access
    • Ports 51820/UDP (WireGuard), 8085/TCP (Web UI), 8095/TCP (API) available

Verify Docker Installation

docker --version
docker compose version  # Note: "docker compose" not "docker-compose" in newer versions

Check WireGuard Support

# Check if WireGuard module is available
lsmod | grep wireguard

# If not loaded, try to load it
sudo modprobe wireguard

# Verify kernel support
uname -r  # Should be 5.6+ for native WireGuard

Project Structure

For this guide, we’ll use the following directory structure:

wiretastix-docker/
├── docker-compose.yml
├── config/
│   ├── wiretastix.yaml
│   └── nftables.conf
├── data/              (created automatically)
│   └── wiretastix.db  (SQLite only)
└── postgres-data/     (created automatically, PostgreSQL only)

Step 1: Prepare the Project Directory

Create the project directory structure:

mkdir -p wiretastix-docker/config
cd wiretastix-docker

Step 2: Build or Pull the Docker Image

You have two options for obtaining the Wiretastix image:

docker pull wiretastix/wiretastix-vpn:latest

Note: Adjust the image name and tag based on your actual registry.

Option B: Build from Source

Clone the repository as a sibling of wiretastix-docker/, not inside it, so the deployment directory stays limited to docker-compose.yml, config/, and data/:

# Clone the repository (as a sibling of wiretastix-docker/)
cd ..
git clone https://github.com/wiretastix/wiretastix-vpn.git
cd wiretastix-vpn

# Build the image
docker build -t wiretastix:latest .

# Return to the project directory
cd ../wiretastix-docker

Verify the image:

docker images | grep wiretastix

Step 3: Prepare Configuration Files

3.1: Create Base Configuration

Download or copy the default configuration template:

# If you cloned the repo, copy from there
cp ../wiretastix-vpn/wiretastix.yaml config/wiretastix.yaml
cp ../wiretastix-vpn/nftables.conf config/nftables.conf

# Or create from scratch (see Configuration Reference)

3.2: Generate WireGuard Private Key

Generate a private key for the WireGuard interface:

docker run --rm alpine sh -c "apk add --no-cache wireguard-tools && wg genkey"

Copy the output - you’ll need it for the configuration.

Required for every setup (SQLite or PostgreSQL): Wiretastix uses this value to sign session cookies. Generate a random secret now and use it in the next step – don’t leave the placeholder value in wiretastix.yaml, or sessions won’t be secure.

openssl rand -base64 32

Copy the output - you’ll need it for the configuration.

3.4: Configure wiretastix.yaml

Edit config/wiretastix.yaml with your settings. Here’s a minimal example:

For SQLite (Simple Setup):

# Web server for user self-service
webserver:
    binding: :8085
    base: /
    html-assets: /usr/lib/wiretastix/html
    html-templates: /usr/lib/wiretastix/templates
    auto-cert: true
    cert-dir: /etc/wiretastix/certs/

# API server
apiserver:
    binding: 0.0.0.0:8095  # Note: 0.0.0.0 for Docker, change for production
    base: /wiretastix/api/v1/

# Database - SQLite
db:
    type: sqlite
    dsn: file:/data/wiretastix.db?cache=shared&_journal=WAL&_synchronous=full&_fk=1

# OIDC configuration (must be configured before first start)
oidc:
    name: YourIdentityProvider
    client-id: your-client-id
    client-secret: your-client-secret
    redirect-url: https://vpn.example.com/callback
    config-issuer: https://your-idp.com/.well-known/openid-configuration
    cookie-secret: GENERATE_RANDOM_STRING_HERE  # From step 3.3
    force-approval: false
    verbose: false
    refresh-min-interval-sec: 300
    scopes:
        - openid
        - email
        - profile
        - offline_access
    constraints:
        groups:
            - vpn-users

# WireGuard interface
wireguard:
    ifname: wg0
    port: 51820
    pvtkey: YOUR_GENERATED_PRIVATE_KEY_HERE  # From step 3.2
    fwmark: 0xbeef
    ipv4: 10.100.200.1/24
    ipv6: fd41:34e9:dead:beef::1/64

# NFTables
nftables:
    table: wiretastix

# DNS resolver (optional)
resolver:
    binding: 0.0.0.0:5353
    concurrency: 5
    domain: vpn.local

# Prometheus metrics
metrics:
    path: /metrics
    binding: 0.0.0.0:9100

For PostgreSQL (Production Setup):

Change the database section to:

db:
    type: postgres
    dsn: postgresql://wiretastix:changeme@postgres:5432/wiretastix?client_encoding=UTF8&application_name=Wiretastix&sslmode=disable

Step 4: Create Docker Compose File

Choose one of the following configurations based on your needs.

Configuration 1: SQLite with Host Network (Simplest)

File: docker-compose.yml

version: '3.8'

services:
  wiretastix:
    image: wiretastix:latest
    container_name: wiretastix-daemon
    restart: unless-stopped
    network_mode: host
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    volumes:
      - ./config/wiretastix.yaml:/etc/wiretastix/wiretastix.yaml:ro
      - ./config/nftables.conf:/etc/nftables.conf:ro
      - ./data:/data
      - /lib/modules:/lib/modules:ro
    command: ["-c", "/etc/wiretastix/wiretastix.yaml"]
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Pros:

  • Simplest configuration
  • Direct access to host network
  • WireGuard interface created directly on host

Cons:

  • Less network isolation
  • Shares host’s network namespace

Configuration 2: PostgreSQL with Host Network (Production)

File: docker-compose.yml

version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    container_name: wiretastix-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: wiretastix
      POSTGRES_USER: wiretastix
      POSTGRES_PASSWORD: changeme  # Change this!
      POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
    volumes:
      - postgres-data:/var/lib/postgresql/data
    ports:
      - "127.0.0.1:5432:5432"  # Only expose to localhost
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U wiretastix"]
      interval: 10s
      timeout: 5s
      retries: 5
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  wiretastix:
    image: wiretastix:latest
    container_name: wiretastix-daemon
    restart: unless-stopped
    network_mode: host
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    volumes:
      - ./config/wiretastix.yaml:/etc/wiretastix/wiretastix.yaml:ro
      - ./config/nftables.conf:/etc/nftables.conf:ro
      - /lib/modules:/lib/modules:ro
    depends_on:
      postgres:
        condition: service_healthy
    command: ["-c", "/etc/wiretastix/wiretastix.yaml"]
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  postgres-data:

Pros:

  • Production-ready database
  • Better for high load
  • Data persistence with PostgreSQL backups

Cons:

  • More complex setup
  • Additional container to manage

Configuration 3: SQLite with Bridge Network and Sidecar (Advanced)

File: docker-compose.yml

version: '3.8'

services:
  wireguard-sidecar:
    image: alpine:latest
    container_name: wiretastix-wg-sidecar
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    devices:
      - /dev/net/tun:/dev/net/tun
    volumes:
      - /lib/modules:/lib/modules:ro
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv4.ip_forward=1
      - net.ipv6.conf.all.forwarding=1
    command:
      - /bin/sh
      - -c
      - |
        apk add --no-cache wireguard-tools iproute2
        ip link add dev wg0 type wireguard || true
        echo "WireGuard interface ready"
        tail -f /dev/null
    ports:
      - "51820:51820/udp"
      - "8085:8085/tcp"
      - "8095:8095/tcp"
      - "9100:9100/tcp"
    healthcheck:
      test: ["CMD", "ip", "link", "show", "wg0"]
      interval: 5s
      timeout: 3s
      retries: 3
      start_period: 10s

  wiretastix:
    image: wiretastix:latest
    container_name: wiretastix-daemon
    restart: unless-stopped
    network_mode: "service:wireguard-sidecar"
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    volumes:
      - ./config/wiretastix.yaml:/etc/wiretastix/wiretastix.yaml:ro
      - ./config/nftables.conf:/etc/nftables.conf:ro
      - ./data:/data
      - /lib/modules:/lib/modules:ro
    depends_on:
      wireguard-sidecar:
        condition: service_healthy
    command: ["-c", "/etc/wiretastix/wiretastix.yaml"]
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Pros:

  • Better network isolation
  • Port mappings controlled explicitly
  • Suitable for environments requiring strict container isolation

Cons:

  • More complex architecture
  • Sidecar container overhead
  • Harder to debug networking issues

Step 5: Start the Services

Start Wiretastix using Docker Compose:

# Start in foreground (see logs)
docker compose up

# Or start in background (detached mode)
docker compose up -d

Check that services are running:

docker compose ps

Expected output (for PostgreSQL setup):

NAME                   IMAGE              STATUS              PORTS
wiretastix-daemon      wiretastix:latest  Up 2 minutes        
wiretastix-postgres    postgres:16-alpine Up 2 minutes (healthy)

Step 6: Initialize the API Token

Generate the initial API token:

# Method 1: Direct execution
docker compose exec wiretastix wiretastix-daemon --initialize -c /etc/wiretastix/wiretastix.yaml

# Method 2: With explicit container name
docker exec wiretastix-daemon wiretastix-daemon --initialize -c /etc/wiretastix/wiretastix.yaml

Copy the output token immediately - you won’t be able to retrieve it later.

If you need to regenerate the token (invalidates the old one):

docker compose exec wiretastix wiretastix-daemon --initialize --wipe -c /etc/wiretastix/wiretastix.yaml

Step 7: Verify Installation

Check Container Status

docker compose ps
docker compose logs wiretastix

Test the API

# Store your token
export WIRETASTIX_TOKEN="your-token-from-step-6"

# Test API connectivity
curl -k -H "Authorization: Bearer ${WIRETASTIX_TOKEN}" \
  https://127.0.0.1:8095/wiretastix/api/v1/configs/

You should see a JSON response with configuration parameters.

Test the Web Interface

Open your browser to:

https://127.0.0.1:8085

You should see the Wiretastix login page (assuming you’ve configured OIDC).

Verify WireGuard Interface

# Check the interface exists
ip link show wg0

# Or from inside the container
docker compose exec wiretastix ip link show wg0

Step 8: Use the CLI

wiretastix-cli is an interactive shell only – there’s no non-interactive, single-command mode. Launching it always drops you into a > prompt, where you type commands like peer list one at a time (see the CLI Commands Reference for the full list).

Method 1: Directly via Docker Compose

docker compose exec wiretastix wiretastix-cli \
  --api https://127.0.0.1:8095/wiretastix/api/v1/ \
  --token "${WIRETASTIX_TOKEN}"
> peer list

Method 2: Enter the Container First

# Enter the container
docker compose exec wiretastix /bin/bash

# Set environment variables
export WIRETASTIX_API="https://127.0.0.1:8095/wiretastix/api/v1/"
export WIRETASTIX_TOKEN="your-token"

# Launch the interactive shell
wiretastix-cli
> peer list

Method 3: From Host (if CLI installed)

# Set environment variables in your shell
export WIRETASTIX_API="https://127.0.0.1:8095/wiretastix/api/v1/"
export WIRETASTIX_TOKEN="your-token"

# Use the host-installed CLI
wiretastix-cli -k
> peer list

Managing the Deployment

View Logs

# All services
docker compose logs -f

# Specific service
docker compose logs -f wiretastix

# Last 100 lines
docker compose logs --tail=100 wiretastix

Stop Services

# Stop but don't remove containers
docker compose stop

# Stop and remove containers (data preserved)
docker compose down

# Stop, remove containers, and remove volumes (WARNING: destroys data)
docker compose down -v

Restart Services

# Restart all
docker compose restart

# Restart specific service
docker compose restart wiretastix

Update Configuration

After editing config/wiretastix.yaml:

# Restart to apply changes
docker compose restart wiretastix

Update Wiretastix Image

# Pull new image
docker compose pull wiretastix

# Recreate containers with new image
docker compose up -d

# Or rebuild if using local Dockerfile
docker compose build --no-cache
docker compose up -d

Data Persistence and Backups

Wiretastix stores critical data that should be backed up regularly:

  • Database: All users, peers, rules, and configuration (SQLite or PostgreSQL)
  • Configuration: config/wiretastix.yaml, docker-compose.yml, config/nftables.conf
  • Volume data: Everything in the data/ directory (for SQLite)

Quick Backup Commands

For SQLite:

# Backup database
docker compose exec wiretastix sqlite3 /data/wiretastix.db ".backup /data/backup.db"
docker compose cp wiretastix:/data/backup.db ./backups/wiretastix-$(date +%Y%m%d).db

# Backup configuration
tar czf backups/config-$(date +%Y%m%d).tar.gz config/ docker-compose.yml

For PostgreSQL:

# Backup database
docker compose exec -T postgres pg_dump -U wiretastix wiretastix > \
  backups/wiretastix-$(date +%Y%m%d).sql

# Backup configuration
tar czf backups/config-$(date +%Y%m%d).tar.gz config/ docker-compose.yml

Comprehensive Backup Guide

For detailed backup strategies, automated backups, restore procedures, and disaster recovery scenarios, see the Backup and Recovery Guide.

This guide covers:

  • What to backup and why
  • Automated backup scripts
  • Backup verification procedures
  • Restore procedures for all scenarios
  • Off-site backup strategies
  • Disaster recovery planning

Troubleshooting

For detailed troubleshooting, see the FAQ & Troubleshooting Guide.

Quick Checks

If you encounter issues:

  1. Check container logs:

    docker compose logs -f wiretastix
    
  2. Verify all services are running:

    docker compose ps
    
  3. Test configuration syntax:

    docker compose config --quiet
    

Common Docker-Specific Issues

Container Won’t Start:

  • Check logs: docker compose logs wiretastix
  • Verify volume mounts exist on host
  • Check for YAML syntax errors in docker-compose.yml

Permission Denied on /dev/net/tun:

sudo mkdir -p /dev/net
sudo mknod /dev/net/tun c 10 200
sudo chmod 666 /dev/net/tun

WireGuard Module Not Available:

# Load on host
sudo modprobe wireguard

Port Conflicts:

# Check what's using the port
sudo netstat -tulpn | grep -E ':(51820|8085|8095)'

Database Not Ready (PostgreSQL):

  • Ensure health check is configured
  • Use condition: service_healthy in depends_on
  • Check: docker compose exec postgres pg_isready -U wiretastix

For additional troubleshooting scenarios including OIDC issues, networking problems, and performance tuning, see the FAQ & Troubleshooting Guide.

Production Considerations

Security Hardening

  1. Use secrets management for sensitive data:

    secrets:
      db_password:
        file: ./secrets/db_password.txt
    
  2. Run as non-root user (requires Dockerfile modification):

    USER wiretastix:wiretastix
    
  3. Restrict API binding to localhost:

    apiserver:
      binding: 127.0.0.1:8095
    
  4. Use proper TLS certificates (not self-signed):

    • Mount cert files in volumes
    • Configure paths in wiretastix.yaml
  5. Limit Docker logging: Already configured with max-size and max-file in examples

Resource Limits

Add resource constraints to prevent resource exhaustion:

services:
  wiretastix:
    # ... other config ...
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

Health Checks

Add health checks for monitoring:

services:
  wiretastix:
    # ... other config ...
    healthcheck:
      test: ["CMD", "curl", "-k", "-f", "https://localhost:8095/wiretastix/api/v1/configs/", "-H", "Authorization: Bearer ${WIRETASTIX_TOKEN}"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Monitoring

Expose Prometheus metrics:

services:
  wiretastix:
    # ... other config ...
    ports:
      - "9100:9100"  # Prometheus metrics

Then configure Prometheus to scrape http://localhost:9100/metrics.

Backup Automation

For comprehensive backup automation including scripts, scheduling, and off-site backup strategies, see the Backup and Recovery Guide.

Quick example for Docker:

#!/bin/bash
# Simple daily backup script
BACKUP_DIR="./backups"
mkdir -p "${BACKUP_DIR}"

# Backup database
docker compose exec -T postgres pg_dump -U wiretastix wiretastix > \
  "${BACKUP_DIR}/db-$(date +%Y%m%d).sql"

# Backup config
tar czf "${BACKUP_DIR}/config-$(date +%Y%m%d).tar.gz" config/

# Keep only last 30 days
find "${BACKUP_DIR}" -mtime +30 -delete

Schedule with cron:

0 2 * * * /path/to/backup-script.sh

Upgrading

Minor Version Upgrades

# Pull new image
docker compose pull wiretastix

# Recreate container
docker compose up -d wiretastix

Major Version Upgrades

  1. Backup everything first
  2. Read release notes for breaking changes
  3. Test in development environment
  4. Update configuration if needed
  5. Perform upgrade:
    docker compose pull
    docker compose up -d
    
  6. Verify services are running correctly
  7. Check logs for any errors

Alternative: Docker Run (Without Compose)

For simple deployments, you can use docker run directly:

docker run -d \
  --name wiretastix-daemon \
  --restart unless-stopped \
  --network host \
  --cap-add NET_ADMIN \
  --cap-add SYS_MODULE \
  -v $(pwd)/config/wiretastix.yaml:/etc/wiretastix/wiretastix.yaml:ro \
  -v $(pwd)/config/nftables.conf:/etc/nftables.conf:ro \
  -v $(pwd)/data:/data \
  -v /lib/modules:/lib/modules:ro \
  wiretastix:latest \
  -c /etc/wiretastix/wiretastix.yaml

Next Steps

After successful deployment:

Additional Resources