# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What this is A Docker Compose setup for a self-hosted WireGuard VPN server using [wg-easy](https://github.com/wg-easy/wg-easy), designed to run on a Raspberry Pi or any Linux server. The web UI (wg-easy) handles client management, QR code generation, and key lifecycle. ## Common commands ```bash # First-time setup cp .env.example .env # Edit .env with WG_HOST, PASSWORD_HASH, TZ # Generate bcrypt password hash (no extra dependencies) docker run --rm -it ghcr.io/wg-easy/wg-easy wgpw 'YourPassword' # Start the VPN docker compose up -d # Update wg-easy to the latest image docker compose pull && docker compose up -d # View logs docker compose logs -f wg-easy ``` ## Configuration All runtime configuration lives in `.env` (not committed). Required variables: | Variable | Description | |---|---| | `WG_HOST` | Public IP or DDNS hostname clients connect to | | `PASSWORD_HASH` | bcrypt hash of the web UI password (prefix `$2a$`, `$2b$`, or `$2y$`) | | `TZ` | IANA timezone (e.g. `Europe/Rome`) | Optional: `WG_PORT` (default 51820/udp), `WG_UI_PORT` (default 51821/tcp), `WG_DEFAULT_DNS` (default `1.1.1.1,8.8.8.8`). ## Important constraints - `wg-data/` is auto-generated by the container on first start and holds live WireGuard keys (`wg0.conf`, `wg0.json`). Never commit it. - `.env` is gitignored — it holds the password hash and hostname. - The container requires `NET_ADMIN` and `SYS_MODULE` capabilities plus `net.ipv4.ip_forward=1` sysctl — these are already set in `docker-compose.yml`. - The router must forward UDP port 51820 (or `WG_PORT`) to the server's local IP. - `openssl passwd` does **not** support bcrypt — use the Docker method, `htpasswd`, or Python's `bcrypt` library to generate `PASSWORD_HASH`.