Dockerfile
Rama main · réplica de lectura del repositorio original.
# ── Frontend source ──────────────────────────────────────────────────────────
FROM --platform=$BUILDPLATFORM alpine:3.22.0 AS frontend-source
ARG FRONTEND_REPOSITORY=https://github.com/kittors/codeProxy.git
ARG FRONTEND_REF=main
ARG FRONTEND_COMMIT=
RUN apk add --no-cache git ca-certificates
WORKDIR /src
# Local `docker compose up -d` from the CliRelay repo should always build the
# current management panel instead of depending on a separately checked out
# `frontend/` directory or an outdated published image. FRONTEND_COMMIT is part
# of this layer on purpose: a moving branch name alone is invisible to Docker's
# cache, so the exact frontend SHA must bust the clone layer.
RUN git clone --depth=1 --branch "${FRONTEND_REF}" "${FRONTEND_REPOSITORY}" frontend \
&& if [ -n "${FRONTEND_COMMIT}" ]; then \
cd frontend \
&& git fetch --depth=1 origin "${FRONTEND_COMMIT}" \
&& git checkout --detach "${FRONTEND_COMMIT}"; \
fi
# ── Frontend build ───────────────────────────────────────────────────────────
FROM --platform=$BUILDPLATFORM oven/bun:1 AS frontend-builder
WORKDIR /frontend
COPY --from=frontend-source /src/frontend/ .
ARG UI_VERSION=dev
ARG FRONTEND_REPOSITORY=https://github.com/kittors/codeProxy.git
ARG FRONTEND_REF=main
ARG FRONTEND_COMMIT=none
ARG BUILD_DATE=unknown
ENV VITE_APP_VERSION=${UI_VERSION}
ENV VITE_PANEL_REPOSITORY=${FRONTEND_REPOSITORY}
ENV VITE_PANEL_REF=${FRONTEND_REF}
ENV VITE_PANEL_COMMIT=${FRONTEND_COMMIT}
ENV VITE_PANEL_BUILD_DATE=${BUILD_DATE}
RUN bun install --frozen-lockfile
RUN bun run build
# ── Backend build ────────────────────────────────────────────────────────────
FROM --platform=$BUILDPLATFORM golang:1.26.10-alpine AS backend-builder
WORKDIR /app
COPY go.mod go.sum ./
COPY updater/go.mod ./updater/go.mod
RUN go mod download
COPY . .
ARG TARGETOS=linux
ARG TARGETARCH
ARG VERSION=dev
ARG COMMIT=none
ARG BUILD_DATE=unknown
ARG UI_VERSION=dev
ARG FRONTEND_REF=main
ARG FRONTEND_COMMIT=none
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \
-ldflags="-s -w \
-X 'github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo.Version=${VERSION}' \
-X 'github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo.Commit=${COMMIT}' \
-X 'github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo.BuildDate=${BUILD_DATE}' \
-X 'github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo.FrontendVersion=${UI_VERSION}' \
-X 'github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo.FrontendCommit=${FRONTEND_COMMIT}' \
-X 'github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo.FrontendRef=${FRONTEND_REF}'" \
-o ./CLIProxyAPI ./cmd/server/
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \
-ldflags="-s -w" \
-o ./clirelay-compose-migrate ./cmd/composemigrate/
# The updater is a separate Go module with no dependencies, so it builds on its own.
# Keeping it out of the main module is what stops it from drifting along with the
# application it is responsible for updating.
RUN cd ./updater && CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \
-ldflags="-s -w" \
-o /app/clirelay-updater .
# ── Runtime ──────────────────────────────────────────────────────────────────
FROM alpine:3.22.0
RUN apk add --no-cache tzdata ca-certificates docker-cli docker-cli-compose su-exec
RUN addgroup -S -g 10001 clirelay \
&& adduser -S -D -H -u 10001 -h /CLIProxyAPI -s /sbin/nologin -G clirelay clirelay \
&& mkdir -p /CLIProxyAPI/panel /CLIProxyAPI/auths /CLIProxyAPI/logs /CLIProxyAPI/data \
&& chown -R clirelay:clirelay /CLIProxyAPI
COPY --from=backend-builder --chown=clirelay:clirelay /app/CLIProxyAPI /CLIProxyAPI/CLIProxyAPI
COPY --from=backend-builder --chown=clirelay:clirelay /app/clirelay-updater /CLIProxyAPI/clirelay-updater
COPY --from=backend-builder --chown=clirelay:clirelay /app/clirelay-compose-migrate /CLIProxyAPI/clirelay-compose-migrate
COPY --from=frontend-builder --chown=clirelay:clirelay /frontend/dist/ /CLIProxyAPI/panel/
COPY --chown=clirelay:clirelay config.example.yaml /CLIProxyAPI/config.example.yaml
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
COPY scripts/init-compose-env.sh /usr/local/bin/clirelay-init-env
WORKDIR /CLIProxyAPI
EXPOSE 8317
ENV TZ=Asia/Shanghai \
MANAGEMENT_PANEL_DIR=/CLIProxyAPI/panel \
AUTH_PATH=/CLIProxyAPI/auths \
CLIRELAY_LOCALE=zh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh /usr/local/bin/clirelay-init-env \
&& cp /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo "${TZ}" > /etc/timezone
USER root
ENTRYPOINT ["docker-entrypoint.sh"]
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget -q -T 2 -O /dev/null http://127.0.0.1:8317/healthz
CMD ["./CLIProxyAPI"]