Initial commit - realms platform
This commit is contained in:
parent
2aa075e842
commit
b3682b1936
12 changed files with 148 additions and 100 deletions
|
|
@ -23,7 +23,7 @@ jobs:
|
||||||
# Build Backend (C++/Drogon)
|
# Build Backend (C++/Drogon)
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
build-backend:
|
build-backend:
|
||||||
runs-on: docker
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
@ -50,7 +50,7 @@ jobs:
|
||||||
# Build Frontend (SvelteKit)
|
# Build Frontend (SvelteKit)
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
build-frontend:
|
build-frontend:
|
||||||
runs-on: docker
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
@ -77,7 +77,7 @@ jobs:
|
||||||
# Build Chat Service
|
# Build Chat Service
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
build-chat:
|
build-chat:
|
||||||
runs-on: docker
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
@ -104,7 +104,7 @@ jobs:
|
||||||
# Build OpenResty (Nginx + Lua)
|
# Build OpenResty (Nginx + Lua)
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
build-openresty:
|
build-openresty:
|
||||||
runs-on: docker
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
deploy:
|
deploy:
|
||||||
# Only deploy if build succeeded OR manual trigger
|
# Only deploy if build succeeded OR manual trigger
|
||||||
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
|
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
|
||||||
runs-on: docker
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
|
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -122,6 +122,11 @@ secrets.json
|
||||||
.gnupg/
|
.gnupg/
|
||||||
backend/config.json
|
backend/config.json
|
||||||
!backend/config.json.example
|
!backend/config.json.example
|
||||||
|
terraform.tfvars
|
||||||
|
terraform.tfstate
|
||||||
|
terraform.tfstate.backup
|
||||||
|
.terraform/
|
||||||
|
.terraform.lock.hcl
|
||||||
|
|
||||||
# Temporary Files
|
# Temporary Files
|
||||||
# ======================================================
|
# ======================================================
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,12 @@ services:
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 256M
|
||||||
|
reservations:
|
||||||
|
memory: 128M
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Forgejo Git Server
|
# Forgejo Git Server
|
||||||
|
|
@ -105,6 +111,14 @@ services:
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
start_period: 60s
|
start_period: 60s
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 384M
|
||||||
|
reservations:
|
||||||
|
memory: 192M
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Caddy Reverse Proxy
|
# Caddy Reverse Proxy
|
||||||
|
|
@ -128,6 +142,14 @@ services:
|
||||||
- forgejo-public
|
- forgejo-public
|
||||||
environment:
|
environment:
|
||||||
FORGEJO_DOMAIN: ${FORGEJO_DOMAIN}
|
FORGEJO_DOMAIN: ${FORGEJO_DOMAIN}
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 64M
|
||||||
|
reservations:
|
||||||
|
memory: 32M
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Forgejo Actions Runner
|
# Forgejo Actions Runner
|
||||||
|
|
@ -161,6 +183,12 @@ services:
|
||||||
fi
|
fi
|
||||||
forgejo-runner daemon --config /data/config.yaml
|
forgejo-runner daemon --config /data/config.yaml
|
||||||
'
|
'
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 256M
|
||||||
|
reservations:
|
||||||
|
memory: 128M
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Docker-in-Docker for Runner
|
# Docker-in-Docker for Runner
|
||||||
|
|
@ -184,6 +212,8 @@ services:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
memory: 512M
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
memory: 256M
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Networks
|
# Networks
|
||||||
|
|
|
||||||
|
|
@ -379,16 +379,77 @@ write_files:
|
||||||
reservations:
|
reservations:
|
||||||
memory: 32M
|
memory: 32M
|
||||||
|
|
||||||
|
# Forgejo Actions Runner (CI/CD)
|
||||||
|
forgejo-runner:
|
||||||
|
image: code.forgejo.org/forgejo/runner:6.3.1
|
||||||
|
container_name: forgejo-runner
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
forgejo:
|
||||||
|
condition: service_healthy
|
||||||
|
docker-dind:
|
||||||
|
condition: service_started
|
||||||
|
environment:
|
||||||
|
DOCKER_HOST: tcp://docker-dind:2376
|
||||||
|
DOCKER_TLS_VERIFY: "1"
|
||||||
|
DOCKER_CERT_PATH: /certs/client
|
||||||
|
volumes:
|
||||||
|
- /mnt/forgejo/runner-data:/data
|
||||||
|
- dind-certs-client:/certs/client:ro
|
||||||
|
networks:
|
||||||
|
- forgejo-internal
|
||||||
|
- dind-network
|
||||||
|
command: >
|
||||||
|
sh -c '
|
||||||
|
if [ ! -f /data/.runner ]; then
|
||||||
|
echo "Runner not registered. Run: docker compose exec forgejo-runner forgejo-runner register"
|
||||||
|
sleep infinity
|
||||||
|
fi
|
||||||
|
forgejo-runner daemon --config /data/config.yaml
|
||||||
|
'
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 256M
|
||||||
|
reservations:
|
||||||
|
memory: 128M
|
||||||
|
|
||||||
|
# Docker-in-Docker for Runner (builds images in CI/CD)
|
||||||
|
docker-dind:
|
||||||
|
image: docker:27-dind
|
||||||
|
container_name: forgejo-dind
|
||||||
|
restart: unless-stopped
|
||||||
|
privileged: true
|
||||||
|
environment:
|
||||||
|
DOCKER_TLS_CERTDIR: /certs
|
||||||
|
volumes:
|
||||||
|
- dind-certs-ca:/certs/ca
|
||||||
|
- dind-certs-client:/certs/client
|
||||||
|
- dind-storage:/var/lib/docker
|
||||||
|
networks:
|
||||||
|
- dind-network
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
memory: 256M
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
forgejo-internal:
|
forgejo-internal:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
internal: true
|
internal: true
|
||||||
forgejo-public:
|
forgejo-public:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
dind-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
caddy_data:
|
caddy_data:
|
||||||
caddy_config:
|
caddy_config:
|
||||||
|
dind-certs-ca:
|
||||||
|
dind-certs-client:
|
||||||
|
dind-storage:
|
||||||
permissions: '0644'
|
permissions: '0644'
|
||||||
|
|
||||||
# Caddy Dockerfile with rate-limit plugin
|
# Caddy Dockerfile with rate-limit plugin
|
||||||
|
|
@ -516,6 +577,15 @@ write_files:
|
||||||
| cd /opt/forgejo && docker compose logs -f |
|
| cd /opt/forgejo && docker compose logs -f |
|
||||||
| cd /opt/forgejo && docker compose restart |
|
| cd /opt/forgejo && docker compose restart |
|
||||||
| |
|
| |
|
||||||
|
| Runner Registration: |
|
||||||
|
| 1. Get token from Forgejo: Site Admin > Actions > Runners |
|
||||||
|
| 2. Register runner: |
|
||||||
|
| cd /opt/forgejo && docker compose exec forgejo-runner \ |
|
||||||
|
| forgejo-runner register --instance https://${domain} |
|
||||||
|
| --token YOUR_TOKEN --name realms-runner |
|
||||||
|
| --labels ubuntu-latest,docker |
|
||||||
|
| 3. Restart: docker compose restart forgejo-runner |
|
||||||
|
| |
|
||||||
+---------------------------------------------------------------+
|
+---------------------------------------------------------------+
|
||||||
|
|
||||||
permissions: '0644'
|
permissions: '0644'
|
||||||
|
|
@ -580,7 +650,7 @@ runcmd:
|
||||||
|
|
||||||
# Start Forgejo stack (build Caddy with rate-limit plugin, pull others)
|
# Start Forgejo stack (build Caddy with rate-limit plugin, pull others)
|
||||||
- cd /opt/forgejo && docker compose build caddy
|
- cd /opt/forgejo && docker compose build caddy
|
||||||
- cd /opt/forgejo && docker compose pull forgejo forgejo-db
|
- cd /opt/forgejo && docker compose pull forgejo forgejo-db forgejo-runner docker-dind
|
||||||
- cd /opt/forgejo && docker compose up -d
|
- cd /opt/forgejo && docker compose up -d
|
||||||
|
|
||||||
# Enable unattended upgrades
|
# Enable unattended upgrades
|
||||||
|
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
# =============================================================================
|
|
||||||
# DigitalOcean Terraform Configuration
|
|
||||||
# =============================================================================
|
|
||||||
# Copy this file to terraform.tfvars and fill in your values
|
|
||||||
# NEVER commit terraform.tfvars to version control!
|
|
||||||
#
|
|
||||||
# Set the DO token via environment variable:
|
|
||||||
# export TF_VAR_do_token="dop_v1_your_token_here"
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Project Configuration
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
project_name = "realms"
|
|
||||||
environment = "production"
|
|
||||||
region = "nyc3"
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# VPC Configuration
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
vpc_ip_range = "10.10.0.0/16"
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# SSH Configuration
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Add your admin SSH public key(s) here
|
|
||||||
# Generate with: ssh-keygen -t ed25519 -C "your_email@example.com"
|
|
||||||
admin_ssh_public_keys = {
|
|
||||||
# "admin-name" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINlczdk2KKjY2CyYV1Ql8enjRn8gpBBgSLmbbCUyG5Qs admin@doom.tube"
|
|
||||||
}
|
|
||||||
|
|
||||||
# SSH ports (non-standard for security)
|
|
||||||
jump_host_ssh_port = 49822 # Jump host public SSH
|
|
||||||
forgejo_ssh_port = 52913 # Forgejo system SSH (VPC only)
|
|
||||||
forgejo_git_ssh_port = 2222 # Forgejo Git SSH (public)
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Jump Host Configuration
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
jump_host_size = "s-1vcpu-512mb-10gb" # $4/mo
|
|
||||||
jump_host_image = "debian-12-x64"
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Forgejo Configuration
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
forgejo_droplet_size = "s-1vcpu-1gb-intel" # $7/mo - 1GB RAM, 1 Intel vCPU
|
|
||||||
forgejo_droplet_image = "debian-12-x64"
|
|
||||||
forgejo_volume_size = 50 # GB for repositories and LFS
|
|
||||||
forgejo_domain = "qbit.realms.pub"
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# DNS Configuration (requires domain to be managed by DigitalOcean)
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Set to true to automatically create/update A record for Forgejo
|
|
||||||
manage_dns = true
|
|
||||||
|
|
||||||
# Base domain managed by DigitalOcean DNS
|
|
||||||
dns_zone = "realms.pub"
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Backup Configuration
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
enable_droplet_backups = true
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Additional Tags
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
tags = []
|
|
||||||
|
|
@ -94,9 +94,9 @@ variable "jump_host_image" {
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
variable "forgejo_droplet_size" {
|
variable "forgejo_droplet_size" {
|
||||||
description = "Size slug for the Forgejo droplet"
|
description = "Size slug for the Forgejo droplet (2GB+ recommended for Actions Runner)"
|
||||||
type = string
|
type = string
|
||||||
default = "s-1vcpu-1gb-intel"
|
default = "s-2vcpu-2gb-intel"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "forgejo_droplet_image" {
|
variable "forgejo_droplet_image" {
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,19 @@ locals {
|
||||||
# SSH Keys
|
# SSH Keys
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
resource "digitalocean_ssh_key" "admin" {
|
# Get all SSH keys on account
|
||||||
for_each = var.admin_ssh_public_keys
|
data "digitalocean_ssh_keys" "all" {}
|
||||||
|
|
||||||
name = "${var.project_name}-app-${var.environment}-${each.key}"
|
# Find the internal VPC key (created by devops/terraform for jump host access)
|
||||||
public_key = each.value
|
locals {
|
||||||
|
internal_key_name = "${var.project_name}-${var.environment}-internal-key"
|
||||||
|
internal_key_ids = [for k in data.digitalocean_ssh_keys.all.ssh_keys : k.id if k.name == local.internal_key_name]
|
||||||
|
|
||||||
|
# Combine: internal key (for jump host) + all admin keys
|
||||||
|
all_ssh_key_ids = distinct(concat(
|
||||||
|
local.internal_key_ids,
|
||||||
|
[for k in data.digitalocean_ssh_keys.all.ssh_keys : k.id]
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
@ -35,7 +43,7 @@ module "app_server" {
|
||||||
region = var.region
|
region = var.region
|
||||||
vpc_uuid = var.vpc_uuid
|
vpc_uuid = var.vpc_uuid
|
||||||
vpc_ip_range = var.vpc_ip_range
|
vpc_ip_range = var.vpc_ip_range
|
||||||
ssh_keys = [for key in digitalocean_ssh_key.admin : key.id]
|
ssh_keys = local.all_ssh_key_ids
|
||||||
droplet_size = var.app_droplet_size
|
droplet_size = var.app_droplet_size
|
||||||
droplet_image = var.app_droplet_image
|
droplet_image = var.app_droplet_image
|
||||||
ssh_port = var.app_ssh_port
|
ssh_port = var.app_ssh_port
|
||||||
|
|
@ -44,5 +52,6 @@ module "app_server" {
|
||||||
tags = local.common_tags
|
tags = local.common_tags
|
||||||
manage_dns = var.manage_dns
|
manage_dns = var.manage_dns
|
||||||
dns_zone = var.dns_zone
|
dns_zone = var.dns_zone
|
||||||
|
dns_record_name = var.dns_record_name
|
||||||
forgejo_registry = var.forgejo_registry
|
forgejo_registry = var.forgejo_registry
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,17 +180,7 @@ resource "digitalocean_record" "app" {
|
||||||
|
|
||||||
domain = var.dns_zone
|
domain = var.dns_zone
|
||||||
type = "A"
|
type = "A"
|
||||||
name = "@"
|
name = var.dns_record_name
|
||||||
value = digitalocean_droplet.app.ipv4_address
|
|
||||||
ttl = 600
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "digitalocean_record" "app_www" {
|
|
||||||
count = var.manage_dns ? 1 : 0
|
|
||||||
|
|
||||||
domain = var.dns_zone
|
|
||||||
type = "A"
|
|
||||||
name = "www"
|
|
||||||
value = digitalocean_droplet.app.ipv4_address
|
value = digitalocean_droplet.app.ipv4_address
|
||||||
ttl = 600
|
ttl = 600
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,12 @@ variable "dns_zone" {
|
||||||
default = "realms.pub"
|
default = "realms.pub"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "dns_record_name" {
|
||||||
|
description = "DNS record name (subdomain). Use '@' for root or 'beeta' for beeta.realms.pub"
|
||||||
|
type = string
|
||||||
|
default = "beeta"
|
||||||
|
}
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Forgejo Registry
|
# Forgejo Registry
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
|
||||||
8
terraform/modules/app_server/versions.tf
Normal file
8
terraform/modules/app_server/versions.tf
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
digitalocean = {
|
||||||
|
source = "digitalocean/digitalocean"
|
||||||
|
version = "~> 2.34"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -104,6 +104,12 @@ variable "dns_zone" {
|
||||||
default = "realms.pub"
|
default = "realms.pub"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "dns_record_name" {
|
||||||
|
description = "DNS record name (subdomain). Use '@' for root or 'beeta' for beeta.realms.pub"
|
||||||
|
type = string
|
||||||
|
default = "beeta"
|
||||||
|
}
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Backup Configuration
|
# Backup Configuration
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue