fix: add web-builder Docker stage for JSX compilation
All checks were successful
check / check (push) Successful in 2m16s
All checks were successful
check / check (push) Successful in 2m16s
The previous rework removed web/dist/ from git tracking (correct) but did not add a web-builder stage to the Dockerfile. This caused //go:embed dist/* in web/embed.go to fail with 'no matching files found'. Add the 4-stage Dockerfile layout: 1. web-builder: compile Preact JSX SPA via esbuild 2. lint: format checking and linting with placeholder dist files 3. builder: compile Go binaries with real web assets from web-builder 4. runtime: minimal Alpine image with neoircd binary Also update README to document the 4-stage build.
This commit is contained in:
14
Dockerfile
14
Dockerfile
@@ -1,3 +1,13 @@
|
|||||||
|
# Web build stage — compile SPA from source
|
||||||
|
# node:22-alpine, 2026-03-09
|
||||||
|
FROM node@sha256:8094c002d08262dba12645a3b4a15cd6cd627d30bc782f53229a2ec13ee22a00 AS web-builder
|
||||||
|
WORKDIR /web
|
||||||
|
COPY web/package.json web/package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
COPY web/src/ src/
|
||||||
|
COPY web/build.sh build.sh
|
||||||
|
RUN sh build.sh
|
||||||
|
|
||||||
# Lint stage — fast feedback on formatting and lint issues
|
# Lint stage — fast feedback on formatting and lint issues
|
||||||
# golangci/golangci-lint:v2.1.6, 2026-03-02
|
# golangci/golangci-lint:v2.1.6, 2026-03-02
|
||||||
FROM golangci/golangci-lint@sha256:568ee1c1c53493575fa9494e280e579ac9ca865787bafe4df3023ae59ecf299b AS lint
|
FROM golangci/golangci-lint@sha256:568ee1c1c53493575fa9494e280e579ac9ca865787bafe4df3023ae59ecf299b AS lint
|
||||||
@@ -5,6 +15,9 @@ WORKDIR /src
|
|||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
COPY . .
|
COPY . .
|
||||||
|
# Create placeholder files so //go:embed dist/* in web/embed.go resolves
|
||||||
|
# without depending on the web-builder stage (lint should fail fast)
|
||||||
|
RUN mkdir -p web/dist && touch web/dist/index.html web/dist/style.css web/dist/app.js
|
||||||
RUN make fmt-check
|
RUN make fmt-check
|
||||||
RUN make lint
|
RUN make lint
|
||||||
|
|
||||||
@@ -21,6 +34,7 @@ COPY go.mod go.sum ./
|
|||||||
RUN go mod download
|
RUN go mod download
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
COPY --from=web-builder /web/dist/ web/dist/
|
||||||
|
|
||||||
RUN make test
|
RUN make test
|
||||||
|
|
||||||
|
|||||||
36
README.md
36
README.md
@@ -1858,26 +1858,16 @@ docker run -p 8080:8080 \
|
|||||||
neoirc
|
neoirc
|
||||||
```
|
```
|
||||||
|
|
||||||
The Dockerfile is a multi-stage build:
|
The Dockerfile is a 4-stage build:
|
||||||
1. **Build stage**: Compiles `neoircd` and `neoirc-cli` (CLI built to verify
|
1. **Web builder stage** (`web-builder`): Compiles the Preact JSX SPA into
|
||||||
compilation, not included in final image)
|
static assets (`web/dist/`) using esbuild
|
||||||
2. **Final stage**: Alpine Linux + `neoircd` binary only
|
2. **Lint stage** (`lint`): Runs formatting checks and linting via golangci-lint
|
||||||
|
3. **Build stage** (`builder`): Compiles `neoircd` and `neoirc-cli`, runs tests
|
||||||
|
(CLI built to verify compilation, not included in final image)
|
||||||
|
4. **Runtime stage**: Alpine Linux + `neoircd` binary only
|
||||||
|
|
||||||
```dockerfile
|
`web/dist/` is not committed to git — it is built from `web/src/` by the
|
||||||
FROM golang:1.24-alpine AS builder
|
web-builder stage during `docker build`.
|
||||||
WORKDIR /src
|
|
||||||
RUN apk add --no-cache make
|
|
||||||
COPY go.mod go.sum ./
|
|
||||||
RUN go mod download
|
|
||||||
COPY . .
|
|
||||||
RUN go build -o /neoircd ./cmd/neoircd/
|
|
||||||
RUN go build -o /neoirc-cli ./cmd/neoirc-cli/
|
|
||||||
|
|
||||||
FROM alpine:latest
|
|
||||||
COPY --from=builder /neoircd /usr/local/bin/neoircd
|
|
||||||
EXPOSE 8080
|
|
||||||
CMD ["neoircd"]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Binary
|
### Binary
|
||||||
|
|
||||||
@@ -2339,7 +2329,13 @@ neoirc/
|
|||||||
│ └── http.go # HTTP timeouts
|
│ └── http.go # HTTP timeouts
|
||||||
├── web/
|
├── web/
|
||||||
│ ├── embed.go # go:embed directive for SPA
|
│ ├── embed.go # go:embed directive for SPA
|
||||||
│ └── dist/ # Built SPA (vanilla JS, no build step)
|
│ ├── build.sh # esbuild script: JSX → dist/
|
||||||
|
│ ├── package.json # Node dependencies (esbuild, preact)
|
||||||
|
│ ├── src/ # SPA source (Preact JSX)
|
||||||
|
│ │ ├── app.jsx
|
||||||
|
│ │ ├── index.html
|
||||||
|
│ │ └── style.css
|
||||||
|
│ └── dist/ # Built SPA (generated by web-builder Docker stage)
|
||||||
│ ├── index.html
|
│ ├── index.html
|
||||||
│ ├── style.css
|
│ ├── style.css
|
||||||
│ └── app.js
|
│ └── app.js
|
||||||
|
|||||||
Reference in New Issue
Block a user