commit 5c42d9f22ade1eb31ba01fed2ed37225220df0c2 Author: Viorel Date: Fri Jan 23 21:02:54 2026 +0200 Initial commit First container (for gitea) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e934adf --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +cache/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57872e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*~ +bin/ +cache/ +repos/ diff --git a/Dockerfile.base.gnu b/Dockerfile.base.gnu new file mode 100644 index 0000000..561f9a8 --- /dev/null +++ b/Dockerfile.base.gnu @@ -0,0 +1,12 @@ +# syntax=docker/dockerfile:1 +# gentoo-base-gnu +FROM docker.io/gentoo/stage3:nomultilib AS builder + +WORKDIR /workdir +COPY --exclude=repos . . +COPY repos /var/db/repos +RUN echo 'FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox"' >> /etc/portage/make.conf +RUN --mount=type=cache,target=/workdir/cache,sharing=locked \ + /bin/bash src/bootstrap.sh -u -r /var/db/repos/ceamac -p ceamac:linux/arch/amd64/gnu -m make-docker.conf /mnt/gentoo -j12 + +CMD ["/bin/sh"] diff --git a/Dockerfile.gitea b/Dockerfile.gitea new file mode 100644 index 0000000..7b2e143 --- /dev/null +++ b/Dockerfile.gitea @@ -0,0 +1,19 @@ +# syntax=docker/dockerfile:1 +# gentoo-gitea +FROM gentoo-base-gnu AS builder + +WORKDIR /workdir +COPY --exclude=repos --exclude=bin . . +RUN --mount=type=cache,target=/workdir/cache,sharing=locked <<-EOF + echo 'acct-user/git gitea -git' >> /etc/portage/package.use/gitea + emerge -1v --quiet-build=y acct-user/git + /bin/bash src/setup-gitea.sh /mnt/gentoo -j8 +EOF + +FROM scratch +WORKDIR / +EXPOSE 3000 32799 +VOLUME ["/etc/gitea", "/var/lib/gitea"] +COPY --from=builder /mnt/gentoo / +USER git:git +CMD ["/usr/bin/gitea", "web"] diff --git a/Dockerfile.gnu b/Dockerfile.gnu new file mode 100644 index 0000000..132303a --- /dev/null +++ b/Dockerfile.gnu @@ -0,0 +1,10 @@ +# syntax=docker/dockerfile:1 +# gentoo-gnu +FROM gentoo-base-gnu AS builder +WORKDIR /workdir +RUN bin/gentoo-emerge -1c --with-bdeps=n + +FROM scratch +WORKDIR / +COPY --from=builder /mnt/gentoo / +CMD ["/bin/bash"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..704f455 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +.PHONY: clean all help + +all: + true + +clean: + find . -name \*~ -delete + +help: + @echo make clean diff --git a/README.md b/README.md new file mode 100644 index 0000000..31e305b --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# What this is + +Scripts and dockerfiles to build docker images based on Gentoo, but only with +what is needed at runtime, i.e., without the build time dependencies. + +I use some non-standard profiles that strip what is not needed. + +# How to use it + +First copy the portage trunk in repo/gentoo/ and the ceamac trunk - miniroot +branch in repo/ceamac/. + +Then run src/bootstrap.sh -h and see what it says. + +## Build locally (to test what goes in) + +For example: + +`src/bootstrap.sh -us -r repos/gentoo -r repos/ceamac output -a` + +- -u to build unstable. +- -s to add support for steve. +- -r repo-name-or-path to add whatever repos you need. gentoo is added by +default, even if not specified. +- output - this can be any name, it is the name of the output directory where +the --root will be. +- optional extra arguments to emerge, added after output. For example use -a +to see what would be merged before merging. + +Other useful options: +- -p profile to specify a profile (if not used, it will be asked) +- -m make.conf to specify an alternate make.conf to be copied in $ROOT +- -c yes to clear the output directory and rebuild all. Without -c, the build +will continue and reuse the last selected profile. +- -e used together with -c to simply clean all and not build anything. + +After finishing, if all goes well, you should have a ready to use $ROOT in +output as well as some useful scripts in bin, like bin/output-emerge to emerge +more packages in output, bin/output-eselect to run eselect in $ROOT and +bin/output-bwrap to start a bubblewrap shell inside $ROOT and test stuff. + +This bootstrap script will create only a base root (@system set, without + anything else). + +To continue run scripts from src or manually emerge stuff. + +For example `src/setup-gitea.sh output [-a]` to install gitea inside output. + +Important note: host portage should have the same trunk as $ROOT, because +that's where BDEPENDs go. In case of mismatches things can go wrong. + +## Build with docker + +Edit the dockerfiles and run docker build. I did not add arguments. + +Unfortunately docker build does not support steve. + +For example: + +Build the base image with +`docker buildx build -t gentoo-base-gnu -f Dockerfile.base.gnu .` + +The build the gitea image with +`docker buildx build -t gentoo-gitea -f Dockerfile.gitea .` + +It uses the base image. And the dockerfile copies the repos from repos/. diff --git a/compose-gitea.yaml b/compose-gitea.yaml new file mode 100644 index 0000000..affd4ca --- /dev/null +++ b/compose-gitea.yaml @@ -0,0 +1,24 @@ +services: + gitea: + image: gentoo-gitea + restart: always + #user: 196:196 + userns: nomap + ports: + - "127.0.0.1:3000:3000/tcp" + - "127.0.0.1:32799:32799/tcp" + volumes: + - type: bind + source: /etc/gitea + target: /etc/gitea + read_only: false + - type: bind + source: /var/lib/gitea + target: /var/lib/gitea + read_only: false + + #command: /bin/bash + #stdin_open: true + #tty: true + + #command: /usr/bin/gitea web diff --git a/make-docker.conf b/make-docker.conf new file mode 100644 index 0000000..ed9a1e6 --- /dev/null +++ b/make-docker.conf @@ -0,0 +1,9 @@ +COMMON_FLAGS="-O2 -pipe" +CFLAGS="${COMMON_FLAGS}" +CXXFLAGS="${COMMON_FLAGS}" +FCFLAGS="${COMMON_FLAGS}" +FFLAGS="${COMMON_FLAGS}" + +LC_MESSAGES=C.utf8 + +FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox" diff --git a/make.conf b/make.conf new file mode 100644 index 0000000..3f90fd7 --- /dev/null +++ b/make.conf @@ -0,0 +1,8 @@ +COMMON_FLAGS="-O2 -pipe" +CFLAGS="${COMMON_FLAGS}" +CXXFLAGS="${COMMON_FLAGS}" +FCFLAGS="${COMMON_FLAGS}" +FFLAGS="${COMMON_FLAGS}" + +LC_MESSAGES=C.utf8 + diff --git a/src/bootstrap.sh b/src/bootstrap.sh new file mode 100755 index 0000000..134cb10 --- /dev/null +++ b/src/bootstrap.sh @@ -0,0 +1,180 @@ +#! /bin/bash + +set -euo pipefail + +die() { + echo "$@" >&2 + exit 1 +} + +declare -A repos +addrepo() { + if [[ -d $1 ]]; then + [[ -e "${1}"/profiles/repo_name ]] || die "Not a valid repo: ${1}" + repos+=( [$(cat "${1}"/profiles/repo_name)]="$(realpath "${1}")" ) + else + repos+=( ["${1}"]="$(portageq get_repo_path / "${1}")" ) + fi +} + +makeconf=make.conf +unstable= +clear= +done= +profile= +steve= +OPTIND=1 +while getopts :ehusc:r:p:m: OPT; do + case $OPT in + h) + echo Usage: "$0" '[-c] [-r repo] [-r repo...] [dirname [emerge-args...]]' + echo ' -c yes: clear dirname first' + echo ' -e: exit after cleaning' + echo ' -u: build unstable' + echo ' -s: use steve' + echo ' -r repo: add repo to list; can be a repo name or a path' + echo ' -p profile: profile tro eselect (default: read from stdin)' + echo ' -m make.conf: path to make.conf (default: make.conf in current directory)' + exit 0 + ;; + + c) + if [[ ${OPTARG} = yes ]]; then + clear=1 + else + die "-c requires confirmation" + fi;; + e) done=1;; + u) unstable='~';; + s) steve=-j;; + r) addrepo "${OPTARG}";; + p) profile="${OPTARG}";; + m) makeconf="${OPTARG}";; + *) + echo "Unknown argument -$OPTARG; try $0 -h" 2> /dev/null + exit 1;; + esac +done + +[[ -v repos[gentoo] ]] || addrepo gentoo + +imageroot=${!OPTIND:-base} +imagename="$(basename "${imageroot}")" + +shift "${OPTIND}" || : + +if [[ -n $clear ]]; then + rm -rf "${imageroot}" + rm -f bin/"${imagename}"-{emerge,eselect,bwrap} +fi +if [[ -n ${done} ]]; then + [[ -z ${clear} ]] && die 'Warning: -e (exit after clean) used without -c (clean); exiting' + exit +fi + +mkdir -p "${imageroot}"/etc/portage/repos.conf +mkdir -p "${imageroot}"/var/db/repos +mkdir -p "${imageroot}"/var/tmp +[[ -e ${makeconf} ]] && cp "${makeconf}" "${imageroot}"/etc/portage/make.conf + +# addrepoconfs [root] +addrepoconfs() { + repoconf="${imageroot}"/etc/portage/repos.conf/gentoo.conf + cat <<-EOF > "${repoconf}" + [DEFAULT] + main-repo = gentoo + sync-allow-hardlinks = no + EOF + for i in "${!repos[@]}"; do + cat <<-EOF >> "${repoconf}" + + [$i] + location = ${1}/var/db/repos/$i + EOF + [[ $i = gentoo ]] || echo "priority = 100" >> "${repoconf}" + + if [[ -z $1 ]]; then + ln -s "${repos[$i]}" "${imageroot}"/var/db/repos/"$i" || [[ -z $clear ]] + fi + done +} +addrepoconfs '' + +unset PORTDIR +unset PORTDIR_OVERLAY +ROOT="$(realpath "${imageroot}")" +export ROOT +eselect profile list +if [[ ! -L "${imageroot}"/etc/portage/make.profile ]]; then + if [[ -z ${profile} ]]; then + read -r -p "select " profile + fi + [[ -z ${profile} ]] && exit 1 + eselect profile set "${profile}" +fi +export PORTAGE_CONFIGROOT="${ROOT}" + +addrepoconfs "${ROOT}" + +abi="$(portageq envvar ABI)" +libdir=LIBDIR_${abi} +libdir=$(portageq envvar "${libdir}") +libdir=${libdir:=lib} + +mkdir -p "${imageroot}"/usr/lib "${imageroot}"/usr/bin "${imageroot}"/usr/"${libdir}" +ln -s usr/lib "${imageroot}"/lib || [[ -z $clear ]] +ln -s usr/bin "${imageroot}"/bin || [[ -z $clear ]] +ln -s usr/bin "${imageroot}"/sbin || [[ -z $clear ]] +ln -s bin "${imageroot}"/usr/sbin || [[ -z $clear ]] +ln -sf usr/"${libdir}" "${imageroot}/${libdir}" + +[[ -n ${unstable} ]] && echo "ACCEPT_KEYWORDS=~${abi}" >> "${imageroot}"/etc/portage/make.conf +[[ -n ${steve} ]] && cat <<-EOF >> "${imageroot}"/etc/portage/make.conf + MAKEFLAGS="--jobserver-auth=fifo:/dev/steve" + MAKEOPTS="-j" + NINJAOPTS="" +EOF +# Use '' to prevent expanding here +# shellcheck disable=SC2016 +echo 'FEATURES="${FEATURES} buildpkg"' >> "${imageroot}"/etc/portage/make.conf + +mkdir -p cache +elibc=$(portageq envvar ELIBC) +PKGDIR=cache/packages${unstable:--}${abi}-${elibc} +mkdir -p "${PKGDIR}" +PKGDIR="$(realpath "${PKGDIR}")" +export PKGDIR + +PORTAGE_TMPDIR="${ROOT}"/var/tmp +export PORTAGE_TMPDIR + +mkdir -p bin +cat <<-EOF > bin/"${imagename}"-emerge +#! /bin/bash +ROOT="${ROOT}" +PORTAGE_CONFIGROOT="${ROOT}" +PORTAGE_TMPDIR="${PORTAGE_TMPDIR}" +PKGDIR="${PKGDIR}" + +export ROOT PORTAGE_CONFIGROOT PORTAGE_TMPDIR PKGDIR +exec emerge "\$@" +EOF +chmod +x bin/"${imagename}"-emerge + +cat <<-EOF > bin/"${imagename}"-eselect +#! /bin/bash +ROOT="${ROOT}" + +export ROOT +exec eselect "\$@" +EOF +chmod +x bin/"${imagename}"-eselect + +cat < bin/"${imagename}"-bwrap +#! /bin/bash +exec bwrap --bind "${ROOT}" / --proc /proc --dev /dev --perms 01777 --tmpfs /dev/shm --perms 01777 --tmpfs /tmp \\ + --clearenv --unshare-ipc --unshare-uts --unshare-pid --unshare-cgroup --die-with-parent --as-pid-1 "\${@:-/bin/sh}" +EOF +chmod +x bin/"${imagename}"-bwrap + +emerge -1vuDUk ${steve} "$@" @system diff --git a/src/setup-gitea.sh b/src/setup-gitea.sh new file mode 100755 index 0000000..d97c72a --- /dev/null +++ b/src/setup-gitea.sh @@ -0,0 +1,43 @@ +#! /bin/bash +# does not install properly on busybox profile. + +set -euo pipefail + +imagedir="${1}" +imagename="$(basename "${imagedir}")" +shift + +usename="${imagedir}"/etc/portage/package.use +[[ -d ${usename} ]] && usename="${usename}"/php.conf + +cat <<-EOF >> "${usename}" +*/* cxx +*/* -pam + +acct-user/git -git gitea +www-apps/gitea sqlite +sys-apps/util-linux -su +dev-vcs/git -perl +sys-apps/shadow su +EOF + +bin/"${imagename}"-emerge -vk "$@" gitea dev-vcs/git-lfs +bin/"${imagename}"-emerge -1vuDUk "$@" @world +bin/"${imagename}"-emerge -1c --with-bdeps=n "$@" + +#cat <<-EOF > "${imagedir}"/init +##! /bin/sh +#systemd-tmpfiles --create +#exec su git -c /usr/bin/gitea web +#EOF +#chmod +x "${imagedir}"/init + +#mkdir -p "${imagedir}"/etc/giteac/custom/conf/ +#cat <<-EOF > "${imagedir}"/etc/giteac/custom/conf/app.ini +#[service] +#DISABLE_REGISTRATION = true +# +#[openid] +#ENABLE_OPENID_SIGNIN = false +#ENABLE_OPENID_SIGNUP = false +#EOF