From ea96696f10c9c700bb14b093821917ba4dd6a2e6 Mon Sep 17 00:00:00 2001 From: Merith Date: Thu, 26 Sep 2024 15:08:31 -0700 Subject: [PATCH] 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, --- Dockerfile.rootless | 6 -- entrypoint.sh | 73 ++++++++++++++----- .../compose-forgejo-and-runner.yml | 70 +++++++----------- 3 files changed, 78 insertions(+), 71 deletions(-) delete mode 100644 Dockerfile.rootless diff --git a/Dockerfile.rootless b/Dockerfile.rootless deleted file mode 100644 index 882be5c..0000000 --- a/Dockerfile.rootless +++ /dev/null @@ -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" ] \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index d1376c0..ed17b19 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -4,25 +4,32 @@ set -e run_command() { 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 + decho "Running as forgejo-runner" su -c "$cmd" forgejo-runner else + decho "Running as RUNNER_USER: ${RUNNER_USER}" eval "$cmd" fi } +decho() { + if [[ "${DEBUG}" == "true" ]]; then + echo "[entrypoint] $@" + fi +} + # Initial setup -if [[ ! -d /data ]]; then - mkdir -p /data -fi 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 if [[ $(id -u) -eq 0 ]]; then ISROOT=true + decho "Running as root" fi if [[ "$ISROOT" == true ]]; then @@ -32,17 +39,21 @@ if [[ "$ISROOT" == true ]]; then # Change the user ID if needed CURRENT_UID=$(id -u forgejo-runner) - if [[ "${CURRENT_UID}" -ne "${RUNNER_USERID}" ]]; then - echo "Changing UID of forgejo-runner to ${RUNNER_USERID}" - sed -i "s/^forgejo-runner:[^:]*:[^:]*:/forgejo-runner:x:${RUNNER_USERID}:/" /etc/passwd + decho "CURRENT_UID: ${CURRENT_UID}" + if [[ "${CURRENT_UID}" -ne "${RUNNER_USER}" ]]; then + echo "Changing UID of forgejo-runner to ${RUNNER_USER}" + sed -i "s/^forgejo-runner:[^:]*:[^:]*:/forgejo-runner:x:${RUNNER_USER}:/" /etc/passwd fi else - echo "Creating user forgejo-runner with UID ${RUNNER_USERID}" - adduser --uid "${RUNNER_USERID}" --home /home/forgejo-runner --disabled-password --gecos "" forgejo-runner + echo "Creating user forgejo-runner with UID ${RUNNER_USER}" + adduser --uid "${RUNNER_USER}" --home /home/forgejo-runner --disabled-password --gecos "" forgejo-runner fi # Ensure /data is owned by the runner user - chown -R forgejo-runner:forgejo-runner /data + if [[ $(stat -c "%u" /data) != "${RUNNER_USER}" ]]; then + decho "Changing ownership of /data to ${RUNNER_USER}" + chown -R forgejo-runner:forgejo-runner /data + fi fi # Handle and alter the config file @@ -51,9 +62,16 @@ if [[ -z "${CONFIG_FILE}" ]]; then CONFIG_FILE="/data/config.yml" fi CONFIG_ARG="--config ${CONFIG_FILE}" +decho "CONFIG: ${CONFIG_ARG}" 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 + echo "Creating ${CONFIG_FILE}" run_command "forgejo-runner generate-config > ${CONFIG_FILE}" forgejo-runner # 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 "/^ privileged:/c\ privileged: true" ${CONFIG_FILE} + if [[ "${DOCKER_TLS_VERIFY}" -ne 1 ]]; then + decho "Docker TLS diabled" sed -i "/^ docker_host:/c\ docker_host: tcp://${DOCKER_HOST}:2375" ${CONFIG_FILE} else + decho "Docker TLS enabled" 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 "/^ options:/c\ options: -v /certs/client:/certs/client" ${CONFIG_FILE} + sed -i "/^ valid_volumes:/c\ valid_volumes:\n - ${DOCKER_TLS_CERTDIR}" ${CONFIG_FILE} + sed -i "/^ options:/c\ options: -v ${DOCKER_TLS_CERTDIR}:${DOCKER_TLS_CERTDIR}" ${CONFIG_FILE} fi fi -if [[ ! -z "${ENV_FILE}" ]]; then - sed -i "/^ env_file:/c\ env_file: ${ENV_FILE}" ${CONFIG_FILE} -else - ENV_FILE="/data/.env" -fi +ENV_FILE=${ENV_FILE:-"/data/.env"} +decho "ENV_FILE: ${ENV_FILE}" +sed -i "/^ env_file:/c\ env_file: ${ENV_FILE}" ${CONFIG_FILE} if [[ ! -f "${ENV_FILE}" ]]; then echo "Creating ${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 EXTRA_ARGS="" if [[ ! -z "${RUNNER_LABELS}" ]]; then EXTRA_ARGS="${EXTRA_ARGS} --labels ${RUNNER_LABELS}" fi +decho "EXTRA_ARGS: ${EXTRA_ARGS}" # Set the runner file 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 +decho "RUNNER_FILE: ${RUNNER_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 touch ${RUNNER_FILE} try=$((try + 1)) success=0 + decho "try: ${try}, success: ${success}" if [[ ! -z "${FORGEJO_SECRET}" ]]; then EXTRA_ARGS="${EXTRA_ARGS} --secret ${FORGEJO_SECRET}" @@ -112,6 +142,7 @@ if [[ ! -s "${RUNNER_FILE}" ]]; then EXTRA_ARGS="${EXTRA_ARGS} --token ${RUNNER_TOKEN}" echo "Registering with TOKEN" 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, # 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 ..." sleep 5 fi + decho "try: ${try}, success: ${success}" done fi # Prevent reading the token from the forgejo-runner process unset RUNNER_TOKEN +unset FORGEJO_SECRET run_command "forgejo-runner daemon ${CONFIG_ARG}" diff --git a/examples/docker-compose/compose-forgejo-and-runner.yml b/examples/docker-compose/compose-forgejo-and-runner.yml index e38e841..e644a4f 100644 --- a/examples/docker-compose/compose-forgejo-and-runner.yml +++ b/examples/docker-compose/compose-forgejo-and-runner.yml @@ -7,7 +7,7 @@ # openssl rand -hex 20 # # Replace all occurences of {SHARED_SECRET} below with the output. -# +# # NOTE: a token obtained from the Forgejo web interface cannot be used # as a shared secret. # @@ -23,20 +23,19 @@ volumes: services: docker-in-docker: image: code.forgejo.org/oci/docker:dind - container_name: docker # needed for docker internal DNS resolution - hostname: docker # Must set hostname as TLS certificates are only valid for docker or localhost + # container_name: docker # Must set container_name to docker for both internal DNS and TLS to work + hostname: docker privileged: true networks: - forgejo environment: - DOCKER_TLS_CERTDIR: "" # set to "certs" to use the TLS certificates, also update existing runner configs to use port 2376 - DOCKER_HOST: docker-in-docker + DOCKER_TLS_CERTDIR: "/certs" # set to "" to disable the use of TLS, also manually update existing runner configs to use port 2375 volumes: - docker_certs:/certs forgejo: image: codeberg.org/forgejo/forgejo:1.21 - container_name: forgejo + hostname: forgejo networks: - forgejo volumes: @@ -47,20 +46,21 @@ services: bash -c ' /bin/s6-svscan /etc/s6 & 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 ; 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: ## TODO: Update image to the the release ## 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 - container_name: forgejo-runner - # user: "1000" # set to run rootless, overrides RUNNER_USER + + # image: code.forgejo.org/forgejo/runner:3.4.1 + build: ../../ + # user: "1000" # set to run rootless, overrides RUNNER_USER and disables automatic file ownership volumes: - ./forgejo-runner:/data - docker_certs:/certs @@ -70,39 +70,19 @@ services: - docker-in-docker - forgejo 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 - FORGEJO_SECRET: "{SHARED_SECRET}" # shared secret, must match Forgejo's + DOCKER_HOST: "docker" # defaults to docker + 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 - RUNNER_NAME: forgejo-runner # defaults to forgejo-runner, used for registration + 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_TOKEN: "${RUNNER_TOKEN}" - RUNNER_USER: 1000 # defaults to 1000 + RUNNER_USER: 1000 # defaults to 1000, allows for automatic file ownership - forgejo-runner-rootless: - ## TODO: Update image to the the release - ## 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}" \ No newline at end of file + DEBUG: "true" # defaults to false, set to true to enable debug logging + 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