remove rootless dockerfile, updatedate entrypoint, update docker compose

Removed the rootless dockerfile as upon further investigation into how a `rootless` container works, the entrypoint that has been written fully accomodates that

to reflect this the compose file has had the rootless config removed from it as it is no longer needed to test a seperate container image,

added a debug echo function `decho` to the entrypoint, when `DEBUG=true` it will print "[entrypoint] message content"

added a 10 second wait to the entrypoint to allow other services such as docker-in-docker and forgejo to finish launching before the runner is launched, this is bypassable by `SKIP_WAIT=true`

applied several modifications requested by viceice,
This commit is contained in:
Merith 2024-09-26 15:08:31 -07:00
parent 2c4a1d43be
commit ea96696f10
3 changed files with 78 additions and 71 deletions

View file

@ -1,6 +0,0 @@
FROM code.forgejo.org/forgejo/runner:3.4.1
USER 1000:1000
## In Theory these can be removed on next release of the runner image
COPY --chown=forgejo-runner:forgejo-runner --chmod=555 ./entrypoint.sh /entrypoint
ENTRYPOINT [ "/entrypoint" ]

View file

@ -4,25 +4,32 @@ set -e
run_command() { run_command() {
local cmd="$1" local cmd="$1"
echo "Running $cmd as $(id -u)" redacted_cmd=$(echo "$cmd" | sed -E 's/(--secret\s+|--token\s+)[^ ]+/--\1[REDACTED]/g')
decho "Running command: $redacted_cmd"
if [[ "$ISROOT" == true ]]; then if [[ "$ISROOT" == true ]]; then
decho "Running as forgejo-runner"
su -c "$cmd" forgejo-runner su -c "$cmd" forgejo-runner
else else
decho "Running as RUNNER_USER: ${RUNNER_USER}"
eval "$cmd" eval "$cmd"
fi fi
} }
# Initial setup decho() {
if [[ ! -d /data ]]; then if [[ "${DEBUG}" == "true" ]]; then
mkdir -p /data echo "[entrypoint] $@"
fi fi
}
# Initial setup
cd /data cd /data
RUNNER_USERID="${RUNNER_USERID:-1000}" decho "RUNNER_USER: ${RUNNER_USER}"
RUNNER_USER="${RUNNER_USER:-1000}"
# Check if the script is running as root # Check if the script is running as root
if [[ $(id -u) -eq 0 ]]; then if [[ $(id -u) -eq 0 ]]; then
ISROOT=true ISROOT=true
decho "Running as root"
fi fi
if [[ "$ISROOT" == true ]]; then if [[ "$ISROOT" == true ]]; then
@ -32,18 +39,22 @@ if [[ "$ISROOT" == true ]]; then
# Change the user ID if needed # Change the user ID if needed
CURRENT_UID=$(id -u forgejo-runner) CURRENT_UID=$(id -u forgejo-runner)
if [[ "${CURRENT_UID}" -ne "${RUNNER_USERID}" ]]; then decho "CURRENT_UID: ${CURRENT_UID}"
echo "Changing UID of forgejo-runner to ${RUNNER_USERID}" if [[ "${CURRENT_UID}" -ne "${RUNNER_USER}" ]]; then
sed -i "s/^forgejo-runner:[^:]*:[^:]*:/forgejo-runner:x:${RUNNER_USERID}:/" /etc/passwd echo "Changing UID of forgejo-runner to ${RUNNER_USER}"
sed -i "s/^forgejo-runner:[^:]*:[^:]*:/forgejo-runner:x:${RUNNER_USER}:/" /etc/passwd
fi fi
else else
echo "Creating user forgejo-runner with UID ${RUNNER_USERID}" echo "Creating user forgejo-runner with UID ${RUNNER_USER}"
adduser --uid "${RUNNER_USERID}" --home /home/forgejo-runner --disabled-password --gecos "" forgejo-runner adduser --uid "${RUNNER_USER}" --home /home/forgejo-runner --disabled-password --gecos "" forgejo-runner
fi fi
# Ensure /data is owned by the runner user # Ensure /data is owned by the runner user
if [[ $(stat -c "%u" /data) != "${RUNNER_USER}" ]]; then
decho "Changing ownership of /data to ${RUNNER_USER}"
chown -R forgejo-runner:forgejo-runner /data chown -R forgejo-runner:forgejo-runner /data
fi fi
fi
# Handle and alter the config file # Handle and alter the config file
if [[ -z "${CONFIG_FILE}" ]]; then if [[ -z "${CONFIG_FILE}" ]]; then
@ -51,9 +62,16 @@ if [[ -z "${CONFIG_FILE}" ]]; then
CONFIG_FILE="/data/config.yml" CONFIG_FILE="/data/config.yml"
fi fi
CONFIG_ARG="--config ${CONFIG_FILE}" CONFIG_ARG="--config ${CONFIG_FILE}"
decho "CONFIG: ${CONFIG_ARG}"
DOCKER_HOST=${DOCKER_HOST:-docker} DOCKER_HOST=${DOCKER_HOST:-docker}
DOCKER_TLS_CERTDIR=${DOCKER_TLS_CERTDIR:-"/certs/client"}
DOCKER_TLS_VERIFY=${DOCKER_TLS_VERIFY:-0}
decho "DOCKER_HOST: ${DOCKER_HOST}"
decho "DOCKER_TLS_CERTDIR: ${DOCKER_TLS_CERTDIR}"
decho "DOCKER_TLS_VERIFY: ${DOCKER_TLS_VERIFY}"
if [[ ! -f "${CONFIG_FILE}" ]]; then if [[ ! -f "${CONFIG_FILE}" ]]; then
echo "Creating ${CONFIG_FILE}"
run_command "forgejo-runner generate-config > ${CONFIG_FILE}" forgejo-runner run_command "forgejo-runner generate-config > ${CONFIG_FILE}" forgejo-runner
# Remove test environment variables if they exist in the config file # Remove test environment variables if they exist in the config file
@ -65,41 +83,53 @@ if [[ ! -f "${CONFIG_FILE}" ]]; then
sed -i "/^ network:/c\ network: host" ${CONFIG_FILE} sed -i "/^ network:/c\ network: host" ${CONFIG_FILE}
sed -i "/^ privileged:/c\ privileged: true" ${CONFIG_FILE} sed -i "/^ privileged:/c\ privileged: true" ${CONFIG_FILE}
if [[ "${DOCKER_TLS_VERIFY}" -ne 1 ]]; then if [[ "${DOCKER_TLS_VERIFY}" -ne 1 ]]; then
decho "Docker TLS diabled"
sed -i "/^ docker_host:/c\ docker_host: tcp://${DOCKER_HOST}:2375" ${CONFIG_FILE} sed -i "/^ docker_host:/c\ docker_host: tcp://${DOCKER_HOST}:2375" ${CONFIG_FILE}
else else
decho "Docker TLS enabled"
sed -i "/^ docker_host:/c\ docker_host: tcp://${DOCKER_HOST}:2376" ${CONFIG_FILE} sed -i "/^ docker_host:/c\ docker_host: tcp://${DOCKER_HOST}:2376" ${CONFIG_FILE}
sed -i "/^ valid_volumes:/c\ valid_volumes:\n - /certs/client" ${CONFIG_FILE} sed -i "/^ valid_volumes:/c\ valid_volumes:\n - ${DOCKER_TLS_CERTDIR}" ${CONFIG_FILE}
sed -i "/^ options:/c\ options: -v /certs/client:/certs/client" ${CONFIG_FILE} sed -i "/^ options:/c\ options: -v ${DOCKER_TLS_CERTDIR}:${DOCKER_TLS_CERTDIR}" ${CONFIG_FILE}
fi fi
fi fi
if [[ ! -z "${ENV_FILE}" ]]; then ENV_FILE=${ENV_FILE:-"/data/.env"}
decho "ENV_FILE: ${ENV_FILE}"
sed -i "/^ env_file:/c\ env_file: ${ENV_FILE}" ${CONFIG_FILE} sed -i "/^ env_file:/c\ env_file: ${ENV_FILE}" ${CONFIG_FILE}
else
ENV_FILE="/data/.env"
fi
if [[ ! -f "${ENV_FILE}" ]]; then if [[ ! -f "${ENV_FILE}" ]]; then
echo "Creating ${ENV_FILE}" echo "Creating ${ENV_FILE}"
touch ${ENV_FILE} touch ${ENV_FILE}
echo "DOCKER_HOST=${DOCKER_HOST}" >> ${ENV_FILE}
echo "DOCKER_TLS_VERIFY=${DOCKER_TLS_VERIFY}" >> ${ENV_FILE}
echo "DOCKER_TLS_CERTDIR=${DOCKER_TLS_CERTDIR}" >> ${ENV_FILE}
fi fi
EXTRA_ARGS="" EXTRA_ARGS=""
if [[ ! -z "${RUNNER_LABELS}" ]]; then if [[ ! -z "${RUNNER_LABELS}" ]]; then
EXTRA_ARGS="${EXTRA_ARGS} --labels ${RUNNER_LABELS}" EXTRA_ARGS="${EXTRA_ARGS} --labels ${RUNNER_LABELS}"
fi fi
decho "EXTRA_ARGS: ${EXTRA_ARGS}"
# Set the runner file # Set the runner file
if [[ -z "${RUNNER_FILE}" ]]; then if [[ -z "${RUNNER_FILE}" ]]; then
RUNNER_FILE=".runner.json" # use json so editors know how to highlight RUNNER_FILE="runner.json" # use json so editors know how to highlight
fi fi
decho "RUNNER_FILE: ${RUNNER_FILE}"
sed -i "/^ file:/c\ file: ${RUNNER_FILE}" ${CONFIG_FILE} sed -i "/^ file:/c\ file: ${RUNNER_FILE}" ${CONFIG_FILE}
if [[ "${SKIP_WAIT}" != "true" ]]; then
secho "Waiting 10s to allow other services to start up..."
sleep 10
fi
if [[ ! -s "${RUNNER_FILE}" ]]; then if [[ ! -s "${RUNNER_FILE}" ]]; then
touch ${RUNNER_FILE} touch ${RUNNER_FILE}
try=$((try + 1)) try=$((try + 1))
success=0 success=0
decho "try: ${try}, success: ${success}"
if [[ ! -z "${FORGEJO_SECRET}" ]]; then if [[ ! -z "${FORGEJO_SECRET}" ]]; then
EXTRA_ARGS="${EXTRA_ARGS} --secret ${FORGEJO_SECRET}" EXTRA_ARGS="${EXTRA_ARGS} --secret ${FORGEJO_SECRET}"
@ -112,6 +142,7 @@ if [[ ! -s "${RUNNER_FILE}" ]]; then
EXTRA_ARGS="${EXTRA_ARGS} --token ${RUNNER_TOKEN}" EXTRA_ARGS="${EXTRA_ARGS} --token ${RUNNER_TOKEN}"
echo "Registering with TOKEN" echo "Registering with TOKEN"
fi fi
decho "EXTRA_ARGS after secret/token: ${EXTRA_ARGS}"
# The point of this loop is to make it simple, when running both forgejo-runner and gitea in docker, # The point of this loop is to make it simple, when running both forgejo-runner and gitea in docker,
# for the forgejo-runner to wait a moment for gitea to become available before erroring out. Within # for the forgejo-runner to wait a moment for gitea to become available before erroring out. Within
@ -131,10 +162,12 @@ if [[ ! -s "${RUNNER_FILE}" ]]; then
echo "Waiting to retry ..." echo "Waiting to retry ..."
sleep 5 sleep 5
fi fi
decho "try: ${try}, success: ${success}"
done done
fi fi
# Prevent reading the token from the forgejo-runner process # Prevent reading the token from the forgejo-runner process
unset RUNNER_TOKEN unset RUNNER_TOKEN
unset FORGEJO_SECRET
run_command "forgejo-runner daemon ${CONFIG_ARG}" run_command "forgejo-runner daemon ${CONFIG_ARG}"

View file

@ -23,20 +23,19 @@ volumes:
services: services:
docker-in-docker: docker-in-docker:
image: code.forgejo.org/oci/docker:dind image: code.forgejo.org/oci/docker:dind
container_name: docker # needed for docker internal DNS resolution # container_name: docker # Must set container_name to docker for both internal DNS and TLS to work
hostname: docker # Must set hostname as TLS certificates are only valid for docker or localhost hostname: docker
privileged: true privileged: true
networks: networks:
- forgejo - forgejo
environment: environment:
DOCKER_TLS_CERTDIR: "" # set to "certs" to use the TLS certificates, also update existing runner configs to use port 2376 DOCKER_TLS_CERTDIR: "/certs" # set to "" to disable the use of TLS, also manually update existing runner configs to use port 2375
DOCKER_HOST: docker-in-docker
volumes: volumes:
- docker_certs:/certs - docker_certs:/certs
forgejo: forgejo:
image: codeberg.org/forgejo/forgejo:1.21 image: codeberg.org/forgejo/forgejo:1.21
container_name: forgejo hostname: forgejo
networks: networks:
- forgejo - forgejo
volumes: volumes:
@ -47,20 +46,21 @@ services:
bash -c ' bash -c '
/bin/s6-svscan /etc/s6 & /bin/s6-svscan /etc/s6 &
sleep 10 ; sleep 10 ;
su -c "forgejo admin user create --admin --username root --password examplepassword --email root@example.com" git ;
su -c "forgejo forgejo-cli actions register --secret {SHARED_SECRET}" git ; su -c "forgejo forgejo-cli actions register --secret {SHARED_SECRET}" git ;
sleep infinity sleep infinity
' '
# all values that have defaults listed are optional
# only FORGEJO_SECRET or RUNNER_TOKEN is required
# FORGEJO_URL is required if forgejo is in this compose file or docker network
forgejo-runner: forgejo-runner:
## TODO: Update image to the the release ## TODO: Update image to the the release
## made from this PR: https://code.forgejo.org/forgejo/runner/pulls/283 ## made from this PR: https://code.forgejo.org/forgejo/runner/pulls/283
# image: code.forgejo.org/forgejo/runner:3.4.1 # image: code.forgejo.org/forgejo/runner:3.4.1
build: build: ../../
context: ../../ # user: "1000" # set to run rootless, overrides RUNNER_USER and disables automatic file ownership
dockerfile: Dockerfile
container_name: forgejo-runner
# user: "1000" # set to run rootless, overrides RUNNER_USER
volumes: volumes:
- ./forgejo-runner:/data - ./forgejo-runner:/data
- docker_certs:/certs - docker_certs:/certs
@ -72,37 +72,17 @@ services:
environment: environment:
CONFIG_FILE: config.yml # defaults to /data/config.yml CONFIG_FILE: config.yml # defaults to /data/config.yml
FORGEJO_URL: ${FORGEJO_URL} # defaults to http://forgejo:3000 DOCKER_HOST: "docker" # defaults to docker
FORGEJO_SECRET: "{SHARED_SECRET}" # shared secret, must match Forgejo's DOCKER_TLS_CERTDIR: "/certs/client" # defaults to /certs/client
DOCKER_TLS_VERIFY: "1" # defaults to 0, set to 1 to enable TLS
RUNNER_FILE: runner.json # defaults to /data/runner.json FORGEJO_URL: ${FORGEJO_URL} # defaults to http://forgejo:3000
FORGEJO_SECRET: "{SHARED_SECRET}" # shared secret, must match Forgejo's, overrides RUNNER_TOKEN
RUNNER_FILE: .runner # defaults to /data/runner.json
RUNNER_NAME: forgejo-runner # defaults to forgejo-runner, used for registration RUNNER_NAME: forgejo-runner # defaults to forgejo-runner, used for registration
RUNNER_TOKEN: "${RUNNER_TOKEN}" RUNNER_TOKEN: "${RUNNER_TOKEN}"
RUNNER_USER: 1000 # defaults to 1000 RUNNER_USER: 1000 # defaults to 1000, allows for automatic file ownership
forgejo-runner-rootless: DEBUG: "true" # defaults to false, set to true to enable debug logging
## TODO: Update image to the the release SKIP_WAIT: "false" # defaults to false, set to true to skip the 10 second wait to allow for forgejo and docker-in-docker to start
## made from this PR: https://code.forgejo.org/forgejo/runner/pulls/283
# image: code.forgejo.org/forgejo/runner:3.4.1
build:
context: ../../
dockerfile: Dockerfile.rootless
container_name: forgejo-runner-rootless
volumes:
- ./forgejo-runner:/data
- docker_certs:/certs
networks:
- forgejo
depends_on:
- docker-in-docker
- forgejo
environment:
CONFIG_FILE: config-rootless.yml # defaults to /data/config.yml
FORGEJO_URL: ${FORGEJO_URL} # defaults to http://forgejo:3000
FORGEJO_SECRET: "{SHARED_SECRET}" # shared secret, must match Forgejo's
RUNNER_FILE: runner-rootless.json # defaults to /data/runner.json
RUNNER_NAME: forgejo-runner-rootless # defaults to forgejo-runner, used for registration
RUNNER_TOKEN: "${RUNNER_TOKEN}"