Compare commits

...

17 Commits

Author SHA1 Message Date
Nemo ecaacaf3a5 [transmission] Upgrade configuration 2022-12-26 12:51:44 +05:30
Nemo af20a4efb9 [traefik] Upgrade 1.17 conf for tatooine.club 2022-12-26 12:51:30 +05:30
Nemo 18f32691f6 [media] Upgrade subnet size 2022-12-26 12:50:54 +05:30
Nemo eb1c40df6e [kaarana] Unused, but upgraded 2022-12-26 12:50:43 +05:30
Nemo 4b6b07c09a [db] Increase connections for mastodon 2022-12-26 12:50:31 +05:30
Nemo 48b93bf25d GPU and provider upgrades.
Applied to jupyter container
2022-12-26 12:49:52 +05:30
Nemo 8a894175a9 [miniflux] Upgrade to 2.0.39 2022-12-26 12:49:23 +05:30
Nemo 30fd75ae52 [main] Mastodon added 2022-12-26 12:49:13 +05:30
Nemo 9f6048a971 [gitea] Upgrades to 1.17 2022-12-26 12:48:59 +05:30
Nemo 442ec2d5d3 [traefik] New tatooine.club keys
Had to disable redirect
2022-12-26 12:48:34 +05:30
Nemo 9f04ebe4c4 [rss-bridge] Switch to upstream
Most of my changes are merged: captnemo.in/rss/
So I can switch to tracking upstream instead
2022-12-26 12:48:03 +05:30
Nemo 587b6258bb Mastodon: Initial Configuration
This is missing some secrets, will commit those later
2022-12-26 12:47:48 +05:30
Nemo da4fc888ef [WIP] Traefik v2 migration 2022-12-26 12:46:31 +05:30
Nemo 10ba57590b Switch from latest -> image_id
former is deprecated
2022-12-26 12:46:09 +05:30
Nemo 8a0ead5bb0 [postgres] Increase memory for mastodon 2022-12-26 12:44:55 +05:30
Nemo 36996a0ace Increase network size for pg to add mastodon containers 2022-12-26 12:44:03 +05:30
Nemo 24079f41a2 Upgrade Terraform version 2022-12-26 12:43:47 +05:30
40 changed files with 343 additions and 74 deletions

View File

@ -1 +1 @@
1.0.9
1.3.6

View File

@ -4,8 +4,7 @@ resource "docker_network" "postgres" {
internal = true
ipam_config {
subnet = "172.20.0.8/29"
subnet = "172.20.0.8/27"
gateway = "172.20.0.9"
}
}

View File

