mirror of
https://github.com/imjasonh/terraform-playground
synced 2026-07-06 23:12:22 +00:00
Add Gitea deployment with Cloud Run and GCS storage
- Deploy Gitea on Cloud Run with persistent GCS storage - Pre-configure with app.ini to skip setup wizard - Enable OAuth2 functionality (GitHub OAuth ready) - Use SQLite for simple single-instance deployment - Mount configuration and data via GCS FUSE - Add documentation for OAuth setup 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
64e62489df
commit
51ee9aa0ec
2 changed files with 167 additions and 14 deletions
83
gitea/app.ini.tpl
Normal file
83
gitea/app.ini.tpl
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
; Gitea Configuration File
|
||||
; This file is auto-generated by Terraform
|
||||
|
||||
APP_NAME = Gitea: Git with a cup of tea
|
||||
RUN_USER = git
|
||||
RUN_MODE = prod
|
||||
|
||||
[database]
|
||||
DB_TYPE = sqlite3
|
||||
PATH = /data/gitea/gitea.db
|
||||
|
||||
[repository]
|
||||
ROOT = /data/gitea/repositories
|
||||
|
||||
[server]
|
||||
DOMAIN = ${domain}
|
||||
HTTP_PORT = 3000
|
||||
ROOT_URL = ${root_url}
|
||||
DISABLE_SSH = false
|
||||
SSH_PORT = 22
|
||||
LFS_START_SERVER = true
|
||||
APP_DATA_PATH = /data/gitea
|
||||
|
||||
[security]
|
||||
INSTALL_LOCK = true
|
||||
SECRET_KEY = ${secret_key}
|
||||
INTERNAL_TOKEN = ${internal_token}
|
||||
|
||||
[service]
|
||||
REGISTER_EMAIL_CONFIRM = false
|
||||
ENABLE_NOTIFY_MAIL = false
|
||||
DISABLE_REGISTRATION = false
|
||||
ENABLE_CAPTCHA = false
|
||||
REQUIRE_SIGNIN_VIEW = false
|
||||
DEFAULT_KEEP_EMAIL_PRIVATE = true
|
||||
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||
DEFAULT_ENABLE_TIMETRACKING = true
|
||||
|
||||
[oauth2]
|
||||
ENABLE = true
|
||||
|
||||
[oauth2_client]
|
||||
ENABLE = true
|
||||
ENABLE_AUTO_REGISTRATION = true
|
||||
REGISTER_EMAIL_CONFIRM = false
|
||||
ACCOUNT_LINKING = auto
|
||||
|
||||
[openid]
|
||||
ENABLE_OPENID_SIGNIN = false
|
||||
ENABLE_OPENID_SIGNUP = false
|
||||
|
||||
[log]
|
||||
MODE = console
|
||||
LEVEL = info
|
||||
ROOT_PATH = /data/gitea/log
|
||||
|
||||
[picture]
|
||||
AVATAR_UPLOAD_PATH = /data/gitea/avatars
|
||||
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
|
||||
|
||||
[attachment]
|
||||
PATH = /data/gitea/attachments
|
||||
|
||||
[lfs]
|
||||
PATH = /data/gitea/lfs
|
||||
|
||||
[session]
|
||||
PROVIDER = file
|
||||
PROVIDER_CONFIG = /data/gitea/sessions
|
||||
|
||||
[indexer]
|
||||
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
|
||||
REPO_INDEXER_PATH = /data/gitea/indexers/repos.bleve
|
||||
|
||||
[cache]
|
||||
ENABLED = true
|
||||
ADAPTER = memory
|
||||
|
||||
[mailer]
|
||||
ENABLED = false
|
||||
|
||||
; OAuth providers must be configured through the UI or CLI after deployment
|
||||
; The OAuth2 functionality is enabled above
|
||||
|
|
@ -14,11 +14,26 @@ provider "google" {
|
|||
region = var.region
|
||||
}
|
||||
|
||||
provider "google-beta" {
|
||||
project = var.project
|
||||
region = var.region
|
||||
}
|
||||
|
||||
resource "google_artifact_registry_repository" "repo" {
|
||||
repository_id = var.name
|
||||
format = "DOCKER"
|
||||
}
|
||||
|
||||
# Generate app.ini configuration
|
||||
locals {
|
||||
app_ini_content = templatefile("${path.module}/app.ini.tpl", {
|
||||
domain = "${var.name}-${var.project}.${var.region}.run.app"
|
||||
root_url = "https://${var.name}-${var.project}.${var.region}.run.app"
|
||||
secret_key = random_password.secret_key.result
|
||||
internal_token = random_password.internal_token.result
|
||||
})
|
||||
}
|
||||
|
||||
resource "random_id" "bucket" { byte_length = 8 }
|
||||
|
||||
resource "google_storage_bucket" "bucket" {
|
||||
|
|
@ -26,37 +41,56 @@ resource "google_storage_bucket" "bucket" {
|
|||
location = var.region
|
||||
}
|
||||
|
||||
data "oci_ref" "upstream" { ref = "gitea/gitea" }
|
||||
|
||||
resource "cosign_copy" "copy" {
|
||||
source = "${data.oci_ref.upstream.ref}@${data.oci_ref.upstream.digest}"
|
||||
destination = "${var.region}-docker.pkg.dev/${var.project}/${google_artifact_registry_repository.repo.name}/gitea"
|
||||
# Generate secure tokens for Gitea configuration
|
||||
resource "random_password" "secret_key" {
|
||||
length = 64
|
||||
special = true
|
||||
}
|
||||
|
||||
resource "random_password" "internal_token" {
|
||||
length = 64
|
||||
special = true
|
||||
}
|
||||
|
||||
resource "cosign_copy" "copy" {
|
||||
source = provider::oci::get("gitea/gitea:latest").full_ref
|
||||
destination = "${var.region}-docker.pkg.dev/${var.project}/${google_artifact_registry_repository.repo.name}/gitea"
|
||||
}
|
||||
resource "google_service_account" "sa" { account_id = "${var.name}-sa" }
|
||||
|
||||
resource "google_storage_bucket_iam_binding" "bucket" {
|
||||
bucket = google_storage_bucket.bucket.name
|
||||
role = "roles/storage.objectAdmin"
|
||||
members = [
|
||||
"serviceAccount:${google_service_account.sa.email}",
|
||||
]
|
||||
bucket = google_storage_bucket.bucket.name
|
||||
role = "roles/storage.objectAdmin"
|
||||
members = ["serviceAccount:${google_service_account.sa.email}"]
|
||||
}
|
||||
|
||||
// TODO: fails with
|
||||
// - error: chmod on /data/gitea/home/.gitconfig.lock failed: Operation not permitted
|
||||
# Upload app.ini to GCS
|
||||
resource "google_storage_bucket_object" "app_ini" {
|
||||
name = "gitea/conf/app.ini"
|
||||
bucket = google_storage_bucket.bucket.name
|
||||
content = local.app_ini_content
|
||||
}
|
||||
|
||||
resource "google_cloud_run_v2_service" "svc" {
|
||||
provider = google-beta
|
||||
name = var.name
|
||||
location = var.region
|
||||
|
||||
launch_stage = "BETA"
|
||||
|
||||
# Force new revision when app.ini changes
|
||||
depends_on = [google_storage_bucket_object.app_ini]
|
||||
|
||||
template {
|
||||
scaling { max_instance_count = 1 }
|
||||
|
||||
execution_environment = "EXECUTION_ENVIRONMENT_GEN2"
|
||||
|
||||
# Force new revision when app.ini changes
|
||||
annotations = {
|
||||
"app-ini-hash" = md5(local.app_ini_content)
|
||||
}
|
||||
|
||||
service_account = google_service_account.sa.email
|
||||
timeout = "${60 * 60}s" // 1 hour
|
||||
containers {
|
||||
|
|
@ -65,6 +99,35 @@ resource "google_cloud_run_v2_service" "svc" {
|
|||
ports {
|
||||
container_port = 3000
|
||||
}
|
||||
|
||||
# Add startup probe to ensure Gitea is ready
|
||||
startup_probe {
|
||||
http_get {
|
||||
path = "/"
|
||||
port = 3000
|
||||
}
|
||||
initial_delay_seconds = 10
|
||||
period_seconds = 5
|
||||
timeout_seconds = 3
|
||||
failure_threshold = 30
|
||||
}
|
||||
|
||||
|
||||
# Use custom config from mounted volume
|
||||
env {
|
||||
name = "GITEA_CUSTOM"
|
||||
value = "/data"
|
||||
}
|
||||
env {
|
||||
name = "USER_UID"
|
||||
value = "1000"
|
||||
}
|
||||
env {
|
||||
name = "USER_GID"
|
||||
value = "1000"
|
||||
}
|
||||
|
||||
|
||||
volume_mounts {
|
||||
name = "gcs"
|
||||
mount_path = "/data"
|
||||
|
|
@ -74,8 +137,9 @@ resource "google_cloud_run_v2_service" "svc" {
|
|||
volumes {
|
||||
name = "gcs"
|
||||
gcs {
|
||||
bucket = google_storage_bucket.bucket.name
|
||||
read_only = false
|
||||
bucket = google_storage_bucket.bucket.name
|
||||
read_only = false
|
||||
mount_options = ["uid=1000", "gid=1000", "file-mode=0755", "dir-mode=0755"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -89,3 +153,9 @@ resource "google_cloud_run_service_iam_binding" "noauth" {
|
|||
}
|
||||
|
||||
output "url" { value = google_cloud_run_v2_service.svc.uri }
|
||||
output "image" { value = cosign_copy.copy.copied_ref }
|
||||
|
||||
output "github_oauth_callback_url" {
|
||||
value = "${google_cloud_run_v2_service.svc.uri}/user/oauth2/github/callback"
|
||||
description = "GitHub OAuth callback URL to use when configuring your GitHub OAuth app"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue