1byte/snell-server

By 1byte

Updated 16 days ago

A lightweight, Busybox-based, multi-architecture(amd64 and arm64) Docker image for Snell Server.

Image
Networking
3

10K+

1byte/snell-server repository overview

English | 中文

Snell Server Docker Image

Build Release Image Size Docker Pulls Docker Stars FOSSA Status Repository License

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).

Available Images

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.

Features

  • Multi-stage build for a smaller image size
  • Multi-architecture support: linux/i386, linux/amd64, linux/arm64 and linux/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, MODE, DNS_IP_PREFERENCE, and OBFS values before startup

Environment Variables

VariableDefault ValueDescriptionValidation Rules
PORTRandom 1025–65535Listening portMust be integer 1025–65535
PSKRandom 32-char alphanumericPre-shared keyRequired
LISTEN0.0.0.0:PORTListen addressesWhen IPv6=true, set to 0.0.0.0:PORT,[::]:PORT; override with a custom value when IPv6 is not true
DNS_IP_PREFERENCEdefaultDNS IP family preferenceMust be default, prefer-ipv4, prefer-ipv6, ipv4-only, or ipv6-only
IPv6Not set (optional)Enable IPv6Must be true or false if provided
MODENot set (optional)Snell v6 crypto/obfuscation mode (beta 3+)Must be default, unshaped, or unsafe-raw if provided
OBFSNot set (optional)Obfuscation mode (legacy)Must be off or http if provided
OBFS_HOSTNot set (optional)Obfuscation hostOnly used when OBFS=http
TFOtrueEnable TCP Fast OpenBoolean

Configuration Behavior

The server uses conditional configuration writing:

  • IPv6: Only written to config if IPv6 environment variable is set; when IPv6=true, listen is set to 0.0.0.0:PORT,[::]:PORT for dual-stack binding
  • LISTEN: Written to config as listen; defaults to 0.0.0.0:PORT, or dual-stack when IPv6=true
  • DNS_IP_PREFERENCE: Always written to config as dns-ip-preference (default: default)
  • MODE: Only written to config if MODE environment variable is set
  • OBFS: Only written to config if OBFS environment variable is set
  • OBFS_HOST: Only written to config if OBFS=http and OBFS_HOST is set
  • Existing config file: If snell-server.conf already exists (e.g., mounted via volume), it will be used as-is and the script will skip generating a new one

Docker Images

Published tags (example for Snell 6.0.0b3):

TagDescription
latestLatest build from main
6Latest image for Snell v6
6.0.0b3Exact Snell version (no v prefix)
# Docker Hub
docker pull 1byte/snell-server
docker pull 1byte/snell-server:6
docker pull 1byte/snell-server:6.0.0b3

# GitHub Container Registry
docker pull ghcr.io/waterdrops/snell-server
docker pull ghcr.io/waterdrops/snell-server:6
docker pull ghcr.io/waterdrops/snell-server:6.0.0b3

Build the Image

Local build:
# 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 .
Multi-arch build (requires buildx):
# 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 .

Run Examples

Default config (random port & PSK, for testing only)
# Using Docker Hub
docker run --stop-timeout 2 --rm 1byte/snell-server

# Using GitHub Container Registry
docker run --stop-timeout 2 --rm ghcr.io/waterdrops/snell-server
Specify port and PSK
# Using Docker Hub
docker run -it -p 8234:8234 \
  --stop-timeout 2 \
  -e PORT=8234 \
  -e PSK=mysecurepsk \
  1byte/snell-server

# Using GitHub Container Registry
docker run -it -p 8234:8234 \
  --stop-timeout 2 \
  -e PORT=8234 \
  -e PSK=mysecurepsk \
  ghcr.io/waterdrops/snell-server
Complete configuration example

Please refer to the Environment Variables section and adjust them as needed. For example, set MODE=unshaped for higher throughput (client must use the same mode).

# Using Docker Hub
docker run -itd -p 8234:8234 \
  --stop-timeout 2 \
  -e PORT=8234 \
  -e PSK=mysecurepsk \
  -e MODE=default \
  -e DNS_IP_PREFERENCE=default \
  -e IPv6=true \
  -e TFO=false \
  1byte/snell-server

# Using GitHub Container Registry
docker run -itd -p 8234:8234 \
  --stop-timeout 2 \
  -e PORT=8234 \
  -e PSK=mysecurepsk \
  -e MODE=default \
  -e DNS_IP_PREFERENCE=default \
  -e IPv6=true \
  -e TFO=false \
  ghcr.io/waterdrops/snell-server

Run with docker-compose

Quick start
  1. Ensure docker-compose.yml is in your working directory
  2. Provide environment variables via a .env file (recommended) or your shell
Example .env and docker-compose.yml(place next to docker-compose.yml):
.env
PORT=8234
PSK=mysecurepsk
# IPv6=false
# TFO=true
# dns-ip-preference = default # default | prefer-ipv4 | prefer-ipv6 | ipv4-only | ipv6-only
# MODE=default          # default | unshaped | unsafe-raw
# OBFS=http
# OBFS_HOST=gateway.icloud.com
docker-compose.yml
services:
  snell-server:
    container_name: snell-server
    stop_grace_period: 2s
    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}"
      # dns-ip-preference = default # default | prefer-ipv4 | prefer-ipv6 | ipv4-only | ipv6-only
      # MODE: "${MODE}"      # default | unshaped | unsafe-raw
      # OBFS: "${OBFS}"        # Set to "false" to disable; `http` enables it
      # OBFS_HOST: "${OBFS_HOST}"
    # volumes:
    #   - ./snell-server.conf:/app/snell-server.conf
Use a custom snell-server.conf

If 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.conf

With this volume mount, the container will use your provided config file and ignore environment variables for generation.

Start the service:
docker compose up -d
Surge Client-Side Settings(iOS & macOS)
Prerequisites
  • 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=6, reuse=true
# mode=unshaped for higher throughput (must match server MODE):
# home = snell, YOUR_PUBLIC_IP or YOUR_FQDN, YOUR_PORT, psk=YOUR_PSK, version=6, mode=unshaped, 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
...

Error Handling

The server validates all input values before starting:

  • Invalid PORT: Must be an integer between 1025 and 65535
  • Invalid IPv6: Must be true or false if provided
  • Invalid DNS_IP_PREFERENCE: Must be default, prefer-ipv4, prefer-ipv6, ipv4-only, or ipv6-only
  • Invalid MODE: Must be default, unshaped, or unsafe-raw if provided
  • Invalid OBFS: Must be off or http if provided

If any validation fails, the server will display an error message and exit with code 1.

License

LICENSE

FOSSA Status

Tag summary

Content type

Image

Digest

sha256:df1d7e051

Size

6.7 MB

Last updated

16 days ago

docker pull 1byte/snell-server:6