Refactor Dagger go_build() helper and standardize Alpine 3.23
All checks were successful
Build Container / detect (push) Successful in 3s
Build Container / build-dagger (miniflux) (push) Successful in 10m2s
Build Container / build-dagger (forgejo-runner) (push) Successful in 10m2s

Extend go_build() with buildmode and extra_env params, migrate miniflux
and forgejo-runner to use it, and bump all Alpine bases from 3.22 to 3.23.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erich Blume 2026-04-16 10:10:46 -07:00
commit 352b95c141
4 changed files with 33 additions and 60 deletions

View file

@ -5,11 +5,11 @@ Source cloned from forge mirror.
"""
import dagger
from dagger import dag
from blumeops.containers import (
alpine_runtime,
clone_from_forge,
go_build,
oci_labels,
)
@ -20,29 +20,16 @@ async def build(src: dagger.Directory) -> dagger.Container:
source = clone_from_forge("forgejo-runner", f"v{VERSION}")
# Stage 1: Build Go binary (static, CGO enabled for SQLite)
backend = go_build(
source,
"/forgejo-runner",
tags="netgo osusergo",
ldflags=(
'-extldflags "-static" -s -w'
f' -X "code.forgejo.org/forgejo/runner/v12/internal/pkg/ver.version=v{VERSION}"'
)
backend = (
dag.container()
.from_("golang:alpine3.22")
.with_exec(["apk", "add", "--no-cache", "build-base", "git"])
.with_directory("/app", source)
.with_workdir("/app")
.with_env_variable("CGO_ENABLED", "1")
.with_env_variable("CGO_CFLAGS", "-DSQLITE_MAX_VARIABLE_NUMBER=32766")
.with_exec(
[
"go",
"build",
"-tags=netgo osusergo",
f"-ldflags={ldflags}",
"-o",
"/forgejo-runner",
".",
]
)
),
cgo_enabled=True,
extra_env={"CGO_CFLAGS": "-DSQLITE_MAX_VARIABLE_NUMBER=32766"},
)
# Stage 2: Runtime

View file

@ -5,11 +5,11 @@ Source cloned from forge mirror.
"""
import dagger
from dagger import dag
from blumeops.containers import (
alpine_runtime,
clone_from_forge,
go_build,
oci_labels,
)
@ -20,25 +20,12 @@ async def build(src: dagger.Directory) -> dagger.Container:
source = clone_from_forge("miniflux", VERSION)
# Stage 1: Build Go backend (PIE mode, matching upstream Makefile)
ldflags = f"-s -w -X 'miniflux.app/v2/internal/version.Version={VERSION}'"
backend = (
dag.container()
.from_("golang:alpine3.22")
.with_exec(["apk", "add", "--no-cache", "build-base", "git"])
.with_directory("/app", source)
.with_workdir("/app")
.with_env_variable("CGO_ENABLED", "1")
.with_exec(
[
"go",
"build",
"-buildmode=pie",
f"-ldflags={ldflags}",
"-o",
backend = go_build(
source,
"/miniflux",
".",
]
)
buildmode="pie",
ldflags=f"-s -w -X 'miniflux.app/v2/internal/version.Version={VERSION}'",
cgo_enabled=True,
)
# Stage 2: Runtime (uses Alpine's built-in nobody:65534)

View file

@ -0,0 +1 @@
Refactored Dagger container pipelines: extended `go_build()` helper with `buildmode` and `extra_env` params, migrated miniflux and forgejo-runner to use it, and standardized all Alpine bases from 3.22 to 3.23.

View file

@ -70,33 +70,31 @@ def go_build(
cmd_path: str = ".",
tags: str = "netgo",
ldflags: str = "-w -s",
buildmode: str | None = None,
cgo_enabled: bool = False,
extra_apk: list[str] | None = None,
extra_env: dict[str, str] | None = None,
) -> dagger.Container:
"""Go build stage on golang:alpine3.22.
"""Go build stage on golang:alpine3.23.
Returns a container with the built binary at `output`.
"""
apk_packages = ["build-base", "git"] + (extra_apk or [])
return (
ctr = (
dag.container()
.from_("golang:alpine3.22")
.from_("golang:alpine3.23")
.with_exec(["apk", "add", "--no-cache", *apk_packages])
.with_directory("/app", source)
.with_workdir("/app")
.with_env_variable("CGO_ENABLED", "1" if cgo_enabled else "0")
.with_exec(
[
"go",
"build",
f"-tags={tags}",
f"-ldflags={ldflags}",
"-o",
output,
cmd_path,
]
)
)
for key, val in (extra_env or {}).items():
ctr = ctr.with_env_variable(key, val)
build_cmd = ["go", "build"]
if buildmode:
build_cmd.append(f"-buildmode={buildmode}")
build_cmd += [f"-tags={tags}", f"-ldflags={ldflags}", "-o", output, cmd_path]
return ctr.with_exec(build_cmd)
def node_build(
@ -133,7 +131,7 @@ def alpine_runtime(
username: str = "app",
create_user: bool = True,
) -> dagger.Container:
"""Standard Alpine 3.22 runtime base.
"""Standard Alpine 3.23 runtime base.
When create_user is True (default), creates a non-root user with the given
uid/gid/username. Set create_user=False to use an existing user (e.g.
@ -147,7 +145,7 @@ def alpine_runtime(
setup_cmds.append(f"addgroup -g {gid} {username}")
setup_cmds.append(f"adduser -u {uid} -G {username} -D {username}")
ctr = dag.container().from_("alpine:3.22")
ctr = dag.container().from_("alpine:3.23")
if setup_cmds:
ctr = ctr.with_exec(["sh", "-c", " && ".join(setup_cmds)])
return ctr