Browse Source

feat: Public and private Caddy instances, Gitea configs

This is a major upgrade.
- Uses a reference to docker network for Caddy instead of hardcoded
  strings
- Sets up Gitea custom config mount with a custom config uploaded as
  well.
- Sets up another Caddy instance which will be usef for public facing
  sites. Listens on public IP only.
- Caddy network name refactors.
- DO Firewall rules now all CF IPs to access 80/443 ports.
- Sidenote: Enabled CF Full Strict mode with this commit.
pull/3/head
Karan Sharma 12 months ago
parent
commit
6d885c948a
  1. 15
      floyd/terraform/Makefile
  2. 2
      floyd/terraform/bookstack/container.tf
  3. 3
      floyd/terraform/bookstack/variables.tf
  4. 7
      floyd/terraform/caddy/conf/Caddyfile-internal.tpl
  5. 6
      floyd/terraform/caddy/conf/Caddyfile-public.tpl
  6. 46
      floyd/terraform/caddy/container.tf
  7. 11
      floyd/terraform/caddy/data.tf
  8. 12
      floyd/terraform/caddy/network.tf
  9. 7
      floyd/terraform/caddy/output.tf
  10. 28
      floyd/terraform/digitalocean-infra/firewalls.tf
  11. 8
      floyd/terraform/env.sample
  12. 2
      floyd/terraform/firefly/container.tf
  13. 3
      floyd/terraform/firefly/variables.tf
  14. 122
      floyd/terraform/gitea/conf/app.ini.tpl
  15. 7
      floyd/terraform/gitea/container.tf
  16. 9
      floyd/terraform/gitea/data.tf
  17. 8
      floyd/terraform/gitea/variables.tf
  18. 30
      floyd/terraform/main.tf
  19. 2
      floyd/terraform/monitoring/grafana.tf
  20. 3
      floyd/terraform/monitoring/variables.tf
  21. 2
      floyd/terraform/pihole/container.tf
  22. 3
      floyd/terraform/pihole/variables.tf
  23. 2
      floyd/terraform/syncthing/container.tf
  24. 1
      floyd/terraform/syncthing/variables.tf
  25. 3
      floyd/terraform/unbound/variables.tf
  26. 24
      floyd/terraform/variables.tf

15
floyd/terraform/Makefile

@ -0,0 +1,15 @@
.PHONY: init plan apply lint
plan:
- terraform plan
init:
- terraform init
apply:
- terraform apply -auto-approve
lint:
- terraform validate && terraform fmt

2
floyd/terraform/bookstack/container.tf

