1 Commits

Author SHA1 Message Date
clawbot
de38b03508 feat: split Dockerfile into dedicated lint and build stages
All checks were successful
check / check (push) Successful in 5s
- Add dedicated lint stage using pre-built golangci-lint v2.10.1 image
- Move fmt-check and lint from build stage to lint stage for faster feedback
- Remove manual golangci-lint binary download (now handled by lint image)
- Remove curl from build stage dependencies (no longer needed)
- Add COPY --from=lint dependency to force BuildKit to run lint stage
- Build stage now runs only tests and compilation

closes #20
2026-03-02 00:05:52 -08:00
2 changed files with 78 additions and 72 deletions

View File

@@ -1,33 +1,38 @@
# Build stage
# Lint stage — fast feedback on formatting and lint issues
# golangci/golangci-lint:v2.10.1, 2026-03-01
FROM golangci/golangci-lint@sha256:ea84d14c2fef724411be7dc45e09e6ef721d748315252b02df19a7e3113ee763 AS lint
# Install CGO dependencies needed for static analysis of vips/libheif code
RUN apt-get update && apt-get install -y --no-install-recommends \
libvips-dev \
libheif-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN make fmt-check
RUN make lint
# Build stage — tests and compilation
# golang:1.25.4-alpine, 2026-02-25
FROM golang:1.25.4-alpine@sha256:d3f0cf7723f3429e3f9ed846243970b20a2de7bae6a5b66fc5914e228d831bbb AS builder
ARG VERSION=dev
# Force BuildKit to run the lint stage by creating a stage dependency
COPY --from=lint /src/go.sum /dev/null
# Install build dependencies for CGO image libraries
RUN apk add --no-cache \
build-base \
vips-dev \
libheif-dev \
pkgconfig \
curl
# golangci-lint v2.10.1, 2026-02-25
# SHA-256 checksums per architecture (amd64 / arm64)
RUN set -e; \
ARCH="$(uname -m)"; \
if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then \
GOARCH="arm64"; \
HASH="6652b42ae02915eb2f9cb2a2e0cac99514c8eded8388d88ae3e06e1a52c00de8"; \
else \
GOARCH="amd64"; \
HASH="dfa775874cf0561b404a02a8f4481fc69b28091da95aa697259820d429b09c99"; \
fi; \
curl -sSfL "https://github.com/golangci/golangci-lint/releases/download/v2.10.1/golangci-lint-2.10.1-linux-${GOARCH}.tar.gz" -o /tmp/golangci-lint.tar.gz && \
echo "${HASH} /tmp/golangci-lint.tar.gz" | sha256sum -c - && \
tar -xzf /tmp/golangci-lint.tar.gz -C /tmp && \
mv "/tmp/golangci-lint-2.10.1-linux-${GOARCH}/golangci-lint" /usr/local/bin/ && \
rm -rf /tmp/golangci-lint*
pkgconfig
WORKDIR /src
@@ -38,8 +43,8 @@ RUN GOTOOLCHAIN=auto go mod download
# Copy source code
COPY . .
# Run all checks (fmt-check, lint, test)
RUN make check
# Run tests
RUN make test
# Build with CGO enabled
RUN CGO_ENABLED=1 GOTOOLCHAIN=auto go build -ldflags "-X main.Version=${VERSION}" -o /pixad ./cmd/pixad

101
TODO.md
View File

