From 9e3a8d6395a130344dc20d37646b7b03660858e6 Mon Sep 17 00:00:00 2001 From: Jeff Clement Date: Fri, 1 Nov 2024 21:50:08 -0600 Subject: [PATCH] Initial version of the Forgejo via. Cloudflare --- README.md | 10 ++- forgejo_cloudflare/.env | 36 ++++++++ forgejo_cloudflare/README.md | 32 +++++++ forgejo_cloudflare/docker-compose.yml | 124 ++++++++++++++++++++++++++ 4 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 forgejo_cloudflare/.env create mode 100644 forgejo_cloudflare/README.md create mode 100644 forgejo_cloudflare/docker-compose.yml diff --git a/README.md b/README.md index b97b319..31e4afb 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ -# Hello, World! \ No newline at end of file +# Docker Sample Repository + +This repository is a collection of Docker Compose examples for various self-hosted services. Installing/configuring internet-facing systems is complex and comes with risk. These samples strive to be self-contained and give a good starting point to get you up and running quickly. They are not intended to be bullet-proof production grade ready-to-rock examples. As such, these are provided without any warranty / use at your own risk. + +To make services easier to manage (backup, restore, move to a different host, etc.), they typically use bind-mounts to store data in a subdirectory (typically `./data`) alongside the `docker-compose.yml` and `.env` files, rather than Docker Volumes. + +Similarly, many examples here rely on Cloudflare Tunnels for publicly exposing services, and Tailscale for internal services. + +In most cases, minimal changes should be required to the `docker-compose.yml` file, while the bulk of the changes will be to the `.env` file. diff --git a/forgejo_cloudflare/.env b/forgejo_cloudflare/.env new file mode 100644 index 0000000..c346bed --- /dev/null +++ b/forgejo_cloudflare/.env @@ -0,0 +1,36 @@ +FORGEJO_TAG=8 +FORGEJO_RUNNER_TAG=4.0.1 + +# Instance Settings +APP_NAME="My Git Server" +FORGEJO_HOSTNAME=git.yourdomain.com +SSH_DOMAIN=git-ssh.yourdomain.com +DISABLE_REGISTRATION=true + +ROOT_URL=https://${FORGEJO_HOSTNAME} + +# Cloudflare Tunnel Token +TUNNEL_TOKEN= ##REQUIRED## + +# Database +FORGEJO_DB_PASSWORD= ##REQUIRED## + +# Mail +MAIL_ENABLED=true +MAIL_FROM='"Git Server" ' +MAIL_SMTP_USER=forgejo@mg.yourdomain.com +MAIL_SMTP_PASSWD= ##REQUIRED## +MAIL_SMTP_PROTOCOL=smtps +MAIL_SMTP_ADDR=smtp.mailgun.org +MAIL_SMTP_PORT=465 + +# Initial user +ROOT_USER=admin +ROOT_EMAIL=admin@yourdomain.com +ROOT_PASSWORD= ##REQUIRED## + +# Token for runner (generate with `openssl rand -hex 20`) +SHARED_SECRET= ##REQUIRED## + +# Runner name / labels +RUNNER_NAME=runner \ No newline at end of file diff --git a/forgejo_cloudflare/README.md b/forgejo_cloudflare/README.md new file mode 100644 index 0000000..c797d8d --- /dev/null +++ b/forgejo_cloudflare/README.md @@ -0,0 +1,32 @@ +# Forgejo via. Cloudflare Tunnel + +This example is a quick start to running an instance of the excellent Forgejo git server under Docker. + +* Publicly exposed via. Cloudflare Tunnel +* Pre-configured Github Action-style Runners +* Mail delivery (assuming Mailgun, but adjustable to any SMTP server) +* Pre-configured (no installation wizard) including admin account + +See the full blog post on this here: +https://www.straybits.ca/2014/self-hosted-git-server/ + +## Steps: + +0. Create a Tunnel on Cloudflare and grab the Tunnel Token +1. Copy `docker-compose.yml` and `.env` to a new folder +2. Update variables in `.env` making sure to generate random secrets for the various secrets marked with `##REQUIRED##` +3. Make sure to update the `yourdomain.com` to match your name +4. Add end points to your Tunnel + 1. `git.yourdomain.com` >> `http://server:3000` + 2. `git-ssh.yourdomain.com` >> `ssh://server:22` +5. `docker compose up -d` +6. Wait... +7. Wait a bit more +8. Visit `https://git.yourdomain.com` in your browser and login with the admin credentials in your `.env` file. +9. Verify settings. (i.e. do you want to disable user signups, etc.) + +## Known Issue + +### Disappearing Runner Labels + +If your runner labels disappear after a restart, you may need to update your runner's `config.yml` to have the same list of runners as found in your `.runner` file. \ No newline at end of file diff --git a/forgejo_cloudflare/docker-compose.yml b/forgejo_cloudflare/docker-compose.yml new file mode 100644 index 0000000..d26e8db --- /dev/null +++ b/forgejo_cloudflare/docker-compose.yml @@ -0,0 +1,124 @@ +services: + + tunnel: + image: cloudflare/cloudflared + command: tunnel --no-autoupdate run + restart: unless-stopped + environment: + - TUNNEL_TOKEN=${TUNNEL_TOKEN} + + server: + image: codeberg.org/forgejo/forgejo:${FORGEJO_TAG} + command: >- + bash -c ' + /bin/s6-svscan /etc/s6 & + sleep 10 ; + su -c "forgejo forgejo-cli actions register --secret ${SHARED_SECRET}" git ; + su -c "forgejo admin user create --admin --username ${ROOT_USER} --password ${ROOT_PASSWORD} --email ${ROOT_EMAIL}" git ; + sleep infinity + ' + environment: + # https://forgejo.org/docs/latest/admin/config-cheat-sheet/ + - RUN_MODE=prod + - USER_UID=1000 + - USER_GID=1000 + - APP_NAME=${APP_NAME} + - FORGEJO__server__ROOT_URL=${ROOT_URL} + # Because we're using Cloudflare, we need the SSH domain + # to be on a different name, like `git-ssh.yourname.com` so + # we override the SSH Domain + - FORGEJO__server__SSH_DOMAIN=${SSH_DOMAIN} + # Prevent the installation wizard from running + - FORGEJO__security__INSTALL_LOCK=true + # Do we allow new signups? + - FORGEJO__service__DISABLE_REGISTRATION=${DISABLE_REGISTRATION} + # DB Setup + - FORGEJO__database__DB_TYPE=postgres + - FORGEJO__database__HOST=db:5432 + - FORGEJO__database__NAME=gitea + - FORGEJO__database__USER=gitea + - FORGEJO__database__PASSWD=${FORGEJO_DB_PASSWORD} + # Mail Setup + - FORGEJO__mailer__ENABLED=${MAIL_ENABLED} + - FORGEJO__mailer__FROM=${MAIL_FROM} + - FORGEJO__mailer__PROTOCOL=${MAIL_SMTP_PROTOCOL} + - FORGEJO__mailer__SMTP_ADDR=${MAIL_SMTP_ADDR} + - FORGEJO__mailer__SMTP_PORT=${MAIL_SMTP_PORT} + - FORGEJO__mailer__USER=${MAIL_SMTP_USER} + - FORGEJO__mailer__PASSWD=${MAIL_SMTP_PASSWD} + # Git rid of the splash screen and just show a project listing + # on the homepage + - FORGEJO__server__LANDING_PAGE=explore + restart: always + volumes: + - ./data/data:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + depends_on: + - db + + db: + image: postgres:13 + restart: always + environment: + - POSTGRES_USER=gitea + - POSTGRES_PASSWORD=${FORGEJO_DB_PASSWORD} + - POSTGRES_DB=gitea + volumes: + - ./data/postgres:/var/lib/postgresql/data + + # Runner configuration is fairly complex and uses Docker-in-Docker + # Pulled from this example: + # https://code.forgejo.org/forgejo/runner/src/branch/main/examples/docker-compose/compose-forgejo-and-runner.yml + + runner-register: + image: code.forgejo.org/forgejo/runner:${FORGEJO_RUNNER_TAG} + links: + - docker-in-docker + - server + environment: + DOCKER_HOST: tcp://docker-in-docker:2376 + volumes: + - ./data/runner-data:/data + user: 0:0 + command: >- + bash -ec ' + while : ; do + forgejo-runner create-runner-file --connect --instance http://server:3000 --name ${RUNNER_NAME} --secret ${SHARED_SECRET} && break ; + sleep 1 ; + done ; + sed -i -e "s|\"labels\": null|\"labels\": [\"docker:docker://code.forgejo.org/oci/node:20-bookworm\", \"ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04\"]|" .runner ; + forgejo-runner generate-config > config.yml ; + sed -i -e "s|network: .*|network: host|" config.yml ; + sed -i -e "s|^ envs:$$| envs:\n DOCKER_HOST: tcp://docker:2376\n DOCKER_TLS_VERIFY: 1\n DOCKER_CERT_PATH: /certs/client|" config.yml ; + sed -i -e "s|^ options:| options: -v /certs/client:/certs/client|" config.yml ; + sed -i -e "s| valid_volumes: \[\]$$| valid_volumes:\n - /certs/client|" config.yml ; + chown -R 1000:1000 /data + ' + + runner-daemon: + image: code.forgejo.org/forgejo/runner:4.0.1 + links: + - docker-in-docker + - server + environment: + DOCKER_HOST: tcp://docker:2376 + DOCKER_CERT_PATH: /certs/client + DOCKER_TLS_VERIFY: "1" + volumes: + - ./data/runner-data:/data + - ./data/docker_certs:/certs + command: >- + bash -c ' + while : ; do test -w .runner && forgejo-runner --config config.yml daemon ; sleep 1 ; done + ' + + docker-in-docker: + image: docker:dind + hostname: docker # Must set hostname as TLS certificates are only valid for docker or localhost + privileged: true + environment: + DOCKER_TLS_CERTDIR: /certs + DOCKER_HOST: docker-in-docker + volumes: + - ./data/docker_certs:/certs \ No newline at end of file