server/Dockerfile (2896B)
1 # syntax=docker/dockerfile:1
2 #
3 # transtation server -- Xray-core with a VLESS/REALITY inbound and an optional
4 # Cloudflare WARP outbound.
5 #
6 # The image holds NO capabilities and needs NO devices. Xray's WireGuard
7 # outbound probes for CAP_NET_ADMIN up front and takes its in-process gVisor
8 # network stack when it is absent -- which is exactly Docker's default. Adding
9 # --cap-add NET_ADMIN makes it try kernel TUN instead, which writes to
10 # /proc/sys before opening the device, hits Docker's read-only /proc/sys, and
11 # fails with no fallback. Do not add capabilities to this image.
12
13 FROM --platform=$BUILDPLATFORM alpine:3.23 AS fetch
14 ARG TARGETARCH
15 # Latest stable Xray. XTLS marks nearly every other release "prerelease".
16 ARG XRAY_VERSION=v26.3.27
17 ARG WGCF_VERSION=2.2.32
18 RUN apk add --no-cache curl unzip && set -eu; \
19 case "$TARGETARCH" in \
20 amd64) XZ=Xray-linux-64.zip; WA=amd64 ;; \
21 arm64) XZ=Xray-linux-arm64-v8a.zip; WA=arm64 ;; \
22 *) echo "transtation: unsupported TARGETARCH=$TARGETARCH (amd64 and arm64 only)" >&2; exit 1 ;; \
23 esac; \
24 B=https://github.com/XTLS/Xray-core/releases/download/${XRAY_VERSION}; \
25 curl -fsSLO "$B/$XZ"; \
26 curl -fsSLO "$B/$XZ.dgst"; \
27 EXP=$(awk '/^SHA2-256/ {print $2}' "$XZ.dgst"); \
28 # Without this guard a changed .dgst format yields an empty expectation and
29 # `sha256sum -c` happily verifies nothing. The label is "SHA2-256= <hex>"
30 # (openssl style), not "SHA256".
31 printf '%s' "$EXP" | grep -Eq '^[0-9a-f]{64}$' || { echo "no usable SHA2-256 line in $XZ.dgst" >&2; exit 1; }; \
32 echo "$EXP $XZ" | sha256sum -c -; \
33 unzip -j "$XZ" xray -d /out; \
34 W=https://github.com/ViRb3/wgcf/releases/download/v${WGCF_VERSION}; \
35 curl -fsSL -o /out/wgcf "$W/wgcf_${WGCF_VERSION}_linux_${WA}"; \
36 curl -fsSL "$W/checksums.txt" | grep " wgcf_${WGCF_VERSION}_linux_${WA}\$" \
37 | awk '{print $1" /out/wgcf"}' | sha256sum -c -; \
38 chmod 0755 /out/xray /out/wgcf
39
40 FROM alpine:3.23
41 RUN apk add --no-cache ca-certificates curl jq libqrencode-tools \
42 && adduser -D -u 10001 xray \
43 && mkdir -p /data \
44 && chown xray:xray /data \
45 && chmod 0700 /data
46 # /data is created and owned here so that a fresh NAMED VOLUME inherits this
47 # ownership on first mount. A bind mount does not -- see the error message in
48 # `transtation run` if you use one.
49
50 COPY --from=fetch /out/xray /out/wgcf /usr/local/bin/
51 COPY server/transtation /usr/local/bin/transtation
52 COPY NOTICE /NOTICE
53
54 # No geoip.dat / geosite.dat on purpose: 29 MiB for one rule that an explicit
55 # CIDR list replaces. Any "geoip:" or "geosite:" routing rule will fail at
56 # startup with file-not-found.
57
58 ENV TT_MANAGED=docker
59 USER xray
60 VOLUME /data
61 EXPOSE 8443
62 HEALTHCHECK --interval=5m --timeout=15s --retries=3 --start-period=45s \
63 CMD ["/usr/local/bin/transtation", "health"]
64 ENTRYPOINT ["/usr/local/bin/transtation"]
65 CMD ["run"]