English | 中文
A lightweight, multi-architecture (linux/i386, linux/amd64, linux/arm64 and linux/armv7l) Docker image for Snell Server.
Supports configuration via environment variables, with secure defaults when not provided: random PSK and random port (>1024).
This project provides Docker images from two sources:
- Docker Hub:
1byte/snell-server - GitHub Container Registry (GHCR):
ghcr.io/waterdrops/snell-server
Both images are identical and you can use either one based on your preference.
- Multi-stage build for a smaller image size
- Multi-architecture support:
linux/i386,linux/amd64,linux/arm64andlinux/armv7l - Configurable via environment variables
- Secure defaults: random port and random 32-character PSK
- Minimal dependencies: based on debian:stable-slim and busybox:stable
- Conditional configuration: only writes optional fields when values are provided
- Input validation: validates IPv6 and OBFS values before startup
| Variable | Default Value | Description | Validation Rules |
|---|---|---|---|
PORT |
Random 1025–65535 | Listening port | Must be integer 1025–65535 |
PSK |
Random 32-char alphanumeric | Pre-shared key | Required |
IPv6 |
Not set (optional) | Enable IPv6 | Must be true or false if provided |
OBFS |
Not set (optional) | Obfuscation mode | Must be off or http if provided |
OBFS_HOST |
Not set (optional) | Obfuscation host | Only used when OBFS=http |
TFO |
true |
Enable TCP Fast Open | Boolean |
The server uses conditional configuration writing:
- IPv6: Only written to config if
IPv6environment variable is set - OBFS: Only written to config if
OBFSenvironment variable is set - OBFS_HOST: Only written to config if
OBFS=httpandOBFS_HOSTis set - Existing config file: If
snell-server.confalready exists (e.g., mounted via volume), it will be used as-is and the script will skip generating a new one
# Docker Hub
docker pull 1byte/snell-server
# GitHub Container Registry
docker pull ghcr.io/waterdrops/snell-server# Build with default Snell version (5.0.1)
git clone https://github.com/waterdrops/snell-server-docker.git
cd snell-server-docker
docker build -t 1byte/snell-server .
# Build with specific Snell version
docker build --build-arg SNELL_VERSION=4.1.1 -t 1byte/snell-server:4.1.1 .# Build with default Snell version (5.0.1)
cd snell-server-docker # Please make sure to clone it first before proceeding
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t 1byte/snell-server:latest .
# Build with specific Snell version
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg SNELL_VERSION=4.1.1 \
-t 1byte/snell-server:v4.1.1 .# Using Docker Hub
docker run --rm 1byte/snell-server
# Using GitHub Container Registry
docker run --rm ghcr.io/waterdrops/snell-server# Using Docker Hub
docker run -it -p 8234:8234 \
-e PORT=8234 \
-e PSK=mysecurepsk \
1byte/snell-server
# Using GitHub Container Registry
docker run -it -p 8234:8234 \
-e PORT=8234 \
-e PSK=mysecurepsk \
ghcr.io/waterdrops/snell-serverPlease refer to the Environment Variables section and adjust them as needed. For example, you can disable obfuscation by setting: OBFS=off
# Using Docker Hub
docker run -itd -p 8234:8234 \
-e PORT=8234 \
-e PSK=mysecurepsk \
-e IPv6=true \
-e OBFS=http \
-e OBFS_HOST=gateway.icloud.com \
-e TFO=false \
1byte/snell-server
# Using GitHub Container Registry
docker run -itd -p 8234:8234 \
-e PORT=8234 \
-e PSK=mysecurepsk \
-e IPv6=true \
-e OBFS=http \
-e OBFS_HOST=gateway.icloud.com \
-e TFO=false \
ghcr.io/waterdrops/snell-server- Ensure
docker-compose.ymlis in your working directory - Provide environment variables via a
.envfile (recommended) or your shell
PORT=8234
PSK=mysecurepsk
# IPv6=false
# TFO=true
# OBFS=http
# OBFS_HOST=gateway.icloud.comservices:
snell-server:
container_name: snell-server
restart: always
image: 1byte/snell-server:latest
ports:
- "${PORT:-8234}:${PORT:-8234}" # Default to 8234 if PORT is not set
environment:
PORT: "${PORT}"
PSK: "${PSK}"
# IPv6: "${IPv6}"
# TFO: "${TFO}"
# OBFS: "${OBFS}" # Set to "false" to disable; `http` enables it
# OBFS_HOST: "${OBFS_HOST}"
# volumes:
# - ./snell-server.conf:/app/snell-server.confIf you already have a snell-server.conf, mount it and the script will skip auto-generation:
services:
snell-server:
# ...
volumes:
- ./snell-server.conf:/app/snell-server.confWith this volume mount, the container will use your provided config file and ignore environment variables for generation.
docker compose up -d- Apply for a public IP address from your ISP
- Port mapping
- Optional: A domain and a DNS provider(e.g, Cloudflare, AliCloud). If you are going to use a DNS provider and your IP is dynamic, I recommend ddns-go for automatic DNS updates. It's a simple and easy-to-use DDNS tool. See 3 for more details.
Add the following to your Surge configuration file (e.g, Surge.conf), and replace placeholders like YOUR_FQDN, YOUR_PUBLIC_IP, YOUR_DOMAIN, ${PORT}, ${PSK}, MyHome and IP-CIDR,192.168.188.0/24 with your actual values.
To learn more about Surge Policy Groups, see Surge Policy Group documentation1 and Surge Manual2. For more information on Snell, refer to Snell knowledge4.
[Proxy]
home = snell, YOUR_FQDN or YOUR_PUBLIC_IP, ${PORT}, psk=${PSK}, version=5, reuse=true
# If obfuscation is enabled:
# home = snell, YOUR_PUBLIC_IP or YOUR_FQDN, YOUR_PORT, psk=YOUR_PSK, version=5, obfs=http, obfs-host=YOUR_OBFS_HOST, reuse=true, tfo=true
...
[Proxy Group]
# Define a policy group named `🏠Home` of type `subnet`.
# Behavior: If the current Wi-Fi SSID is `MyHome`, connect directly;
# otherwise, switch to the `🏠Home` policy group.
# Please refer to [1] for more details.
🏠Home = subnet, default = home, SSID:MyHome = DIRECT
...
[Rule]
IP-CIDR,192.168.188.0/24,🏠Home,no-resolve
# Modify the following line as needed when using DNS(e.g, Cloudflare or another provider.)
OR,((DOMAIN,plex.YOUR_DOMAIN), (DOMAIN,vw.YOUR_DOMAIN), (DOMAIN,gitea.YOUR_DOMAIN), (DOMAIN,myns.YOUR_DOMAIN)),🏠Home
...The server validates all input values before starting:
- Invalid PORT: Must be an integer between 1025 and 65535
- Invalid IPv6: Must be
trueorfalseif provided - Invalid OBFS: Must be
offorhttpif provided
If any validation fails, the server will display an error message and exit with code 1.