@ -21,7 +21,7 @@ resource "docker_container" "bookstack" {
}
networks_advanced {
name = "caddy"
name = var.caddy_network_internal
}
env = [

3
floyd/terraform/bookstack/variables.tf

@ -4,4 +4,5 @@ variable "ips" {
variable "bookstack_mariadb_password" {
type = string
}
}
variable "caddy_network_internal" {}

7
floyd/terraform/caddy/conf/Caddyfile.tpl → floyd/terraform/caddy/conf/Caddyfile-internal.tpl

@ -1,10 +1,3 @@
git.mrkaran.dev {
reverse_proxy gitea:3000
tls {
dns cloudflare "${cloudflare_api_token}"
}
}
pi.mrkaran.dev {
reverse_proxy pihole:80
tls {

6
floyd/terraform/caddy/conf/Caddyfile-public.tpl

@ -0,0 +1,6 @@
git.mrkaran.dev {
reverse_proxy gitea:3000
tls {
dns cloudflare "${cloudflare_api_token}"
}
}

46
floyd/terraform/caddy/container.tf

@ -1,5 +1,5 @@
resource "docker_container" "caddy" {
name = "caddy"
resource "docker_container" "caddy_public" {
name = "caddy_public"
image = docker_image.caddy.latest
volumes {
@ -9,7 +9,45 @@ resource "docker_container" "caddy" {
# Caddyfile
upload {
content = data.template_file.caddyfile.rendered
content = data.template_file.caddyfile_public.rendered
file = "/etc/caddy/Caddyfile"
}
ports {
internal = 443
external = 443
ip = var.ips["public"]
protocol = "tcp"
}
ports {
internal = 80
external = 80
ip = var.ips["public"]
protocol = "tcp"
}
networks_advanced {
name = docker_network.caddy_public.name
}
restart = "unless-stopped"
destroy_grace_seconds = 30
must_run = true
}
resource "docker_container" "caddy_internal" {
name = "caddy_internal"
image = docker_image.caddy.latest
volumes {
host_path = "/data/caddy"
container_path = "/data"
}
# Caddyfile
upload {
content = data.template_file.caddyfile_internal.rendered
file = "/etc/caddy/Caddyfile"
}
@ -28,7 +66,7 @@ resource "docker_container" "caddy" {
}
networks_advanced {
name = docker_network.caddy.name
name = docker_network.caddy_internal.name
}
restart = "unless-stopped"

11
floyd/terraform/caddy/data.tf

@ -1,5 +1,12 @@
data "template_file" "caddyfile" {
template = file("${path.module}/conf/Caddyfile.tpl")
data "template_file" "caddyfile_internal" {
template = file("${path.module}/conf/Caddyfile-internal.tpl")
vars = {
cloudflare_api_token = var.cloudflare_api_token
}
}
data "template_file" "caddyfile_public" {
template = file("${path.module}/conf/Caddyfile-public.tpl")
vars = {
cloudflare_api_token = var.cloudflare_api_token
}

12
floyd/terraform/caddy/network.tf

@ -1,5 +1,11 @@
resource "docker_network" "caddy" {
name = "caddy"
resource "docker_network" "caddy_public" {
name = "caddy_public"
driver = "bridge"
internal = "false"
}
}
resource "docker_network" "caddy_internal" {
name = "caddy_internal"
driver = "bridge"
internal = "false"
}

7
floyd/terraform/caddy/output.tf

@ -0,0 +1,7 @@
output "caddy_network_internal" {
value = docker_network.caddy_internal.name
}
output "caddy_network_public" {
value = docker_network.caddy_public.name
}

28
floyd/terraform/digitalocean-infra/firewalls.tf

@ -1,17 +1,31 @@
data "http" "cloudflare_ip4_addrs" {
url = "https://www.cloudflare.com/ips-v4"
}
data "http" "cloudflare_ip6_addrs" {
url = "https://www.cloudflare.com/ips-v6"
}
resource "digitalocean_firewall" "web" {
name = "allow-http-https-tailscale"
name = "allow-http-https-cloudflare"
droplet_ids = [digitalocean_droplet.floyd.id]
inbound_rule {
protocol = "tcp"
port_range = "80"
source_addresses = ["100.64.0.0/10"]
protocol = "tcp"
port_range = "80"
source_addresses = concat(
split("\n", trimspace(data.http.cloudflare_ip4_addrs.body)),
split("\n", trimspace(data.http.cloudflare_ip6_addrs.body))
)
}
inbound_rule {
protocol = "tcp"
port_range = "443"
source_addresses = ["100.64.0.0/10"]
protocol = "tcp"
port_range = "443"
source_addresses = concat(
split("\n", trimspace(data.http.cloudflare_ip4_addrs.body)),
split("\n", trimspace(data.http.cloudflare_ip6_addrs.body))
)
}
}

8
floyd/terraform/env.sample

@ -1,3 +1,9 @@
DIGITALOCEAN_TOKEN=
TF_VAR_bookstack_mariadb_password=
TF_VAR_cloudflare_api_token=
TF_VAR_cloudflare_api_token=
TF_VAR_firefly_postgres_password=
TF_VAR_firefly_app_key=
TF_VAR_gitea_secret_key=
TF_VAR_gitea_internal_token=
TF_VAR_gitea_lfs_jwt_secret=
TF_VAR_gitea_oauth2_jwt_secret=

2
floyd/terraform/firefly/container.tf

@ -19,7 +19,7 @@ resource "docker_container" "firefly" {
}
networks_advanced {
name = "caddy"
name = var.caddy_network_internal
}
env = [

3
floyd/terraform/firefly/variables.tf

@ -8,4 +8,5 @@ variable "firefly_postgres_password" {
variable "firefly_app_key" {
type = string
}
}
variable "caddy_network_internal" {}

122
floyd/terraform/gitea/conf/app.ini.tpl

@ -0,0 +1,122 @@
; This file lists the default values used by Gitea
; Sample file: https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini
; Docs: https://docs.gitea.io/en-us/config-cheat-sheet/
APP_NAME = Code by mrkaran
RUN_MODE = prod
RUN_USER = git
[repository]
ROOT = /data/git/repositories
[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
[repository.upload]
TEMP_PATH = /data/gitea/uploads
[server]
APP_DATA_PATH = /data/gitea
DOMAIN = git.mrkaran.dev
SSH_DOMAIN = git.mrkaran.dev
HTTP_PORT = 3000
ROOT_URL = https://git.mrkaran.dev/
DISABLE_SSH = false
SSH_PORT = 4222
SSH_LISTEN_PORT = 22
LFS_START_SERVER = true
LFS_CONTENT_PATH = /data/git/lfs
LFS_JWT_SECRET = "${gitea_lfs_jwt_secret}"
OFFLINE_MODE = true
LANDING_PAGE = explore
[ui]
THEME_COLOR_META_TAG = "#6B46C1"
[ui.meta]
AUTHOR = Karan
DESCRIPTION = Karan's self-hosted Gitea instance
KEYWORDS = git, gitea, karan, git.mrkaran.dev, mrkaran
[database]
PATH = /data/gitea/gitea.db
DB_TYPE = sqlite3
HOST = localhost:3306
NAME = gitea
USER = root
PASSWD =
SCHEMA =
SSL_MODE = disable
CHARSET = utf8
[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER = file
COOKIE_SECURE = true
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = true
[attachment]
PATH = /data/gitea/attachments
[log]
ROOT_PATH = /data/gitea/log
MODE = file
LEVEL = info
[security]
INSTALL_LOCK = true
SECRET_KEY = "${gitea_secret_key}"
INTERNAL_TOKEN = "${gitea_internal_token}"
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.localhost
[oauth2]
JWT_SECRET = "${gitea_oauth2_jwt_secret}"
[mailer]
ENABLED = false
[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = true
[metrics]
ENABLED = true
[cron]
ENABLED = true
RUN_AT_START = false
[cron.archive_cleanup]
RUN_AT_START = true
SCHEDULE = @every 24h
OLDER_THAN = 24h
[cron.update_mirrors]
SCHEDULE = @every 3h
[cron.repo_health_check]
SCHEDULE = @every 24h
TIMEOUT = 60s
[cron.check_repo_stats]
RUN_AT_START = true
SCHEDULE = @every 24h

7
floyd/terraform/gitea/container.tf

@ -9,6 +9,11 @@ resource "docker_container" "gitea" {
container_path = "/data/"
}
upload {
content = data.template_file.gitea.rendered
file = "/data/gitea/conf/app.ini"
}
# https://tools.ietf.org/html/rfc5966
# mentions to support TCP for DNS.
ports {
@ -31,7 +36,7 @@ resource "docker_container" "gitea" {
}
networks_advanced {
name = "caddy"
name = var.caddy_network_public
}
restart = "unless-stopped"

9
floyd/terraform/gitea/data.tf

@ -0,0 +1,9 @@
data "template_file" "gitea" {
template = file("${path.module}/conf/app.ini.tpl")
vars = {
gitea_secret_key = var.gitea_secret_key
gitea_internal_token = var.gitea_internal_token
gitea_lfs_jwt_secret = var.gitea_lfs_jwt_secret
gitea_oauth2_jwt_secret = var.gitea_oauth2_jwt_secret
}
}

8
floyd/terraform/gitea/variables.tf

@ -1,3 +1,9 @@
variable "ips" {
type = map
}
}
variable "gitea_secret_key" {}
variable "gitea_internal_token" {}
variable "gitea_lfs_jwt_secret" {}
variable "gitea_oauth2_jwt_secret" {}
variable "caddy_network_public" {}

30
floyd/terraform/main.tf

@ -6,24 +6,31 @@ module "hydra-infra" {
}
module "pihole" {
source = "./pihole"
ips = var.ips
source = "./pihole"
ips = var.ips
caddy_network_internal = module.caddy.caddy_network_internal
providers = {
docker = docker.floyd
}
}
module "unbound" {
source = "./unbound"
ips = var.ips
source = "./unbound"
ips = var.ips
caddy_network_internal = module.caddy.caddy_network_internal
providers = {
docker = docker.floyd
}
}
module "gitea" {
source = "./gitea"
ips = var.ips
source = "./gitea"
ips = var.ips
gitea_secret_key = var.gitea_secret_key
gitea_internal_token = var.gitea_internal_token
gitea_lfs_jwt_secret = var.gitea_lfs_jwt_secret
gitea_oauth2_jwt_secret = var.gitea_oauth2_jwt_secret
caddy_network_public = module.caddy.caddy_network_public
providers = {
docker = docker.floyd
}
@ -48,8 +55,9 @@ module "caddy" {
}
module "monitoring" {
source = "./monitoring"
ips = var.ips
source = "./monitoring"
ips = var.ips
caddy_network_internal = module.caddy.caddy_network_internal
providers = {
docker = docker.floyd
}
@ -60,6 +68,7 @@ module "firefly" {
ips = var.ips
firefly_postgres_password = var.firefly_postgres_password
firefly_app_key = var.firefly_app_key
caddy_network_internal = module.caddy.caddy_network_internal
providers = {
docker = docker.floyd
}
@ -75,8 +84,9 @@ module "firefly" {
module "syncthing" {
source = "./syncthing"
ips = var.ips
source = "./syncthing"
ips = var.ips
caddy_network_internal = module.caddy.caddy_network_internal
providers = {
docker = docker.floyd
}

2
floyd/terraform/monitoring/grafana.tf

@ -21,7 +21,7 @@ resource "docker_container" "grafana" {
}
networks_advanced {
name = "caddy"
name = var.caddy_network_internal
}
user = "root"

3
floyd/terraform/monitoring/variables.tf

@ -1,3 +1,4 @@
variable "ips" {
type = map
}
}
variable "caddy_network_internal" {}

2
floyd/terraform/pihole/container.tf

@ -57,7 +57,7 @@ resource "docker_container" "pihole" {
}
networks_advanced {
name = "caddy"
name = var.caddy_network_internal
}
restart = "unless-stopped"

3
floyd/terraform/pihole/variables.tf

@ -1,3 +1,4 @@
variable "ips" {
type = map
}
}
variable "caddy_network_internal" {}

2
floyd/terraform/syncthing/container.tf

@ -35,7 +35,7 @@ resource "docker_container" "syncthing" {
}
networks_advanced {
name = "caddy"
name = var.caddy_network_internal
}
env = [

1
floyd/terraform/syncthing/variables.tf

@ -1,3 +1,4 @@
variable "ips" {
type = map
}
variable "caddy_network_internal" {}

3
floyd/terraform/unbound/variables.tf

@ -1,3 +1,4 @@
variable "ips" {
type = map
}
}
variable "caddy_network_internal" {}

24
floyd/terraform/variables.tf

@ -5,6 +5,9 @@ variable "ips" {
tailscale_floyd = "100.101.134.59"
tailscale_parvaaz = "100.94.241.54"
eth1 = "10.139.120.134"
anchor = "10.47.0.5"
floating = "139.59.55.13"
public = "134.209.159.175"
}
}
@ -27,3 +30,24 @@ variable "firefly_app_key" {
type = string
description = "32Char token uniquely generated to encrypt Firefly Sessions and Attachments"
}
variable "gitea_secret_key" {
type = string
description = "Global secret key"
}
variable "gitea_internal_token" {
type = string
description = "Secret used to validate communication within Gitea binary"
}
variable "gitea_lfs_jwt_secret" {
type = string
description = "LFS authentication secret"
}
variable "gitea_oauth2_jwt_secret" {
type = string
description = "OAuth2 authentication secret for access and refresh tokens"
}

Loading…
Cancel
Save