transtation.git

transtation

~ Your own VLESS + REALITY proxy with optional Cloudflare WARP egress. Server in a container or native; native client with a fail-closed killswitch.
git clone https://github.com/debuman/transtation.git

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"]