Russian version: README.ru.md
Containerized VPN gateway that establishes an AmneziaWG tunnel and exposes a SOCKS5 proxy.
Traffic flow:
- Client -> SOCKS5 proxy (
microsocks) - Proxy process -> container network stack
- Container routing policy -> AWG tunnel (
awg-quick+amneziawg-gouserspace fallback)
This project is designed to work on Windows Docker Desktop and Linux.
- Base image: Alpine (portable variant)
- AWG userspace backend:
amneziawg-go - AWG tooling:
awg,awg-quick - Proxy:
microsocks - Entrypoint orchestration:
entrypoint.sh
- Docker Engine / Docker Desktop
- Docker Compose v2
NET_ADMINcapability/dev/net/tundevice mapping- AWG client config mounted to
/config/amnezia.conf
- Put your AWG config into
amnezia.confin project root. - Start service:
docker compose up --build -d- Check status:
docker compose ps
docker compose logs --tail=120 awg-proxy- Use SOCKS5 proxy on host:
- Address:
127.0.0.1 - Port:
1080(default)
Example:
curl.exe --socks5-hostname 127.0.0.1:1080 https://api.ipify.orgCompose publishes a configurable port:
PROXY_PORT(default1080)
Supported environment variables:
AWG_CONFIG_FILE(default/config/amnezia.conf)WG_QUICK_USERSPACE_IMPLEMENTATION(defaultamneziawg-go)LOG_LEVEL(defaultinfo)WATCHDOG_INTERVAL(default30, seconds between AWG health checks)WATCHDOG_STALE_THRESHOLD(default180, restart tunnel when latest handshake is older)WATCHDOG_LOG_EVERY(default2, print watchdog health line every N checks)PROXY_LISTEN_HOST(default0.0.0.0)PROXY_PORT(default1080)PROXY_USER,PROXY_PASSWORD(optional auth, must be set together)MICROSOCKS_BIND_ADDRESS(optional)MICROSOCKS_WHITELIST(optional)MICROSOCKS_AUTH_ONCE(0or1)MICROSOCKS_QUIET(0or1)MICROSOCKS_OPTS(extra flags)
DNS behavior:
DNS = ...from AWG config is applied to container resolver.- Runtime uses two layers for portability:
resolvconfshim forawg-quickDNS hook.- Explicit DNS apply step in
entrypoint.shafterawg-quick up.
- On Docker Desktop, AWG startup may take time (endpoint retries are normal), so check resolver state after startup logs finish.
- File name must end with
.conf. AllowedIPsshould include default routes if you want all proxy traffic to go through VPN:0.0.0.0/0::/0
- Empty assignments like
I2 =are sanitized at runtime byentrypoint.shinto a temporary config.
- Windows Docker Desktop: expected to use userspace fallback (
amneziawg-go). - Linux with kernel module installed:
awg-quickmay use kernel path first.
- Check that the service is running:
docker compose psExpected: service awg-proxy is Up and the proxy port is published.
- Check startup logs:
docker compose logs --tail=120 awg-proxyExpected: lines about bringing up AWG and starting microsocks.
- Test proxy egress with curl:
curl.exe --socks5-hostname 127.0.0.1:1080 https://api.ipify.orgIf your proxy port is custom, replace 1080 with PROXY_PORT value.
- Optional tunnel evidence from inside container:
docker exec awg-proxy awg show- Verify DNS from AWG config is active inside container:
docker exec awg-proxy cat /etc/resolv.conf
docker exec awg-proxy nslookup google.comExpected: resolv.conf contains nameserver entries from your AWG config (for example 1.1.1.1) and nslookup reports one of those servers.
If direct and proxied public IP are identical, your host may already use the same upstream route. In this case, rely on awg show counters and container logs to confirm traffic through the tunnel.
-
/dev/net/tun is missing- Ensure
devices: - /dev/net/tun:/dev/net/tunis present in compose.
- Ensure
-
Line unrecognized: I2=- Fixed by runtime sanitization in
entrypoint.sh. Use the current image.
- Fixed by runtime sanitization in
-
sysctl: permission denied on key net.ipv4.conf.all.src_valid_mark- Expected in some Docker Desktop environments.
- Current image tolerates this and continues startup.
-
Proxy port busy
- Override host/container port via
PROXY_PORT.
- Override host/container port via
-
Proxy stops working after laptop sleep or network/location change
- Keep
PersistentKeepalive = 25in AWG peer config. - Current image runs an AWG watchdog that checks
latest-handshakesand restarts the tunnel when stale. - Tune with
WATCHDOG_INTERVALandWATCHDOG_STALE_THRESHOLDin compose if needed.
- Keep
-
Container still shows
nameserver 127.0.0.11- Wait until AWG startup completes (
docker compose logs --tail=120 awg-proxy). - Re-check
docker exec awg-proxy cat /etc/resolv.conf. - If needed, restart and wait longer (AWG may retry endpoint before finishing setup).
- Wait until AWG startup completes (
Dockerfile- multi-stage Alpine portable buildentrypoint.sh- AWG startup and proxy orchestrationdocker-compose.yml- capabilities, tun mapping, env defaults