Files
forge/Dockerfile.rootless
zeekayandHanzo Dev 27cde39e36 Name every remaining identifier, path and default for this product
Storage buckets, indexer names, the bleve analyzer, the lock prefix, SSH host
keys, the markdown front-matter key, the container data paths, the RPM repo id
and the API security scheme all read as this product now, and app.example.ini
matches the code again. The upstream maintainer list and the changelog
generator config went with the release history they belonged to, and the
citation comments state the fact rather than link the issue.

Three inert rules turn out to have been inert because they named a module path
this tree does not use: gci grouped no first-party imports under prefix(), and
depguard let models/migrations import models and modules/structs. They now name
github.com/hanzoai/git. The config example also documented .gitea/workflows
while the code has read .hanzo/workflows for some time.

The authorized_keys marker follows the delegate-hook precedent: the new name is
written and the old one is still recognised, because a marker we do not know is
copied through as a hand-added key and leaves a revoked key authorized. The
stored user_setting key keeps its value; only a migration may change that.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 19:14:35 -07:00

117 lines
4.1 KiB
Docker

# syntax=docker/dockerfile:1
# Build frontend on the native platform to avoid QEMU-related issues with nodejs ecosystem
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26.5-alpine3.24 AS frontend-build
# go.mod pins the toolchain. The golang base image sets GOTOOLCHAIN=local,
# which turns a `go` directive newer than the image into a hard build
# failure instead of a download.
ENV GOTOOLCHAIN=auto
RUN apk --no-cache add build-base git nodejs pnpm
WORKDIR /src
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
COPY --exclude=.git/ . .
RUN make frontend
# Build backend for each target platform
FROM docker.io/library/golang:1.26.5-alpine3.24 AS build-env
# go.mod pins the toolchain. The golang base image sets GOTOOLCHAIN=local,
# which turns a `go` directive newer than the image into a hard build
# failure instead of a download.
ENV GOTOOLCHAIN=auto
ARG GIT_VERSION
ARG TAGS=""
ENV TAGS="bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS
# Build deps
RUN apk --no-cache add \
build-base \
git
WORKDIR ${GOPATH}/src/hanzo-git
# Sources private hanzoai modules (xorm, builder): mark them private
# (direct VCS fetch, no proxy/sumdb) and, when gh_token is mounted, rewrite
# github.com to an authenticated fetch so `go mod download` can read them. No-op
# without the token, so public-only builds still work. gh_token is the secret id
# the canonical hanzoai/ci reusable mounts (was GIT_AUTH_TOKEN, which ci never set).
ENV GOPRIVATE=github.com/hanzoai/*
COPY go.mod go.sum ./
# The root module replaces github.com/hanzoai/git/modules/actions/runner with
# ./modules/actions/runner, so `go mod download` reads that directory's go.mod
# and fails without it. It is copied here, ahead of the source tree, to keep
# the dependency layer cached independently of every other file.
COPY modules/actions/runner/go.mod modules/actions/runner/
RUN --mount=type=secret,id=gh_token \
if [ -s /run/secrets/gh_token ]; then \
export GIT_CONFIG_COUNT=1 \
GIT_CONFIG_KEY_0="url.https://x-access-token:$(cat /run/secrets/gh_token)@github.com/.insteadOf" \
GIT_CONFIG_VALUE_0="https://github.com/"; \
fi; \
go mod download
# See the comments in Dockerfile
COPY --exclude=.git/ . .
COPY --from=frontend-build /src/public/assets public/assets
# Build gitd. Same as Dockerfile: the Makefile reads the VERSION file when it
# exists and falls back to `git describe` when it does not, so a build context
# without .git supplies the version through the ARG instead of the repository.
RUN --mount=type=cache,target="/root/.cache/go-build" \
if [ -n "${GIT_VERSION}" ]; then echo "${GIT_VERSION}" > VERSION; \
elif [ ! -d .git ] && [ ! -f VERSION ]; then echo "0.0.0+unknown" > VERSION; fi && \
make backend
COPY docker/rootless /tmp/local
# Set permissions for builds that made under windows which strips the executable bit from file
RUN chmod 755 /tmp/local/usr/local/bin/* \
/go/src/hanzo-git/gitd
FROM docker.io/library/alpine:3.24 AS hanzo-git-rootless
EXPOSE 2222 3000
RUN apk --no-cache add \
bash \
ca-certificates \
dumb-init \
gettext \
git \
curl \
gnupg \
openssh-keygen
RUN addgroup \
-S -g 1000 \
git && \
adduser \
-S -H -D \
-h /var/lib/forge/git \
-s /bin/bash \
-u 1000 \
-G git \
git
RUN mkdir -p /var/lib/forge /etc/forge
RUN chown git:git /var/lib/forge /etc/forge
COPY --from=build-env /tmp/local /
COPY --from=build-env --chown=root:root /go/src/hanzo-git/gitd /app/git/gitd
# git:git
USER 1000:1000
ENV GIT_WORK_DIR=/var/lib/forge
ENV GIT_CUSTOM=/var/lib/forge/custom
ENV GIT_TEMP=/tmp/forge
ENV TMPDIR=/tmp/forge
# TODO add to docs the ability to define the ini to load (useful to test and revert a config)
ENV GIT_APP_INI=/etc/forge/app.ini
ENV HOME="/var/lib/forge/git"
VOLUME ["/var/lib/forge", "/etc/forge"]
WORKDIR /var/lib/forge
# HINT: HEALTH-CHECK-ENDPOINT: don't use HEALTHCHECK, search this hint keyword for more information
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/usr/local/bin/docker-entrypoint.sh"]
CMD []