Skip to content

Commit 6d6185f

Browse files
committed
♻️ refactor: Simplify Dockerfile and Makefile, improve CLI
Refactored Dockerfile for clarity and efficiency, using multi-stage builds and Alpine base image. Updated Makefile for streamlined commands. Improved CLI by deferring `Gosched` and simplifying proxy header handling.
1 parent 5c601cb commit 6d6185f

File tree

8 files changed

+33
-112
lines changed

8 files changed

+33
-112
lines changed

.devcontainer/devcontainer.json

Lines changed: 0 additions & 18 deletions
This file was deleted.

Dockerfile

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,36 @@
11
# syntax=docker/dockerfile:1
22

3-
# -✂- this stage is used to develop and build the application locally -------------------------------------------------
4-
FROM docker.io/library/golang:1.24-bookworm AS develop
5-
6-
# use the /var/tmp/go as the GOPATH to reuse the modules cache
7-
ENV GOPATH="/var/tmp/go"
8-
9-
RUN set -x \
10-
# renovate: source=github-releases name=golangci/golangci-lint
11-
&& GOLANGCI_LINT_VERSION="2.3.0" \
12-
&& wget -O- -nv "https://cdn.jsdelivr.net/gh/golangci/golangci-lint@v${GOLANGCI_LINT_VERSION}/install.sh" \
13-
| sh -s -- -b /bin "v${GOLANGCI_LINT_VERSION}"
14-
15-
RUN set -x \
16-
# customize the shell prompt (for the bash)
17-
&& echo "PS1='\[\033[1;36m\][go] \[\033[1;34m\]\w\[\033[0;35m\] \[\033[1;36m\]# \[\033[0m\]'" >> /etc/bash.bashrc
18-
19-
WORKDIR /src
20-
21-
# burn the modules cache
22-
RUN \
23-
--mount=type=bind,source=go.mod,target=/src/go.mod \
24-
--mount=type=bind,source=go.sum,target=/src/go.sum \
25-
go mod download -x \
26-
&& find "${GOPATH}" -type d -exec chmod 0777 {} \; \
27-
&& find "${GOPATH}" -type f -exec chmod 0666 {} \;
28-
293
# -✂- this stage is used to compile the application -------------------------------------------------------------------
30-
FROM develop AS compile
4+
FROM docker.io/library/golang:1.24-alpine AS compile
315

326
# can be passed with any prefix (like `v1.2.3@GITHASH`), e.g.: `docker build --build-arg "APP_VERSION=v1.2.3" .`
337
ARG APP_VERSION="undefined@docker"
348

359
# copy the source code
3610
COPY . /src
3711

12+
WORKDIR /src
13+
3814
RUN set -x \
39-
&& go generate ./... \
40-
&& CGO_ENABLED=0 LDFLAGS="-s -w -X gh.tarampamp.am/error-pages/internal/appmeta.version=${APP_VERSION}" \
41-
go build -trimpath -ldflags "${LDFLAGS}" -o /tmp/error-pages ./cmd/error-pages/ \
15+
&& go generate -skip readme ./... \
16+
&& CGO_ENABLED=0 go build \
17+
-trimpath \
18+
-ldflags "-s -w -X gh.tarampamp.am/error-pages/internal/appmeta.version=${APP_VERSION}" \
19+
-o /tmp/error-pages \
20+
./cmd/error-pages/ \
4221
&& /tmp/error-pages --version \
4322
&& /tmp/error-pages -h
4423

45-
# -✂- this stage is used to prepare the runtime fs --------------------------------------------------------------------
46-
FROM docker.io/library/alpine:3.22 AS rootfs
47-
4824
WORKDIR /tmp/rootfs
4925

5026
# prepare rootfs for runtime
5127
RUN set -x \
5228
&& mkdir -p ./etc/ssl/certs ./bin \
5329
&& echo 'appuser:x:10001:10001::/nonexistent:/sbin/nologin' > ./etc/passwd \
5430
&& echo 'appuser:x:10001:' > ./etc/group \
55-
&& cp /etc/ssl/certs/ca-certificates.crt ./etc/ssl/certs/
56-
57-
# take the binary from the compile stage
58-
COPY --from=compile /tmp/error-pages ./bin/error-pages
31+
&& cp /etc/ssl/certs/ca-certificates.crt ./etc/ssl/certs/ \
32+
&& mv /tmp/error-pages ./bin/error-pages \
33+
&& chmod 755 ./bin/error-pages
5934

6035
WORKDIR /tmp/rootfs/opt
6136

@@ -81,7 +56,7 @@ LABEL \
8156
org.opencontainers.image.licenses="MIT"
8257

8358
# import from builder
84-
COPY --from=rootfs /tmp/rootfs /
59+
COPY --from=compile /tmp/rootfs /
8560

8661
# use an unprivileged user
8762
USER 10001:10001
@@ -95,7 +70,7 @@ ENV LOG_LEVEL="warn" \
9570
LOG_FORMAT="json"
9671