@@ -1,64 +1,65 @@
# Status
# Pixa 1.0 TODO
pre-1.0. No git tags. Full policy file set is present, but make check
fails on main with 10 gosec lint findings, so main is not green.
Remaining tasks sorted by priority for a working 1.0 release.
# Next Step
## P0: Critical for 1.0
Fix the 10 gosec findings so make check passes on main. Fix each issue
properly (no blanket nolint suppressions) and confirm lint, tests, and
CI are green. This restores the main-always-green policy.
### Image Processing
- [x] Add WebP encoding support (currently returns error)
- [ ] Add AVIF encoding support (currently returns error)
# Completed Steps
### Manual Testing (verify auth/encrypted URLs work)
- [ ] Manual test: visit `/`, see login form
- [ ] Manual test: enter wrong key, see error
- [ ] Manual test: enter correct signing key, see generator form
- [ ] Manual test: generate encrypted URL, verify it works
- [ ] Manual test: wait for expiration or use short TTL, verify expired URL returns 410
- [ ] Manual test: logout, verify redirected to login
- 2026-02-25: Docker arm64 build fixed via architecture detection for
golangci-lint download (#16)
- 2026-02-25: full repo policy compliance pass (#14): LICENSE,
REPO_POLICIES.md, .editorconfig, Gitea Actions CI workflow, Docker
images pinned by hash, README restructured to policy sections, hooks
Makefile target, golangci-lint errors resolved
- 2026-02-20: stale local dev config files removed (#12)
- 2026-02-09: correctness fixes: negative cache checked in Service.Get()
before upstream fetch (#8); Stats() column scanning and HitRate
computation corrected (#9)
- 2026-02-08: AllowHTTP propagated to SourceURL() scheme selection (#6)
- WebP encoding support added (P0 item, checked off in TODO)
- 2026-01-08: initial implementation with Makefile and TODO checklist
### Cache Management
- [ ] Implement cache size management/eviction (prevent disk from filling up)
# Future Steps
### Configuration
- [ ] Validate configuration on startup (fail fast on bad config)
Compliance:
## P1: Important for Production
- After the gosec fix lands, verify CI runs make check green on main
### Security
- [ ] Implement blocked networks configuration (extend SSRF protection)
- [ ] Add rate limiting global concurrent fetches (prevent resource exhaustion)
P0, critical for 1.0 (from existing TODO.md):
### Image Processing
- [ ] Implement EXIF/metadata stripping (privacy)
- Add AVIF encoding support (currently returns error)
- Manual test pass for auth and encrypted URLs:
- visit /, see login form
- wrong key shows error; correct signing key shows generator form
- generated encrypted URL works
- expired URL (short TTL) returns 410
- logout redirects to login
- Implement cache size management and eviction (prevent disk fill)
- Validate configuration on startup (fail fast on bad config)
## P2: Nice to Have
P1, important for production:
### Security
- [ ] Implement referer blacklist
- [ ] Add rate limiting per-IP
- [ ] Add rate limiting per-origin
- Blocked networks configuration (extend SSRF protection)
- Rate limit global concurrent fetches (resource exhaustion)
- EXIF/metadata stripping (privacy)
### HTTP Response Handling
- [ ] Implement Last-Modified headers
- [ ] Implement Vary header for content negotiation
- [ ] Implement X-Request-ID propagation
P2, nice to have:
### Additional Endpoints
- [ ] Implement auto-format selection (format=auto based on Accept header)
- Referer blacklist; per-IP and per-origin rate limiting
- Last-Modified headers; Vary header; X-Request-ID propagation
- Auto-format selection (format=auto based on Accept header)
- All configuration options from README; env var overrides; YAML config
file support
- Sentry error reporting (optional); comprehensive request logging;
Prometheus metrics
- Integration tests for the image proxy flow; load tests for the
1-5k req/s target
- Docs: configuration options, API endpoints, deployment guide, example
nginx/caddy reverse proxy config
### Configuration
- [ ] Add all configuration options from README
- [ ] Implement environment variable overrides
- [ ] Implement YAML config file support
### Operational
- [ ] Implement Sentry error reporting (optional)
- [ ] Add comprehensive request logging
- [ ] Add performance metrics (Prometheus)
- [ ] Write integration tests for image proxy flow
- [ ] Write load tests to verify 1-5k req/s target
### Documentation
- [ ] Document configuration options
- [ ] Document API endpoints
- [ ] Document deployment guide
- [ ] Add example nginx/caddy reverse proxy config