* Modernize build: switch to CMake, add unit tests, fix man pages
Remove autotools (configure.ac, Makefile.am, m4/, autogen.sh) and make
CMake the sole build system. Enhance CMake with proper Find modules for
MbedTLS, libsodium, PCRE, and c-ares with version/feature detection.
Add support for connmarktos, nftables, stack protector, and MinGW.
Add 10 unit test suites (CTest) covering base64, buffer, cache, crypto,
jconf, json, netutils, ppbloom, rule, and utils modules. Add a Python
stress test measuring bandwidth per cipher with memory leak detection.
Fix man page typos ("Resovle" -> "Resolve"), document missing TCP buffer
options, fix ss-manager duplicate --executable entry, add example section
to ss-tunnel, and document --workdir and --nftables-sets options.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Migrate from PCRE to PCRE2
Replace legacy PCRE (libpcre3) with PCRE2 (libpcre2-8). PCRE1 has been
end-of-life since 2021.
- src/rule.h: use pcre2_code and pcre2_match_data types
- src/rule.c: pcre_compile -> pcre2_compile, pcre_exec -> pcre2_match,
pcre_free -> pcre2_code_free, with proper error message retrieval
- cmake/FindPCRE.cmake -> cmake/FindPCRE2.cmake: find libpcre2-8 via
pkg-config, pcre2-config, or manual search
- Update all CMakeLists.txt, config.h.cmake, configure.cmake, README.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update Dockerfiles: use CMake build and pcre2-dev
The alpine Dockerfile still used autotools (autogen.sh/configure) which
were removed. Switch to cmake build and replace pcre-dev with pcre2-dev.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Docker build: disable tests and remove git dep
The tests/ directory is excluded by .dockerignore, so pass
-DBUILD_TESTING=OFF to cmake. Submodules are already checked out
by actions/checkout, no need for git inside the container.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Docker build: disable static libs (not available in alpine)
Alpine's mbedtls-dev only provides shared libraries. Disable static
build since Docker only needs shared binaries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Rewrite GitHub Actions: build and test directly on runner
Replace Docker-based CI with direct cmake build on ubuntu-latest and
macos-latest. Install dependencies via apt/brew, build with cmake,
run unit tests with ctest.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix CI: use mbedtls@3 on macOS, disable static build
- macOS: brew's mbedtls is now v4 (incompatible), use mbedtls@3
- Disable static build since CI runners lack static lib packages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix test build on Linux: add stdint.h and link libm
- test_ppbloom.c: add missing #include <stdint.h> for uint8_t
- test_json: link against libm for pow() used in json.c
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix test_ppbloom link: add libm for bloom's log()
On Linux, libbloom uses log() which requires explicit -lm linkage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Linux build: link libm for test_buffer and test_crypto, fix warnings
Both test_buffer and test_crypto link libbloom.so which uses log() from
libm. Also fix unused variable warnings in test_json.c that would fail
with -Werror.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Linux build: link libm for test_jconf (json.c uses pow)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* CI: add unit test and stress test steps to GitHub Actions
Split the Test step into separate "Unit tests" (ctest) and "Stress test"
(stress_test.py with 10MB transfer across all AEAD ciphers) steps for
better visibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Shadowsocks-libev Docker Image
shadowsocks-libev is a lightweight secured socks5 proxy for embedded devices and low end boxes. It is a port of shadowsocks created by @clowwindy maintained by @madeye and @linusyang.
Docker images are built for quick deployment in various computing cloud providers. For more information on docker and containerization technologies, refer to official document.
Prepare the host
Many cloud providers offer docker-ready environments, for instance the CoreOS Droplet in DigitalOcean or the Container-Optimized OS in Google Cloud.
If you need to install docker yourself, follow the official installation guide.
Pull the image
$ docker pull shadowsocks/shadowsocks-libev
This pulls the latest release of shadowsocks-libev.
You can also choose to pull a previous release or to try the bleeding edge build:
$ docker pull shadowsocks/shadowsocks-libev:<tag>
$ docker pull shadowsocks/shadowsocks-libev:edge
A list of supported tags can be found at Docker Hub.
Start a container
$ docker run -p 8388:8388 -p 8388:8388/udp -d --restart always shadowsocks/shadowsocks-libev:latest
This starts a container of the latest release with all the default settings, which is equivalent to
$ ss-server -s 0.0.0.0 -p 8388 -k "$(hostname)" -m aes-256-gcm -t 300 -d "8.8.8.8,8.8.4.4" -u
Note
: It's the hostname in the container that is used as the password, not that of the host.
With custom port
In most cases you'll want to change a thing or two, for instance the port which the server listens on. This is done by changing the -p arguments.
Here's an example to start a container that listens on 28388 (both TCP and UDP):
$ docker run -p 28388:8388 -p 28388:8388/udp -d --restart always shadowsocks/shadowsocks-libev
With custom password
Another thing you may want to change is the password. To change that, you can pass your own password as an environment variable when starting the container.
Here's an example to start a container with 9MLSpPmNt as the password:
$ docker run -e PASSWORD=9MLSpPmNt -p 8388:8388 -p 8388:8388/udp -d --restart always shadowsocks/shadowsocks-libev
⚠️ Click here to generate a strong password to protect your server.
With password as a mounted file or a Docker secret (swarm only)
Instead of hardcoding a password to the docker-compose file or docker run command, you can mount in a file that contains the password. To do so, pass the path that you mounted to the container as the PASSWORD_FILE environment variable.
If you are running Docker Swarm, you can also utilize Docker secrets. To do so, pass the name of the secret as the PASSWORD_SECRET environment variable. If you specify both PASSWORD_FILE and PASSWORD_SECRET, the latter will take effect.
This is a sample docker-compose.yml file that uses the external Docker secret named shadowsocks as the password.
shadowsocks:
image: shadowsocks/shadowsocks-libev
ports:
- "8388:8388"
environment:
- METHOD=aes-256-gcm
- PASSWORD_SECRET=shadowsocks
secrets:
- shadowsocks
This is a sample docker service create command that uses the external Docker secret named shadowsocks as the password.
docker service create -e PASSWORD_SECRET=shadowsocks -p 8388:8388 -p 8388:8388/udp --secret shadowsocks shadowsocks/shadowsocks-libev
With other customizations
Besides PASSWORD, the image also defines the following environment variables that you can customize:
SERVER_ADDR: the IP/domain to bind to, defaults to0.0.0.0SERVER_ADDR_IPV6: the IPv6 address to bind to, defaults to::0METHOD: encryption method to use, defaults toaes-256-gcmTIMEOUT: defaults to300DNS_ADDRS: DNS servers to redirect NS lookup requests to, defaults to8.8.8.8,8.8.4.4TZ: Timezone, defaults toUTC
Additional arguments supported by ss-server can be passed with the environment variable ARGS, for instance to start in verbose mode:
$ docker run -e ARGS=-v -p 8388:8388 -p 8388:8388/udp -d --restart always shadowsocks/shadowsocks-libev:latest
Use docker-compose to manage (optional)
It is very handy to use docker-compose to manage docker containers. You can download the binary at https://github.com/docker/compose/releases.
This is a sample docker-compose.yml file.
shadowsocks:
image: shadowsocks/shadowsocks-libev
ports:
- "8388:8388"
environment:
- METHOD=aes-256-gcm
- PASSWORD=9MLSpPmNt
restart: always
It is highly recommended that you setup a directory tree to make things easy to manage.
$ mkdir -p ~/fig/shadowsocks/
$ cd ~/fig/shadowsocks/
$ curl -sSLO https://github.com/shadowsocks/shadowsocks-libev/raw/master/docker/alpine/docker-compose.yml
$ docker-compose up -d
$ docker-compose ps
Finish
At last, download shadowsocks client here. Don't forget to share internet with your friends.
{
"server": "your-vps-ip",
"server_port": 8388,
"local_address": "0.0.0.0",
"local_port": 1080,
"password": "9MLSpPmNt",
"timeout": 600,
"method": "aes-256-gcm"
}