Warning
Codex made this, which means that it may not meet our code quality standards.
It was only for internal use, but we open sourced it because someone might find it useful in the future.
This runs local Shadowsocks and SOCKS5 proxy servers and sends all proxied outbound traffic through Cloudflare WARP using sing-box's user-space WireGuard endpoint. It does not require a privileged container or host WireGuard setup.
Dockerfilebuilds an Alpine-based image withsing-boxandwgcf.docker-compose.ymldefines the runtime service and a one-shot WARP registration service../warpstores generated WARP credentials and is intentionally ignored by git.
-
Create your env file and set a strong password:
cp .env.example .env ${EDITOR:-vi} .envOn Linux, set
PUIDandPGIDin.envtoid -uandid -gif your user is not1000:1000. -
Register a WARP device and generate
./warp/wgcf-profile.conf:docker compose --profile init run --rm warp-register
-
Start the Shadowsocks proxy:
docker compose up -d --build warp-shadowsocks
Your Shadowsocks client should use:
- Server:
127.0.0.1 - Port: the
SS_PORTvalue from.env, default8388 - Method: the
SS_METHODvalue from.env, defaultchacha20-ietf-poly1305 - Password: the
SS_PASSWORDvalue from.env
Your SOCKS5 client should use:
- Server:
127.0.0.1 - Port: the
SOCKS_PORTvalue from.env, default1080 - Username/password: blank by default, or the
SOCKS_USERNAMEandSOCKS_PASSWORDvalues from.env
By default Docker only publishes both proxies on localhost. To expose them to your LAN, set SS_BIND_HOST=0.0.0.0 and/or SOCKS_BIND_HOST=0.0.0.0 in .env and restart the service.
The service prints ss:// and socks5:// connection URLs at startup:
docker compose logs warp-shadowsocksFor LAN use, also set SS_URL_HOST and SOCKS_URL_HOST in .env to the Docker host's LAN IP so the printed URLs are directly usable. These URLs may include proxy credentials, so treat container logs as sensitive.
View logs:
docker compose logs -f warp-shadowsocksRegenerate the WARP profile after account changes:
docker compose --profile init run --rm warp-register
docker compose restart warp-shadowsocksCheck whether traffic exits via WARP by sending traffic through a Shadowsocks client to Cloudflare's trace endpoint and looking for warp=on:
curl https://www.cloudflare.com/cdn-cgi/traceRun that curl through your Shadowsocks client, not directly from the host shell.
If you already have WARP WireGuard values, you can skip wgcf and provide these variables to warp-shadowsocks instead of mounting ./warp:
WARP_PRIVATE_KEYWARP_LOCAL_ADDRESS, comma-separated, for example172.16.0.2/32,2606:4700:110:.../128WARP_PEER_PUBLIC_KEYWARP_SERVER, for exampleengage.cloudflareclient.comWARP_SERVER_PORT, usually2408WARP_RESERVED, optional comma-separated reserved bytes if your account has them