FROM node:22 AS web-builder COPY web/package.json /web/package.json COPY web/shared/ /web/shared/ COPY web/frpc/ /web/frpc/ WORKDIR /web RUN npm install WORKDIR /web/frpc RUN npm run build FROM golang:1.25 AS building COPY . /building COPY --from=web-builder /web/frpc/dist /building/web/frpc/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc FROM alpine:3 RUN apk add --no-cache tzdata COPY --from=building /building/bin/frpc /usr/bin/frpc ENTRYPOINT ["/usr/bin/frpc"]
FROM node:22 AS web-builder COPY web/package.json /web/package.json COPY web/shared/ /web/shared/ COPY web/frps/ /web/frps/ WORKDIR /web RUN npm install WORKDIR /web/frps RUN npm run build FROM golang:1.25 AS building COPY . /building COPY --from=web-builder /web/frps/dist /building/web/frps/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frps -o bin/frps ./cmd/frps FROM alpine:3 RUN apk add --no-cache tzdata COPY --from=building /building/bin/frps /usr/bin/frps ENTRYPOINT ["/usr/bin/frps"]
Concerns: No Dockerfile found at repo root
FROM node:22 AS web-builder # Build frontend assets for both frpc and frps COPY web/package.json /web/package.json COPY web/shared/ /web/shared/ COPY web/frpc/ /web/frpc/ COPY web/frps/ /web/frps/ WORKDIR /web RUN npm install # Build frpc frontend WORKDIR /web/frpc RUN npm run build # Build frps frontend WORKDIR /web/frps RUN npm run build FROM golang:1.25 AS building # Build Go binaries for both frpc and frps COPY . /building COPY --from=web-builder /web/frpc/dist /building/web/frpc/dist COPY --from=web-builder /web/frps/dist /building/web/frps/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frps -o bin/frps ./cmd/frps FROM alpine:3 RUN apk add --no-cache tzdata # Final images: two separate targets produced from the same Dockerfile # Default image (last stage) will be used by docker build without --target specification. # To build specific images, use --target frpc or --target frps. # Frpc final image FROM alpine:3 AS frpc RUN apk add --no-cache tzdata COPY --from=building /building/bin/frpc /usr/bin/frpc ENTRYPOINT ["/usr/bin/frpc"] # Frps final image FROM alpine:3 AS frps RUN apk add --no-cache tzdata COPY --from=building /building/bin/frps /usr/bin/frps ENTRYPOINT ["/usr/bin/frps"]
Build timed out after 600s
.git node_modules dist build bin vendor *.log .DS_Store
Build timed out after 600s
FROM node:22 AS web-builder-frpc # Build frontend assets for frpc COPY web/package.json /web/package.json COPY web/shared/ /web/shared/ COPY web/frpc/ /web/frpc/ WORKDIR /web RUN npm install WORKDIR /web/frpc RUN npm run build FROM golang:1.25 AS building-frpc COPY . /building COPY --from=web-builder-frpc /web/frpc/dist /building/web/frpc/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc FROM alpine:3 RUN apk add --no-cache tzdata COPY --from=building-frpc /building/bin/frpc /usr/bin/frpc ENTRYPOINT ["/usr/bin/frpc"]
Build timed out after 600s
No files found matching pattern.
# Multi-stage Dockerfile to build frpc and frps from source with frontend assets # 1) Build frontend assets (Node.js) for both frpc and frps FROM node:22 AS web-builder # Copy frontend source trees COPY web/package.json /web/package.json COPY web/shared/ /web/shared/ COPY web/frpc/ /web/frpc/ COPY web/frps/ /web/frps/ WORKDIR /web RUN npm install WORKDIR /web/frpc RUN npm run build WORKDIR /web/frps RUN npm run build # 2) Build frpc binary from Go sources FROM golang:1.25 AS building-frpc COPY . /building COPY --from=web-builder /web/frpc/dist /building/web/frpc/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc # 3) Build frps binary from Go sources FROM golang:1.25 AS building-frps COPY . /building COPY --from=web-builder /web/frps/dist /building/web/frps/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frps -o bin/frps ./cmd/frps # 4) Runtime images (minimal Alpine, with tzdata) FROM alpine:3 RUN apk add --no-cache tzdata # Frpc runtime COPY --from=building-frpc /building/bin/frpc /usr/bin/frpc ENTRYPOINT ["/usr/bin/frpc"] # Frps runtime (secondary image) FROM alpine:3 AS frps-runtime RUN apk add --no-cache tzdata COPY --from=building-frps /building/bin/frps /usr/bin/frps ENTRYPOINT ["/usr/bin/frps"]
Concerns: The first runtime stage has no alias, which means building the frpc runtime image via docker build --target would be awkward or unclear. Providing explicit aliases for all final images improves usability., There are no health checks or tests included in the Dockerfile; smoke tests would rely on the presence of endpoints or a script, which may not align with real FRP behavior without a known health API. Smoke [FAIL]: docker run --rm --entrypoint "" <image> sh -c 'set -e; cat > /tmp/frps.ini <<"EOF"\n[common]\nbind_port = 7000\nEOF\n/usr/bin/frps -c /tmp/frps.ini 2>&1 | head -n 5 Output: sh: syntax error: unterminated quoted string Smoke [FAIL]: docker run --rm --entrypoint "" <image> sh -c 'set -e; cat > /tmp/frpc.ini <<"EOF"\n[common]\nserver_addr = 127.0.0.1\nserver_port = 7000\nEOF\n/usr/bin/frpc -c /tmp/frpc.ini 2>&1 | head -n 5 Output: sh: syntax error: unterminated quoted string
# Multi-stage build: frontend, then two Go binaries, then a minimal runtime that contains both frpc and frps # 1) Build frontend assets for both frpc and frps FROM node:22 AS web-builder COPY web/package.json /web/package.json COPY web/shared/ /web/shared/ COPY web/frpc/ /web/frpc/ COPY web/frps/ /web/frps/ WORKDIR /web RUN npm install # Build frontend for frpc WORKDIR /web/frpc RUN npm run build # Build frontend for frps WORKDIR /web/frps RUN npm run build # 2) Build frpc binary FROM golang:1.25 AS frpc-builder COPY . /building COPY --from=web-builder /web/frpc/dist /building/web/frpc/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc # 3) Build frps binary FROM golang:1.25 AS frps-builder COPY . /building COPY --from=web-builder /web/frps/dist /building/web/frps/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frps -o bin/frps ./cmd/frps # 4) Runtime image containing both binaries FROM alpine:3 RUN apk add --no-cache tzdata COPY --from=frpc-builder /building/bin/frpc /usr/bin/frpc COPY --from=frps-builder /building/bin/frps /usr/bin/frps # Provide a default shell to aid testing; entries in tests override entrypoint as needed CMD ["/bin/sh"] # End of Dockerfile
Build timed out after 600s
# Root multi-stage Dockerfile to build frpc and frps from source (no frontend build dependencies) # 1) Build both binaries using Go in a single builder stage FROM golang:1.25 AS builder WORKDIR /build # Cache dependencies first COPY go.mod go.sum ./ RUN go mod download # Copy all source COPY . ./ # Build both binaries (CGO disabled for static compatibility) RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frps -o bin/frps ./cmd/frps # 2) Runtime image (Alpine) with tzdata FROM alpine:3 RUN apk add --no-cache tzdata # Copy both statically linked binaries COPY --from=builder /build/bin/frpc /usr/bin/frpc COPY --from=builder /build/bin/frps /usr/bin/frps # Default to showing help if containers are run directly; smoke tests override entrypoint CMD ["/bin/sh"]
- Exact error message and exit code - web/frpc/embed.go:11:12: pattern dist: no matching files found - Exit code: 1 - Failing command/step - [builder 6/7] RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc - Missing packages or files mentioned - The go:embed directive in web/frpc/embed.go references the pattern "dist"; no matching files found in the build context. - Version mismatch info - Base images used: alpine:3 and golang:1.25. No explicit version mismatch reported.
# Root multi-stage Dockerfile to build frpc and frps from source with frontend assets # 1) Build frontend assets for both frpc and frps FROM node:22 AS web-builder # Frontend sources COPY web/package.json /web/package.json COPY web/shared/ /web/shared/ COPY web/frpc/ /web/frpc/ COPY web/frps/ /web/frps/ WORKDIR /web RUN npm install # Build frontend assets for frpc WORKDIR /web/frpc RUN npm run build # Build frontend assets for frps WORKDIR /web/frps RUN npm run build # 2) Build frpc binary FROM golang:1.25 AS frpc-builder COPY . /building COPY --from=web-builder /web/frpc/dist /building/web/frpc/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc # 3) Build frps binary FROM golang:1.25 AS frps-builder COPY . /building COPY --from=web-builder /web/frps/dist /building/web/frps/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frps -o bin/frps ./cmd/frps # 4) Runtime image containing both binaries FROM alpine:3 RUN apk add --no-cache tzdata COPY --from=frpc-builder /building/bin/frpc /usr/bin/frpc COPY --from=frps-builder /building/bin/frps /usr/bin/frps # Default to a shell; tests override entrypoint as needed CMD ["/bin/sh"]
Build timed out after 600s
# Root multi-target Dockerfile to build frpc and frps from source with frontend assets # 1) Build frontend assets for both frpc and frps FROM node:22 AS web-builder # Frontend sources COPY web/package.json /web/package.json COPY web/shared/ /web/shared/ COPY web/frpc/ /web/frpc/ COPY web/frps/ /web/frps/ WORKDIR /web RUN npm install # Build frontend for frpc WORKDIR /web/frpc RUN npm run build # Build frontend for frps WORKDIR /web/frps RUN npm run build # 2) Build frpc binary FROM golang:1.25 AS frpc-builder COPY . /building COPY --from=web-builder /web/frpc/dist /building/web/frpc/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frpc -o bin/frpc ./cmd/frpc # 3) Build frps binary FROM golang:1.25 AS frps-builder COPY . /building COPY --from=web-builder /web/frps/dist /building/web/frps/dist WORKDIR /building RUN env CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -tags frps -o bin/frps ./cmd/frps # 4) Frpc final image FROM alpine:3 AS frpc RUN apk add --no-cache tzdata COPY --from=frpc-builder /building/bin/frpc /usr/bin/frpc ENTRYPOINT ["/usr/bin/frpc"] # 5) Frps final image FROM alpine:3 AS frps RUN apk add --no-cache tzdata COPY --from=frps-builder /building/bin/frps /usr/bin/frps ENTRYPOINT ["/usr/bin/frps"]