mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-07 21:54:10 +00:00
Phase 8 cut all panel HTML routes over to web/dist/ and embedded the Vite bundle into the Go binary via //go:embed all:dist. web/dist/ is .gitignored, so on a fresh CI checkout it doesn't exist — every Go build since Phase 8 has been failing with "pattern dist: no matching files found" or producing a binary that 404s on first asset request. release.yml: add a setup-node@v4 + npm ci + npm run build trio before the existing go build step in both the Linux matrix job (7 arches) and the Windows job. npm cache is keyed on frontend/package-lock.json. Dockerfile: add a node:22-alpine frontend stage that runs npm ci + npm run build and emits to /src/web/dist (via vite.config.js's outDir). The golang builder stage then COPY --from=frontend /src/web/dist into ./web/dist before the go build, so embed.FS sees the bundle. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
75 lines
2.1 KiB
Docker
75 lines
2.1 KiB
Docker
# ========================================================
|
|
# Stage: Frontend (Vite)
|
|
# ========================================================
|
|
# web/dist/ is .gitignored and embedded into the Go binary via
|
|
# //go:embed all:dist in web/web.go, so the SPA bundle MUST be built
|
|
# before the Go compile step. We build it in its own stage so the
|
|
# Go builder image doesn't need Node installed.
|
|
FROM node:22-alpine AS frontend
|
|
WORKDIR /src/frontend
|
|
COPY frontend/package.json frontend/package-lock.json ./
|
|
RUN npm ci
|
|
COPY frontend/ ./
|
|
RUN npm run build
|
|
# Vite outDir is set to ../web/dist (see frontend/vite.config.js), so
|
|
# the bundle lands at /src/web/dist — that's what we copy into the
|
|
# next stage.
|
|
|
|
# ========================================================
|
|
# Stage: Builder
|
|
# ========================================================
|
|
FROM golang:1.26-alpine AS builder
|
|
WORKDIR /app
|
|
ARG TARGETARCH
|
|
|
|
RUN apk --no-cache --update add \
|
|
build-base \
|
|
gcc \
|
|
curl \
|
|
unzip
|
|
|
|
COPY . .
|
|
COPY --from=frontend /src/web/dist ./web/dist
|
|
|
|
ENV CGO_ENABLED=1
|
|
ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE"
|
|
RUN go build -ldflags "-w -s" -o build/x-ui main.go
|
|
RUN ./DockerInit.sh "$TARGETARCH"
|
|
|
|
# ========================================================
|
|
# Stage: Final Image of 3x-ui
|
|
# ========================================================
|
|
FROM alpine
|
|
ENV TZ=Asia/Tehran
|
|
WORKDIR /app
|
|
|
|
RUN apk add --no-cache --update \
|
|
ca-certificates \
|
|
tzdata \
|
|
fail2ban \
|
|
bash \
|
|
curl \
|
|
openssl
|
|
|
|
COPY --from=builder /app/build/ /app/
|
|
COPY --from=builder /app/DockerEntrypoint.sh /app/
|
|
COPY --from=builder /app/x-ui.sh /usr/bin/x-ui
|
|
|
|
|
|
# Configure fail2ban
|
|
RUN rm -f /etc/fail2ban/jail.d/alpine-ssh.conf \
|
|
&& cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local \
|
|
&& sed -i "s/^\[ssh\]$/&\nenabled = false/" /etc/fail2ban/jail.local \
|
|
&& sed -i "s/^\[sshd\]$/&\nenabled = false/" /etc/fail2ban/jail.local \
|
|
&& sed -i "s/#allowipv6 = auto/allowipv6 = auto/g" /etc/fail2ban/fail2ban.conf
|
|
|
|
RUN chmod +x \
|
|
/app/DockerEntrypoint.sh \
|
|
/app/x-ui \
|
|
/usr/bin/x-ui
|
|
|
|
ENV XUI_ENABLE_FAIL2BAN="true"
|
|
EXPOSE 2053
|
|
VOLUME [ "/etc/x-ui" ]
|
|
CMD [ "./x-ui" ]
|
|
ENTRYPOINT [ "/app/DockerEntrypoint.sh" ]
|