@ -1,6 +1,14 @@
resource "docker_container" "postgres" {
name = "postgres"
image = docker_image.postgres.latest
image = docker_image.postgres.image_id
command = [
"postgres",
"-c",
"max_connections=250",
"-c",
"shared_buffers=500MB",
]
volumes {
volume_name = docker_volume.pg_data.name
@ -23,8 +31,8 @@ resource "docker_container" "postgres" {
ip = var.ips["tun0"]
}
memory = 256
memory_swap = 512
memory = 2048
memory_swap = 2048
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true

View File

@ -0,0 +1,72 @@
# Web must be converted manually. See https://docs.traefik.io/operations/api/
# Redirect on entry point "http" must be converted manually. See https://docs.traefik.io/middlewares/http/redirectscheme/
# TLS on entry point "https" must be converted manually. See https://docs.traefik.io/routing/routers/#tls
# The domain (bb8.fun) defined in the Docker provider must be converted manually. See https://docs.traefik.io/providers/docker/#defaultrule
# All the elements related to dynamic configuration (backends, frontends, ...) must be converted manually. See https://docs.traefik.io/routing/overview/
# The entry point (https) defined in the ACME configuration must be converted manually. See https://docs.traefik.io/routing/routers/#certresolver
[global]
sendAnonymousUsage = true
[tls.options]
[tls.options.default]
minVersion = "VersionTLS12"
[[tls.certificates]]
certFile = "/etc/traefik/git.captnemo.in.crt"
keyFile = "/etc/traefik/git.captnemo.in.key"
[[tls.certificates]]
certFile = "/etc/traefik/rss.captnemo.in.crt"
keyFile = "/etc/traefik/rss.captnemo.in.key"
# This forces port 8080
[api]
# https://doc.traefik.io/traefik/operations/dashboard/#insecure-mode
dashboard = true
# Enable the API in insecure mode, which means that the API will be available directly on the entryPoint named traefik.
insecure = true
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.http]
[entryPoints.https]
address = ":443"
[entryPoints.https.http]
[providers]
providersThrottleDuration = "2s"
[providers.docker]
watch = true
endpoint = "unix:///var/run/docker.sock"
swarmModeRefreshSeconds = "15s"
httpClientTimeout = "0s"
[providers.file]
[log]
[accessLog]
bufferingSize = 0
[certificatesResolvers]
[certificatesResolvers.default]
[certificatesResolvers.default.acme]
email = "acme@captnemo.in"
storage = "/acme/acme.json"
certificatesDuration = 0
[certificatesResolvers.default.acme.dnsChallenge]
provider = "cloudflare"
delayBeforeCheck = "2m0s"
[certificatesResolvers.default.acme.httpChallenge]
entryPoint = "http"
[certificatesResolvers.t]
[certificatesResolvers.t.acme]
email = "acme@captnemo.in"
storage = "/acme/acme.json"
[certificatesResolvers.myresolver.acme.tlsChallenge]
[http.middlewares]
[http.middlewares.test-redirectscheme.redirectScheme]
scheme = "https"
permanent = true

View File

@ -0,0 +1,26 @@
global:
sendAnonymousUsage: true
entryPoints:
http:
address: :80
https:
address: :443
providers:
providersThrottleDuration: 2s
docker:
watch: true
endpoint: unix:///var/run/docker.sock
swarmModeRefreshSeconds: 15s
file: {}
log: {}
accessLog: {}
certificatesResolvers:
default:
acme:
email: acme@captnemo.in
storage: /acme/acme.json
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 2m0s
httpChallenge:
entryPoint: http

View File

@ -6,10 +6,6 @@ checkNewVersion = false
[accessLog]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
# This is required for ACME support
@ -20,6 +16,9 @@ checkNewVersion = false
[[entryPoints.https.tls.certificates]]
certFile = "/etc/traefik/rss.captnemo.in.crt"
keyFile = "/etc/traefik/rss.captnemo.in.key"
[[entryPoints.https.tls.certificates]]
certFile = "/etc/traefik/tatooine.club.crt"
keyFile = "/etc/traefik/tatooine.club.key"
[docker]
# Make sure you mount this as readonly

View File

@ -8,7 +8,7 @@ data "docker_registry_image" "gotviz" {
# }
# resource "docker_container" "gotviz" {
# name = "gotviz"
# image = "${docker_image.gotviz.latest}"
# image = "${docker_image.gotviz.image_id}"
# labels = "${merge(
# local.traefik_common_labels, map(
# "traefik.port", 8080,

View File

@ -1,6 +1,6 @@
# resource "docker_container" "lychee" {
# name = "lychee"
# image = "${docker_image.lychee.latest}"
# image = "${docker_image.lychee.image_id}"
# restart = "unless-stopped"
# destroy_grace_seconds = 10
# must_run = true

View File

@ -1,18 +1,21 @@
resource "docker_container" "traefik" {
name = "traefik"
image = docker_image.traefik17.latest
image = docker_image.traefik17.image_id
# Admin Backend
ports {
internal = 1111
external = 1111
ip = var.ips["eth0"]
labels {
label = "traefik.enable"
value = "true"
}
ports {
internal = 1111
external = 1111
ip = var.ips["tun0"]
labels {
label = "traefik.http.routers.api.rule"
value = "Host('traefik.in.bb8.fun')"
}
labels {
label = "traefik.http.routers.api.service"
value = "api@internal"
}
# Local Web Server
@ -61,6 +64,20 @@ resource "docker_container" "traefik" {
file = "/etc/traefik/git.captnemo.in.key"
}
upload {
content = file(
"/home/nemo/projects/personal/certs/lego/certificates/tatooine.club.key",
)
file = "/etc/traefik/tatooine.club.key"
}
upload {
content = file(
"/home/nemo/projects/personal/certs/lego/certificates/tatooine.club.crt",
)
file = "/etc/traefik/tatooine.club.crt"
}
upload {
content = file(
"/home/nemo/projects/personal/certs/rss.captnemo.in/fullchain.pem",

View File

@ -7,7 +7,7 @@ locals {
resource "docker_container" "ubooquity" {
name = "ubooquity"
image = docker_image.ubooquity.latest
image = docker_image.ubooquity.image_id
restart = "unless-stopped"
destroy_grace_seconds = 30

View File

@ -1,6 +1,6 @@
# https://github.com/go-gitea/gitea/releases
data "docker_registry_image" "gitea" {
name = "gitea/gitea:1.16"
name = "gitea/gitea:1.17"
}
data "docker_registry_image" "redis" {

View File

@ -7,7 +7,7 @@ locals {
resource "docker_container" "gitea" {
name = "gitea"
image = docker_image.gitea.latest
image = docker_image.gitea.image_id
dynamic "labels" {
for_each = local.l

View File

@ -1,6 +1,6 @@
resource "docker_container" "redis" {
name = "gitea-redis"
image = docker_image.redis.latest
image = docker_image.redis.image_id
volumes {
host_path = "/mnt/xwing/cache/gitea"

View File

@ -1,12 +1,16 @@
# module "jupyter" {
# name = "jupyter"
# source = "modules/container"
# image = "jupyter/tensorflow-notebook"
# ports = [
# {
# internal = 8888
# external = 1112
# ip = "${var.ips["tun0"]}"
# },
# ]
# }
module "jupyter" {
name = "jupyter"
source = "./modules/container"
image = "jupyter/scipy-notebook"
resource = {
memory = 1024
memory_swap = 4096
}
web = {
expose = "true"
host = "j.${var.root-domain}"
port = 8888
}
networks = ["bridge"]
gpu = true
}

View File

@ -18,7 +18,7 @@ resource "docker_network" "kaarana-db" {
// Run a small mySQL container in this subnet
resource "docker_container" "mysql" {
image = docker_image.db.latest
image = docker_image.db.image_id
name = "kaarana-mariadb"
restart = "always"
must_run = true

View File

@ -12,7 +12,7 @@ resource "docker_network" "traefik" {
resource "docker_container" "traefik" {
name = "traefik"
image = docker_image.traefik.latest
image = docker_image.traefik.image_id
# Do not offer HTTP2
# https://community.containo.us/t/traefikv2-http-2-0/1199

View File

@ -1,5 +1,5 @@
resource "docker_container" "wp" {
image = docker_image.wp.latest
image = docker_image.wp.image_id
name = "kaarana-wordpress"
restart = "always"

View File

@ -68,7 +68,8 @@ module "media" {
domain = "bb8.fun"
traefik-labels = var.traefik-common-labels
ips = var.ips
traefik-network-id = module.docker.traefik-network-id
# ToDO: Change this to lookup
traefik-network-id = "ffc1e366849e"
lastfm_api_key = data.pass_password.navidrome-lastfm-api-key.password
lastfm_secret = data.pass_password.navidrome-lastfm-secret.password
spotify_id = data.pass_password.navidrome-spotify-id.password
@ -90,6 +91,11 @@ module "digitalocean" {
source = "./digitalocean"
}
module "mastodon" {
source = "./mastodon"
db-password = data.pass_password.mastodon-db-password.password
}
// Used to force access to ISP related resources
# module "tinyproxy" {
# source = "./tinyproxy"

18
mastodon/db.tf Normal file
View File

@ -0,0 +1,18 @@
module "mastodon-redis" {
name = "mastodon-redis"
source = "../modules/container"
image = "redis:alpine"
networks = ["mastodon"]
keep_image = true
resource = {
memory = 256
memory_swap = 256
}
}
module "mastodon-db" {
source = "../modules/postgres"
name = "mastodon"
password = var.db-password
}

94
mastodon/main.tf Normal file
View File

@ -0,0 +1,94 @@
module "mastodon-web" {
name = "mastodon-web"
source = "../modules/container"
image = "tootsuite/mastodon:v4.0"
networks = ["mastodon", "traefik", "external", "postgres"]
env = concat(local.env,[
"MAX_THREADS=4",
"WEB_CONCURRENCY=5"
])
command = [
"bash",
"-c",
"rm -f /mastodon/tmp/pids/server.pid; bundle exec rake db:migrate; bundle exec rails s -p 3000"
]
volumes = [{
container_path = "/mastodon/public/system"
host_path = "/mnt/xwing/data/mastodon"
}]
web = {
expose = "true"
host = "tatooine.club"
port = 3000
}
resource = {
memory = 1024
memory_swap = 1024
}
}
module "mastodon-streaming" {
name = "mastodon-streaming"
source = "../modules/container"
image = "tootsuite/mastodon:v4.0"
# 24 threads for Streaming
env = concat(local.env,[
"DB_POOL=8",
"STREAMING_CLUSTER_NUM=4"
])
networks = ["postgres", "external", "mastodon"]
command = [
"node",
"./streaming"
]
web = {
expose = "false"
}
resource = {
memory = 1024
memory_swap = 1024
}
}
module "mastodon-sidekiq" {
name = "mastodon-sidekiq"
source = "../modules/container"
image = "tootsuite/mastodon:v4.0"
env = concat(local.env,[
"DB_POOL=50"
])
web = {
expose = "false"
}
networks = ["postgres", "external", "mastodon"]
command = [
"bundle",
"exec",
"sidekiq"
]
volumes = [{
container_path = "/mastodon/public/system"
host_path = "/mnt/xwing/data/mastodon"
}]
resource = {
memory = 1024
memory_swap = 1024
}
}

5
mastodon/network.tf Normal file
View File

@ -0,0 +1,5 @@
resource "docker_network" "mastodon" {
name = "mastodon"
driver = "bridge"
internal = true
}

10
mastodon/provider.tf Normal file
View File

@ -0,0 +1,10 @@
terraform {
required_providers {
postgresql = {
source = "cyrilgdn/postgresql"
}
docker = {
source = "kreuzwerker/docker"
}
}
}

3
mastodon/vars.tf Normal file
View File

@ -0,0 +1,3 @@
variable "db-password" {
type = string
}

View File

@ -10,17 +10,17 @@
"bind-address-ipv6": "::",
"blocklist-enabled": true,
"blocklist-url": "http://john.bitsurge.net/public/biglist.p2p.gz",
"cache-size-mb": 16,
"dht-enabled": false,
"cache-size-mb": 256,
"dht-enabled": true,
"download-dir": "/downloads",
"download-queue-enabled": true,
"download-queue-enabled": false,
"download-queue-size": 5,
"encryption": 1,
"idle-seeding-limit": 30,
"idle-seeding-limit-enabled": false,
"incomplete-dir": "/downloads",
"incomplete-dir-enabled": true,
"lpd-enabled": false,
"lpd-enabled": true,
"message-level": 2,
"peer-congestion-algorithm": "",
"peer-id-ttl-hours": 6,
@ -35,10 +35,10 @@
"port-forwarding-enabled": true,
"preallocation": 1,
"prefetch-enabled": true,
"queue-stalled-enabled": true,
"queue-stalled-enabled": false,
"queue-stalled-minutes": 30,
"ratio-limit": 0.2,
"ratio-limit-enabled": false,
"ratio-limit": 1.2,
"ratio-limit-enabled": true,
"rename-partial-files": true,
"rpc-host-whitelist": "transmission.bb8.fun,transmission",
"rpc-host-whitelist-enabled": true,
@ -51,19 +51,19 @@
"rpc-username": "",
"rpc-whitelist": "127.0.0.1",
"rpc-whitelist-enabled": false,
"scrape-paused-torrents-enabled": true,
"scrape-paused-torrents-enabled": false,
"script-torrent-done-enabled": false,
"script-torrent-done-filename": "",
"seed-queue-enabled": false,
"seed-queue-size": 10,
"seed-queue-enabled": true,
"seed-queue-size": 50,
"speed-limit-down": 100,
"speed-limit-down-enabled": false,
"speed-limit-up": 50,
"speed-limit-up-enabled": true,
"speed-limit-up-enabled": false,
"start-added-torrents": true,
"trash-original-torrent-files": false,
"umask": 2,
"upload-slots-per-torrent": 14,
"upload-slots-per-torrent": 10,
"utp-enabled": true,
"watch-dir": "/watch",
"watch-dir-enabled": true

View File

@ -9,7 +9,7 @@ locals {
resource "docker_container" "emby" {
name = "emby"
image = docker_image.emby.latest
image = docker_image.emby.image_id
volumes {
host_path = "/mnt/xwing/config/emby"
@ -36,10 +36,7 @@ resource "docker_container" "emby" {
destroy_grace_seconds = 10
must_run = true
devices {
host_path = "/dev/dri"
container_path = "/dev/dri"
}
gpus = "all"
# Running as lounge:tatooine
env = [

View File

@ -16,7 +16,7 @@ locals {
resource "docker_container" "lidarr" {
name = "lidarr"
image = docker_image.lidarr.latest
image = docker_image.lidarr.image_id
dynamic "labels" {
for_each = local.lidarr_labels

View File

@ -3,8 +3,7 @@ resource "docker_network" "media" {
driver = "bridge"
ipam_config {
subnet = "172.18.0.0/16"
subnet = "172.18.0.0/24"
gateway = "172.18.0.1"
}
}

View File

@ -7,7 +7,7 @@ locals {
resource "docker_container" "transmission" {
name = "transmission"
image = docker_image.transmission.latest
image = docker_image.transmission.image_id
dynamic "labels" {
for_each = local.transmission_labels

View File

@ -1,7 +1,7 @@
module "miniflux-container" {
name = "miniflux"
source = "./modules/container"
image = "miniflux/miniflux:2.0.34"
image = "miniflux/miniflux:2.0.39"
web = {
expose = true

View File

@ -1,6 +1,6 @@
resource "docker_container" "container" {
name = var.name
image = docker_image.image.latest
image = docker_image.image.image_id
dynamic "ports" {
for_each = var.ports
@ -19,6 +19,8 @@ resource "docker_container" "container" {
network_mode = var.network_mode
gpus = var.gpu ? "all" : ""
dynamic "capabilities" {
for_each = [var.capabilities]
content {

View File

@ -1,9 +1,7 @@
terraform {
experiments = [module_variable_optional_attrs]
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "2.15.0"
}
}
}

View File

@ -135,3 +135,8 @@ variable "uploads" {
default = []
}
variable "gpu" {
type = bool
default = false
}

View File

@ -12,6 +12,6 @@ resource "docker_image" "image" {
}
output "image" {
value = docker_image.image.latest
value = docker_image.image.image_id
}

View File

@ -1,6 +1,6 @@
resource "docker_container" "redis" {
name = "outline-redis"
image = "${docker_image.redis.latest}"
image = "${docker_image.redis.image_id}"
volumes {
host_path = "/mnt/xwing/cache/outline"

View File

@ -4,7 +4,7 @@ data "docker_registry_image" "act-exporter" {
resource "docker_container" "act-exporter" {
name = "act-exporter"
image = docker_image.act-exporter.latest
image = docker_image.act-exporter.image_id
entrypoint = ["/usr/local/bin/node", "server.js"]

View File

@ -1,6 +1,6 @@
resource "docker_container" "prometheus" {
name = "prometheus"
image = docker_image.prometheus.latest
image = docker_image.prometheus.image_id
# prometheus:prometheus
user = "985:983"

View File

@ -31,6 +31,7 @@ provider "pass" {
terraform {
required_version = ">= 1.3.0"
required_providers {
pass = {
source = "camptocamp/pass"
@ -46,6 +47,7 @@ terraform {
}
docker = {
source = "kreuzwerker/docker"
version = "~> 2.23"
}
}
}

View File

@ -2,7 +2,7 @@ module "rss-bridge" {
name = "rss-bridge"
source = "./modules/container"
image = "captn3m0/rss-bridge:develop"
image = "ghcr.io/rss-bridge/rss-bridge:latest"
resource = {
memory = 256
@ -14,7 +14,7 @@ module "rss-bridge" {
host = "rss-bridge.${var.root-domain}"
}
networks = ["external"]
networks = ["bridge"]
volumes = [
{

View File

@ -176,3 +176,8 @@ data "pass_password" "navidrome-spotify-secret" {
path = "Nebula/navidrome-spotify-secret"
}
data "pass_password" "mastodon-db-password" {
path = "Nebula/MASTODON_DB_PASSWORD"
}

View File

@ -9,7 +9,7 @@ resource "docker_image" "timemachine" {
resource "docker_container" "timemachine" {
name = "timemachine"
image = docker_image.timemachine.latest
image = docker_image.timemachine.image_id
volumes {
host_path = "/mnt/xwing/data/timemachine"