9772
# docs: https://docs.docker.com/reference/dockerfile/#healthcheck
98-
HEALTHCHECK --interval=10s --start-interval=1s --start-period=5s --timeout=2s CMD ["/bin/error-pages", "healthcheck"]
73+
HEALTHCHECK --interval=10s --start-interval=1s --start-period=2s --timeout=1s CMD ["/bin/error-pages", "healthcheck"]
9974

10075
ENTRYPOINT ["/bin/error-pages"]
10176

Makefile

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,18 @@
11
#!/usr/bin/make
22

3-
DC_RUN_ARGS = --rm --user "$(shell id -u):$(shell id -g)"
3+
.DEFAULT_GOAL : build
44

5-
.DEFAULT_GOAL : help
6-
7-
help: ## Show this help
8-
@printf "\033[33m%s:\033[0m\n" 'Available commands'
9-
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[32m%-11s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
10-
11-
.PHONY: up
12-
up: ## Start the application in watch mode
13-
docker compose kill web --remove-orphans 2>/dev/null || true
14-
docker compose up --detach --wait web
15-
$$SHELL -c "\
16-
trap 'docker compose down --remove-orphans --timeout 30' EXIT; \
17-
docker compose watch --no-up web \
18-
"
19-
20-
.PHONY: down
21-
down: ## Stop the application
22-
docker compose down --remove-orphans
5+
gen: ## Generate code
6+
go generate ./...
237

24-
.PHONY: shell
25-
shell: ## Start shell into development environment
26-
docker compose run -ti $(DC_RUN_ARGS) develop bash
8+
build: gen ## Build the application
9+
CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o ./error-pages ./cmd/error-pages/
2710

28-
.PHONY: test
2911
test: ## Run tests
30-
docker compose run $(DC_RUN_ARGS) develop gotestsum --format pkgname -- -race -timeout 2m ./...
12+
go test -race ./...
3113

32-
.PHONY: lint
33-
lint: ## Run linters
34-
docker compose run $(DC_RUN_ARGS) develop golangci-lint run
14+
lint: ## Run linters (requires https://github.com/golangci/golangci-lint installed)
15+
golangci-lint run
3516

36-
.PHONY: gen
37-
gen: ## Generate code
38-
docker compose run $(DC_RUN_ARGS) develop go generate ./...
17+
up: build ## Start the application at http://localhost:8080
18+
./error-pages --log-level debug serve --show-details --proxy-headers=X-Foo,Bar,Baz_blah

cmd/error-pages/main.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@ import (
66
"os"
77
"os/signal"
88
"path/filepath"
9+
"runtime"
910
"syscall"
1011

1112
"go.uber.org/automaxprocs/maxprocs"
1213

1314
"gh.tarampamp.am/error-pages/internal/cli"
1415
)
1516

17+
// set GOMAXPROCS to match Linux container CPU quota.
18+
var _, _ = maxprocs.Set(maxprocs.Min(1), maxprocs.Logger(func(string, ...any) {}))
19+
1620
// main CLI application entrypoint.
1721
func main() {
18-
// automatically set GOMAXPROCS to match Linux container CPU quota
19-
_, _ = maxprocs.Set(maxprocs.Min(1), maxprocs.Logger(func(_ string, _ ...any) {}))
20-
2122
if err := run(); err != nil {
2223
_, _ = fmt.Fprintln(os.Stderr, err.Error())
2324

@@ -27,9 +28,11 @@ func main() {
2728

2829
// run this CLI application.
2930
func run() error {
31+
defer runtime.Gosched() // increase the chance of running deferred functions before exiting
32+
3033
// create a context that is canceled when the user interrupts the program
3134
var ctx, cancel = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
3235
defer cancel()
3336

34-
return (cli.NewApp(filepath.Base(os.Args[0]))).Run(ctx, os.Args)
37+
return cli.NewApp(filepath.Base(os.Args[0])).Run(ctx, os.Args)
3538
}

compose.yml

Lines changed: 0 additions & 19 deletions
This file was deleted.

internal/cli/app.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
"gh.tarampamp.am/error-pages/internal/logger"
1717
)
1818

19-
//go:generate go run app_generate.go
19+
//go:generate go run update_readme.go
2020

2121
// NewApp creates a new console application.
2222
func NewApp(appName string) *cli.Command {

internal/cli/serve/command.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ func NewCommand(log *logger.Logger) *cli.Command { //nolint:funlen,gocognit,gocy
220220
m[http.CanonicalHeaderKey(strings.TrimSpace(header))] = struct{}{}
221221
}
222222

223-
clear(cfg.ProxyHeaders) // clear the list before adding new headers
223+
cfg.ProxyHeaders = make([]string, 0, len(m)) // clear the list before adding new headers
224224

225225
for header := range m {
226226
cfg.ProxyHeaders = append(cfg.ProxyHeaders, header)
File renamed without changes.

0 commit comments

Comments
 (0)