# syntax=docker/dockerfile:1 ARG RUNTIME_BASE=jrohy/trojan@sha256:f559fac7e9960614032e520c59405cec0e8937eca009a8169cb1d188f2b5ccb9 ARG MANAGER_VERSION=2.0.0 FROM node:20.11.1-bookworm AS frontend WORKDIR /src COPY trojan-web-master/package.json trojan-web-master/package-lock.json ./ RUN npm ci COPY trojan-web-master/ ./ RUN npm run build FROM golang:1.21.6-bookworm AS manager-build WORKDIR /src COPY trojan-master/go.mod trojan-master/go.sum ./ RUN go mod download COPY trojan-master/ ./ COPY --from=frontend /src/dist ./web/templates ARG MANAGER_VERSION RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w -X trojan/trojan.MVersion=${MANAGER_VERSION} -X trojan/trojan.BuildDate=compat-image -X trojan/trojan.GoVersion=go1.21.6 -X trojan/trojan.GitVersion=local-build" -o /out/trojan . # Production builds pass an immutable, verified runtime snapshot that contains # the legacy Trojan core. This avoids a runtime download and preserves protocol # compatibility during the first replacement release. FROM ${RUNTIME_BASE} COPY --from=manager-build /out/trojan /usr/local/bin/trojan COPY trojan-master/asset/trojan.service /etc/systemd/system/trojan.service COPY trojan-master/asset/trojan-web.service /etc/systemd/system/trojan-web.service COPY trojan-master/asset/trojan-acme-challenge.service /etc/systemd/system/trojan-acme-challenge.service COPY trojan-master/asset/trojan-acme-renew.service /etc/systemd/system/trojan-acme-renew.service COPY trojan-master/asset/trojan-acme-renew.timer /etc/systemd/system/trojan-acme-renew.timer COPY trojan-master/asset/renew-trojan-certificate /usr/local/sbin/renew-trojan-certificate COPY trojan-master/asset/compat-init /usr/local/sbin/compat-init RUN chmod 0755 /usr/local/sbin/renew-trojan-certificate /usr/local/sbin/compat-init HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 CMD curl -fsS "http://127.0.0.1:${WEB_PORT:-8081}/healthz" || exit 1 CMD ["/usr/local/sbin/compat-init"]