Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Nemo | 853d77e0bf |
|
@ -3,7 +3,6 @@
|
||||||
.terraform
|
.terraform
|
||||||
*.tfstate
|
*.tfstate
|
||||||
*.tfstate.backup
|
*.tfstate.backup
|
||||||
*.terraform.lock.hcl
|
|
||||||
*.out
|
*.out
|
||||||
*.backup
|
*.backup
|
||||||
secrets
|
secrets
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.3.6
|
0.12.30
|
||||||
|
|
18
HACKING.md
18
HACKING.md
|
@ -1,18 +0,0 @@
|
||||||
# Hacking on the thing
|
|
||||||
|
|
||||||
Generate certs as per:
|
|
||||||
|
|
||||||
https://gist.github.com/captn3m0/2c2e723b2dcd5cdaad733aad12be59a2
|
|
||||||
|
|
||||||
Copy ca.pem, server-cert.pem, server-key.pem to /etc/docker/certs.
|
|
||||||
|
|
||||||
Make sure server-key.pem is 0400 in permissions.
|
|
||||||
|
|
||||||
Run `systemctl edit docker`
|
|
||||||
|
|
||||||
````
|
|
||||||
/etc/systemd/system/docker.service.d/override.conf
|
|
||||||
[Service]
|
|
||||||
ExecStart=
|
|
||||||
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/certs/ca.pem --tlscert=/etc/docker/certs/server-cert.pem --tlskey=/etc/docker/certs/server-key.pem -H=0.0.0.0:2376 -H unix:///var/run/docker.sock
|
|
||||||
````
|
|
|
@ -42,6 +42,7 @@ Currently running the following (all links are to the `store.docker.com` links f
|
||||||
| image | tag | module/link |
|
| image | tag | module/link |
|
||||||
| -------------------------------- | ---------- | ---------------------------------------------------- |
|
| -------------------------------- | ---------- | ---------------------------------------------------- |
|
||||||
| captn3m0/opml-gen | latest | https://opml.bb8.fun |
|
| captn3m0/opml-gen | latest | https://opml.bb8.fun |
|
||||||
|
| captn3m0/prometheus-act-exporter | latest | https://git.captnemo.in/nemo/prometheus-act-exporter |
|
||||||
| captn3m0/rss-bridge | latest | https://github.com/RSS-Bridge/rss-bridge |
|
| captn3m0/rss-bridge | latest | https://github.com/RSS-Bridge/rss-bridge |
|
||||||
| captn3m0/speedtest-exporter | alpine | https://github.com/stefanwalther/speedtest-exporter |
|
| captn3m0/speedtest-exporter | alpine | https://github.com/stefanwalther/speedtest-exporter |
|
||||||
| emby/embyserver | latest | https://emby.media |
|
| emby/embyserver | latest | https://emby.media |
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,8 @@ resource "docker_network" "postgres" {
|
||||||
internal = true
|
internal = true
|
||||||
|
|
||||||
ipam_config {
|
ipam_config {
|
||||||
subnet = "172.20.0.8/27"
|
subnet = "172.20.0.8/29"
|
||||||
gateway = "172.20.0.9"
|
gateway = "172.20.0.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
resource "docker_container" "postgres" {
|
resource "docker_container" "postgres" {
|
||||||
name = "postgres"
|
name = "postgres"
|
||||||
image = docker_image.postgres.image_id
|
image = docker_image.postgres.latest
|
||||||
|
|
||||||
command = [
|
|
||||||
"postgres",
|
|
||||||
"-c",
|
|
||||||
"max_connections=250",
|
|
||||||
"-c",
|
|
||||||
"shared_buffers=500MB",
|
|
||||||
]
|
|
||||||
|
|
||||||
volumes {
|
volumes {
|
||||||
volume_name = docker_volume.pg_data.name
|
volume_name = docker_volume.postgres_volume.name
|
||||||
container_path = "/var/lib/postgresql/data"
|
container_path = "/var/lib/postgresql/data"
|
||||||
read_only = false
|
host_path = docker_volume.postgres_volume.mountpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is so that other host-only services can share this
|
// This is so that other host-only services can share this
|
||||||
|
@ -31,8 +23,7 @@ resource "docker_container" "postgres" {
|
||||||
ip = var.ips["tun0"]
|
ip = var.ips["tun0"]
|
||||||
}
|
}
|
||||||
|
|
||||||
memory = 2048
|
memory = 256
|
||||||
memory_swap = 2048
|
|
||||||
restart = "unless-stopped"
|
restart = "unless-stopped"
|
||||||
destroy_grace_seconds = 10
|
destroy_grace_seconds = 10
|
||||||
must_run = true
|
must_run = true
|
||||||
|
@ -56,3 +47,4 @@ data "docker_registry_image" "postgres" {
|
||||||
data "docker_network" "bridge" {
|
data "docker_network" "bridge" {
|
||||||
name = "bridge"
|
name = "bridge"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
variable "postgres-version" {
|
variable "postgres-version" {
|
||||||
description = "postgres version to use for fetching the docker image"
|
description = "postgres version to use for fetching the docker image"
|
||||||
default = "14-alpine"
|
default = "10-alpine"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "ips" {
|
variable "ips" {
|
||||||
|
@ -9,3 +9,4 @@ variable "ips" {
|
||||||
|
|
||||||
variable "postgres-root-password" {
|
variable "postgres-root-password" {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
resource "docker_volume" "pg_data" {
|
resource "docker_volume" "postgres_volume" {
|
||||||
name = "pg_data"
|
name = "postgres_volume"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
resource "digitalocean_droplet" "sydney" {
|
resource "digitalocean_droplet" "sydney" {
|
||||||
image = "??"
|
image = ""
|
||||||
name = "sydney.captnemo.in"
|
name = "sydney.captnemo.in"
|
||||||
region = "blr1"
|
region = "blr1"
|
||||||
size = "s-1vcpu-2gb"
|
size = "s-1vcpu-2gb"
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -1,72 +0,0 @@
|
||||||
# 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
|
|
|
@ -1,26 +0,0 @@
|
||||||
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
|
|
|
@ -6,6 +6,10 @@ checkNewVersion = false
|
||||||
[accessLog]
|
[accessLog]
|
||||||
|
|
||||||
[entryPoints]
|
[entryPoints]
|
||||||
|
[entryPoints.http]
|
||||||
|
address = ":80"
|
||||||
|
[entryPoints.http.redirect]
|
||||||
|
entryPoint = "https"
|
||||||
[entryPoints.https]
|
[entryPoints.https]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
# This is required for ACME support
|
# This is required for ACME support
|
||||||
|
@ -16,9 +20,6 @@ checkNewVersion = false
|
||||||
[[entryPoints.https.tls.certificates]]
|
[[entryPoints.https.tls.certificates]]
|
||||||
certFile = "/etc/traefik/rss.captnemo.in.crt"
|
certFile = "/etc/traefik/rss.captnemo.in.crt"
|
||||||
keyFile = "/etc/traefik/rss.captnemo.in.key"
|
keyFile = "/etc/traefik/rss.captnemo.in.key"
|
||||||
[[entryPoints.https.tls.certificates]]
|
|
||||||
certFile = "/etc/traefik/tatooine.club.crt"
|
|
||||||
keyFile = "/etc/traefik/tatooine.club.key"
|
|
||||||
|
|
||||||
[docker]
|
[docker]
|
||||||
# Make sure you mount this as readonly
|
# Make sure you mount this as readonly
|
||||||
|
@ -37,6 +38,33 @@ checkNewVersion = false
|
||||||
# Since I can't apply a authentication
|
# Since I can't apply a authentication
|
||||||
# on this yet
|
# on this yet
|
||||||
|
|
||||||
|
[backends.elibsrv]
|
||||||
|
[backends.elibsrv.servers.default]
|
||||||
|
url = "http://elibsrv.captnemo.in:90"
|
||||||
|
|
||||||
|
[backends.scan]
|
||||||
|
[backends.scan.servers.default]
|
||||||
|
url = "http://scan.in.bb8.fun:90"
|
||||||
|
|
||||||
|
[frontends]
|
||||||
|
|
||||||
|
[frontends.scan]
|
||||||
|
backend = "scan"
|
||||||
|
[frontends.scan.headers]
|
||||||
|
SSLRedirect = true
|
||||||
|
SSLTemporaryRedirect = true
|
||||||
|
STSSeconds = 2592000
|
||||||
|
FrameDeny = true
|
||||||
|
ContentTypeNosniff = true
|
||||||
|
BrowserXssFilter = true
|
||||||
|
ReferrerPolicy = "no-referrer"
|
||||||
|
[frontends.scan.headers.customresponseheaders]
|
||||||
|
X-Powered-By = "Allomancy"
|
||||||
|
Server = "BlackBox"
|
||||||
|
X-Clacks-Overhead = "GNU Terry Pratchett"
|
||||||
|
[frontends.scan.routes.domain]
|
||||||
|
rule = "Host:scan.bb8.fun"
|
||||||
|
|
||||||
[web]
|
[web]
|
||||||
address = ":1111"
|
address = ":1111"
|
||||||
readOnly = true
|
readOnly = true
|
||||||
|
@ -57,8 +85,7 @@ acmelogging = true
|
||||||
|
|
||||||
[acme.dnsChallenge]
|
[acme.dnsChallenge]
|
||||||
provider = "cloudflare"
|
provider = "cloudflare"
|
||||||
delayBeforeCheck = 120
|
delayBeforeCheck = 30
|
||||||
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
|
|
||||||
|
|
||||||
# Primary 2 wildcard certs
|
# Primary 2 wildcard certs
|
||||||
[[acme.domains]]
|
[[acme.domains]]
|
||||||
|
|
|
@ -8,7 +8,7 @@ data "docker_registry_image" "gotviz" {
|
||||||
# }
|
# }
|
||||||
# resource "docker_container" "gotviz" {
|
# resource "docker_container" "gotviz" {
|
||||||
# name = "gotviz"
|
# name = "gotviz"
|
||||||
# image = "${docker_image.gotviz.image_id}"
|
# image = "${docker_image.gotviz.latest}"
|
||||||
# labels = "${merge(
|
# labels = "${merge(
|
||||||
# local.traefik_common_labels, map(
|
# local.traefik_common_labels, map(
|
||||||
# "traefik.port", 8080,
|
# "traefik.port", 8080,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# resource "docker_container" "lychee" {
|
# resource "docker_container" "lychee" {
|
||||||
# name = "lychee"
|
# name = "lychee"
|
||||||
# image = "${docker_image.lychee.image_id}"
|
# image = "${docker_image.lychee.latest}"
|
||||||
# restart = "unless-stopped"
|
# restart = "unless-stopped"
|
||||||
# destroy_grace_seconds = 10
|
# destroy_grace_seconds = 10
|
||||||
# must_run = true
|
# must_run = true
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +1,18 @@
|
||||||
resource "docker_container" "traefik" {
|
resource "docker_container" "traefik" {
|
||||||
name = "traefik"
|
name = "traefik"
|
||||||
image = docker_image.traefik17.image_id
|
image = docker_image.traefik17.latest
|
||||||
|
|
||||||
|
# Admin Backend
|
||||||
labels {
|
ports {
|
||||||
label = "traefik.enable"
|
internal = 1111
|
||||||
value = "true"
|
external = 1111
|
||||||
|
ip = var.ips["eth0"]
|
||||||
}
|
}
|
||||||
|
|
||||||
labels {
|
ports {
|
||||||
label = "traefik.http.routers.api.rule"
|
internal = 1111
|
||||||
value = "Host('traefik.in.bb8.fun')"
|
external = 1111
|
||||||
}
|
ip = var.ips["tun0"]
|
||||||
|
|
||||||
labels {
|
|
||||||
label = "traefik.http.routers.api.service"
|
|
||||||
value = "api@internal"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Local Web Server
|
# Local Web Server
|
||||||
|
@ -64,20 +61,6 @@ resource "docker_container" "traefik" {
|
||||||
file = "/etc/traefik/git.captnemo.in.key"
|
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 {
|
upload {
|
||||||
content = file(
|
content = file(
|
||||||
"/home/nemo/projects/personal/certs/rss.captnemo.in/fullchain.pem",
|
"/home/nemo/projects/personal/certs/rss.captnemo.in/fullchain.pem",
|
||||||
|
@ -110,16 +93,18 @@ resource "docker_container" "traefik" {
|
||||||
|
|
||||||
// `bridge` is auto-connected for now
|
// `bridge` is auto-connected for now
|
||||||
// https://github.com/terraform-providers/terraform-provider-docker/issues/10
|
// https://github.com/terraform-providers/terraform-provider-docker/issues/10
|
||||||
networks_advanced {
|
networks = [
|
||||||
name = "traefik"
|
docker_network.traefik.id,
|
||||||
}
|
data.docker_network.bridge.id,
|
||||||
|
]
|
||||||
networks_advanced {
|
|
||||||
name = "bridge"
|
|
||||||
}
|
|
||||||
|
|
||||||
env = [
|
env = [
|
||||||
"CLOUDFLARE_EMAIL=${var.cloudflare_email}",
|
"CLOUDFLARE_EMAIL=${var.cloudflare_email}",
|
||||||
"CLOUDFLARE_API_KEY=${var.cloudflare_key}",
|
"CLOUDFLARE_API_KEY=${var.cloudflare_key}",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data "docker_network" "bridge" {
|
||||||
|
name = "bridge"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
locals {
|
|
||||||
l = merge(local.traefik_common_labels, {
|
|
||||||
"traefik.port" = 3000
|
|
||||||
"traefik.frontend.rule" = "Host:${var.domain}"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "docker_container" "ubooquity" {
|
resource "docker_container" "ubooquity" {
|
||||||
name = "ubooquity"
|
name = "ubooquity"
|
||||||
image = docker_image.ubooquity.image_id
|
image = docker_image.ubooquity.latest
|
||||||
|
|
||||||
restart = "unless-stopped"
|
restart = "unless-stopped"
|
||||||
destroy_grace_seconds = 30
|
destroy_grace_seconds = 30
|
||||||
|
@ -32,33 +25,24 @@ resource "docker_container" "ubooquity" {
|
||||||
host_path = "/mnt/xwing/media/EBooks/Comics"
|
host_path = "/mnt/xwing/media/EBooks/Comics"
|
||||||
container_path = "/comics"
|
container_path = "/comics"
|
||||||
}
|
}
|
||||||
labels {
|
|
||||||
label = "traefik.enable"
|
labels = {
|
||||||
value = "true"
|
"traefik.enable" = "true"
|
||||||
}
|
"traefik.admin.port" = 2203
|
||||||
labels {
|
"traefik.admin.frontend.rule" = "Host:library.${var.domain}"
|
||||||
label = "traefik.admin.port"
|
# I do not trust the Ubooquity authentication
|
||||||
value = 2203
|
# it does some shady JS encryption
|
||||||
}
|
"traefik.admin.frontend.auth.basic" = var.basic_auth
|
||||||
labels {
|
"traefik.read.port" = 2202
|
||||||
label = "traefik.admin.frontend.rule"
|
"traefik.read.frontend.rule" = "Host:read.${var.domain},comics.${var.domain},books.${var.domain}"
|
||||||
value = "Host:library.${var.domain}"
|
"traefik.read.frontend.headers.SSLTemporaryRedirect" = "true"
|
||||||
}
|
"traefik.read.frontend.headers.STSSeconds" = "2592000"
|
||||||
labels {
|
"traefik.read.frontend.headers.STSIncludeSubdomains" = "false"
|
||||||
label = "traefik.admin.frontend.auth.basic"
|
"traefik.read.frontend.headers.contentTypeNosniff" = "true"
|
||||||
value = var.basic_auth
|
"traefik.read.frontend.headers.browserXSSFilter" = "true"
|
||||||
}
|
"traefik.read.frontend.headers.customResponseHeaders" = var.xpoweredby
|
||||||
labels {
|
"traefik.frontend.headers.customFrameOptionsValue" = var.xfo_allow
|
||||||
label = "traefik.read.port"
|
"traefik.docker.network" = "traefik"
|
||||||
value = 2202
|
|
||||||
}
|
|
||||||
labels {
|
|
||||||
label = "traefik.read.frontend.rule"
|
|
||||||
value = "Host:read.${var.domain},comics.${var.domain},books.${var.domain}"
|
|
||||||
}
|
|
||||||
labels {
|
|
||||||
label = "traefik.docker.network"
|
|
||||||
value = "traefik"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
upload {
|
upload {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
11
elibsrv.tf
11
elibsrv.tf
|
@ -1,5 +1,5 @@
|
||||||
module "elibsrv" {
|
module "elibsrv" {
|
||||||
name = "elibsrv"
|
name = "./elibsrv"
|
||||||
source = "./modules/container"
|
source = "./modules/container"
|
||||||
image = "captn3m0/elibsrv"
|
image = "captn3m0/elibsrv"
|
||||||
|
|
||||||
|
@ -40,6 +40,13 @@ module "elibsrv" {
|
||||||
"elibsrv_thumbheight=320",
|
"elibsrv_thumbheight=320",
|
||||||
"elibsrv_title=Scarif Media Archives",
|
"elibsrv_title=Scarif Media Archives",
|
||||||
]
|
]
|
||||||
networks = ["bridge"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "traefik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "bridge"
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
module "firefox-sync" {
|
||||||
|
name = "firefox-sync"
|
||||||
|
source = "./modules/container"
|
||||||
|
image = "mozilla/syncserver:latest"
|
||||||
|
|
||||||
|
// Default is port 80
|
||||||
|
web = {
|
||||||
|
expose = true
|
||||||
|
port = "5000"
|
||||||
|
host = "firesync.${var.root-domain}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource = {
|
||||||
|
memory = "400"
|
||||||
|
memory_swap = "400"
|
||||||
|
}
|
||||||
|
|
||||||
|
volumes = [
|
||||||
|
{
|
||||||
|
host_path = "/mnt/xwing/data/firefox-sync"
|
||||||
|
container_path = "/data"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
env = [
|
||||||
|
"SYNCSERVER_PUBLIC_URL=https://firesync.${var.root-domain}",
|
||||||
|
"SYNCSERVER_SECRET=${data.pass_password.syncserver_secret.password}",
|
||||||
|
"SYNCSERVER_SQLURI=sqlite:////data/sync.db",
|
||||||
|
"SYNCSERVER_BATCH_UPLOAD_ENABLED=true",
|
||||||
|
"SYNCSERVER_FORCE_WSGI_ENVIRON=true",
|
||||||
|
"PORT=5000",
|
||||||
|
]
|
||||||
|
|
||||||
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "traefik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "bridge"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
; Copy required sections to your own app.ini (default is custom/conf/app.ini)
|
; Copy required sections to your own app.ini (default is custom/conf/app.ini)
|
||||||
; and modify as needed.
|
; and modify as needed.
|
||||||
; See the cheatsheet at https://docs.gitea.io/en-us/config-cheat-sheet/
|
; See the cheatsheet at https://docs.gitea.io/en-us/config-cheat-sheet/
|
||||||
; A sample file with all configuration documented is at https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini
|
; A sample file with all configuration documented is at https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample
|
||||||
|
|
||||||
; App name that shows on every page title
|
; App name that shows on every page title
|
||||||
APP_NAME = Nemo's code
|
APP_NAME = Nemo's code
|
||||||
RUN_MODE = prod
|
RUN_MODE = prod
|
||||||
RUN_USER = git
|
RUN_USER = git
|
||||||
WORK_PATH=/data/gitea
|
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
ROOT = /data/git/repositories
|
ROOT = /data/git/repositories
|
||||||
|
@ -18,10 +17,6 @@ USE_COMPAT_SSH_URI = false
|
||||||
TEMP_PATH = /data/gitea/uploads
|
TEMP_PATH = /data/gitea/uploads
|
||||||
|
|
||||||
[ui]
|
[ui]
|
||||||
|
|
||||||
;; Number of issues that are displayed on one page
|
|
||||||
ISSUE_PAGING_NUM = 20
|
|
||||||
|
|
||||||
; Value of `theme-color` meta tag, used by Android >= 5.0
|
; Value of `theme-color` meta tag, used by Android >= 5.0
|
||||||
; An invalid color like "none" or "disable" will have the default style
|
; An invalid color like "none" or "disable" will have the default style
|
||||||
; More info: https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android
|
; More info: https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android
|
||||||
|
@ -41,11 +36,6 @@ NOTICE_PAGING_NUM = 25
|
||||||
; Number of organization that are showed in one page
|
; Number of organization that are showed in one page
|
||||||
ORG_PAGING_NUM = 50
|
ORG_PAGING_NUM = 50
|
||||||
|
|
||||||
;; Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used.
|
|
||||||
;; A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic).
|
|
||||||
|
|
||||||
ONLY_SHOW_RELEVANT_REPOS = true
|
|
||||||
|
|
||||||
[ui.user]
|
[ui.user]
|
||||||
; Number of repos that are showed in one page
|
; Number of repos that are showed in one page
|
||||||
REPO_PAGING_NUM = 15
|
REPO_PAGING_NUM = 15
|
||||||
|
@ -63,9 +53,6 @@ ENABLE_HARD_LINE_BREAK = false
|
||||||
CUSTOM_URL_SCHEMES = git,magnet,steam,irc,slack
|
CUSTOM_URL_SCHEMES = git,magnet,steam,irc,slack
|
||||||
FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
|
FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
|
||||||
|
|
||||||
;; Enables math inline and block detection
|
|
||||||
ENABLE_MATH = true
|
|
||||||
|
|
||||||
; Define allowed algorithms and their minimum key length (use -1 to disable a type)
|
; Define allowed algorithms and their minimum key length (use -1 to disable a type)
|
||||||
[ssh.minimum_key_sizes]
|
[ssh.minimum_key_sizes]
|
||||||
ED25519 = 256
|
ED25519 = 256
|
||||||
|
@ -73,9 +60,6 @@ ECDSA = 256
|
||||||
RSA = 2048
|
RSA = 2048
|
||||||
DSA = 1024
|
DSA = 1024
|
||||||
|
|
||||||
[lfs]
|
|
||||||
PATH=/data/gitea/lfs
|
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
APP_DATA_PATH = /data/gitea
|
APP_DATA_PATH = /data/gitea
|
||||||
HTTP_PORT = 3000
|
HTTP_PORT = 3000
|
||||||
|
@ -83,6 +67,7 @@ ROOT_URL = https://git.captnemo.in/
|
||||||
DISABLE_SSH = true
|
DISABLE_SSH = true
|
||||||
DOMAIN = git.captnemo.in
|
DOMAIN = git.captnemo.in
|
||||||
LFS_START_SERVER = true
|
LFS_START_SERVER = true
|
||||||
|
LFS_CONTENT_PATH = /data/gitea/lfs
|
||||||
LFS_JWT_SECRET = "${lfs-jwt-secret}"
|
LFS_JWT_SECRET = "${lfs-jwt-secret}"
|
||||||
OFFLINE_MODE = true
|
OFFLINE_MODE = true
|
||||||
LANDING_PAGE = explore
|
LANDING_PAGE = explore
|
||||||
|
@ -114,7 +99,10 @@ SQLITE_TIMEOUT = 500
|
||||||
; ITERATE_BUFFER_SIZE = 50
|
; ITERATE_BUFFER_SIZE = 50
|
||||||
; Show the database generated SQL
|
; Show the database generated SQL
|
||||||
LOG_SQL = false
|
LOG_SQL = false
|
||||||
SQLITE_JOURNAL_MODE = WAL
|
|
||||||
|
[session]
|
||||||
|
PROVIDER_CONFIG = /data/gitea/sessions
|
||||||
|
PROVIDER = file
|
||||||
|
|
||||||
[picture]
|
[picture]
|
||||||
AVATAR_UPLOAD_PATH = /data/gitea/avatars
|
AVATAR_UPLOAD_PATH = /data/gitea/avatars
|
||||||
|
@ -126,11 +114,9 @@ ISSUE_INDEXER_PATH = indexers/issues.bleve
|
||||||
; repo indexer by default disabled, since it uses a lot of disk space
|
; repo indexer by default disabled, since it uses a lot of disk space
|
||||||
REPO_INDEXER_ENABLED = true
|
REPO_INDEXER_ENABLED = true
|
||||||
REPO_INDEXER_PATH = indexers/repos.bleve
|
REPO_INDEXER_PATH = indexers/repos.bleve
|
||||||
|
UPDATE_BUFFER_LEN = 20
|
||||||
MAX_FILE_SIZE = 1048576
|
MAX_FILE_SIZE = 1048576
|
||||||
|
|
||||||
[queue.issue_indexer]
|
|
||||||
LENGTH = 100
|
|
||||||
|
|
||||||
[admin]
|
[admin]
|
||||||
; Disable regular (non-admin) users to create organizations
|
; Disable regular (non-admin) users to create organizations
|
||||||
DISABLE_REGULAR_ORG_CREATION = false
|
DISABLE_REGULAR_ORG_CREATION = false
|
||||||
|
@ -155,7 +141,7 @@ ACTIVE_CODE_LIVE_MINUTES = 15
|
||||||
RESET_PASSWD_CODE_LIVE_MINUTES = 30
|
RESET_PASSWD_CODE_LIVE_MINUTES = 30
|
||||||
REGISTER_EMAIL_CONFIRM = true
|
REGISTER_EMAIL_CONFIRM = true
|
||||||
ENABLE_NOTIFY_MAIL = true
|
ENABLE_NOTIFY_MAIL = true
|
||||||
DISABLE_REGISTRATION = true
|
DISABLE_REGISTRATION = false
|
||||||
; ; Enable captcha validation for registration
|
; ; Enable captcha validation for registration
|
||||||
ENABLE_CAPTCHA = true
|
ENABLE_CAPTCHA = true
|
||||||
REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA = true
|
REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA = true
|
||||||
|
@ -164,7 +150,7 @@ CAPTCHA_TYPE = image
|
||||||
REQUIRE_SIGNIN_VIEW = false
|
REQUIRE_SIGNIN_VIEW = false
|
||||||
; ; Default value for KeepEmailPrivate
|
; ; Default value for KeepEmailPrivate
|
||||||
; ; New user will get the value of this setting copied into their profile
|
; ; New user will get the value of this setting copied into their profile
|
||||||
DEFAULT_KEEP_EMAIL_PRIVATE = true
|
DEFAULT_KEEP_EMAIL_PRIVATE = false
|
||||||
; ; Default value for AllowCreateOrganization
|
; ; Default value for AllowCreateOrganization
|
||||||
; ; New user will have rights set to create organizations depending on this setting
|
; ; New user will have rights set to create organizations depending on this setting
|
||||||
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||||
|
@ -182,39 +168,44 @@ ENABLED = true
|
||||||
FROM = git@captnemo.in
|
FROM = git@captnemo.in
|
||||||
USER = git@captnemo.in
|
USER = git@captnemo.in
|
||||||
PASSWD = ${smtp_password}
|
PASSWD = ${smtp_password}
|
||||||
PROTOCOL = smtps
|
HOST = smtp.migadu.com:587
|
||||||
SMTP_ADDR = smtp.migadu.com
|
|
||||||
SMTP_PORT = 465
|
|
||||||
SEND_AS_PLAIN_TEXT = true
|
SEND_AS_PLAIN_TEXT = true
|
||||||
SUBJECT_PREFIX = "[git.captnemo.in] "
|
SUBJECT_PREFIX = "[git.captnemo.in] "
|
||||||
|
|
||||||
[cache]
|
[cache]
|
||||||
ADAPTER = redis
|
ADAPTER = redis
|
||||||
|
INTERVAL = 60
|
||||||
HOST = "network=tcp,addr=gitea-redis:6379,db=0,pool_size=100,idle_timeout=180"
|
HOST = "network=tcp,addr=gitea-redis:6379,db=0,pool_size=100,idle_timeout=180"
|
||||||
|
ITEM_TTL = 16h
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
; ; Either "memory", "file", or "redis", default is "memory"
|
; ; Either "memory", "file", or "redis", default is "memory"
|
||||||
PROVIDER = redis
|
PROVIDER = redis
|
||||||
; Provider config options
|
|
||||||
; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
|
|
||||||
PROVIDER_CONFIG = "network=tcp,addr=gitea-redis:6379,db=1,pool_size=100,idle_timeout=180"
|
PROVIDER_CONFIG = "network=tcp,addr=gitea-redis:6379,db=1,pool_size=100,idle_timeout=180"
|
||||||
|
; ; Session cookie name
|
||||||
|
COOKIE_NAME = i_like_gitea
|
||||||
; ; If you use session in https only, default is false
|
; ; If you use session in https only, default is false
|
||||||
COOKIE_SECURE = true
|
COOKIE_SECURE = true
|
||||||
; SameSite settings. Either "none", "lax", or "strict"
|
; ; Enable set cookie, default is true
|
||||||
SAME_SITE = strict
|
ENABLE_SET_COOKIE = true
|
||||||
|
; ; Session GC time interval in seconds, default is 86400 (1 day)
|
||||||
|
; GC_INTERVAL_TIME = 86400
|
||||||
|
; ; Session life time in seconds, default is 86400 (1 day)
|
||||||
|
SESSION_LIFE_TIME = 2592000
|
||||||
|
|
||||||
[migrations]
|
[picture]
|
||||||
ALLOWED_DOMAINS = github.com
|
|
||||||
ALLOW_LOCALNETWORKS = false
|
|
||||||
|
|
||||||
|
ENABLE_FEDERATED_AVATAR = true
|
||||||
|
|
||||||
[attachment]
|
[attachment]
|
||||||
; ; Whether attachments are enabled. Defaults to `true`
|
; ; Whether attachments are enabled. Defaults to `true`
|
||||||
ENABLE = true
|
ENABLE = true
|
||||||
|
; ; Path for attachments. Defaults to `data/attachments`
|
||||||
|
PATH = data/attachments
|
||||||
; ; One or more allowed types, e.g. image/jpeg|image/png
|
; ; One or more allowed types, e.g. image/jpeg|image/png
|
||||||
ALLOWED_TYPES = image/jpeg|image/png|application/zip|application/gzip|application/pdf|text/csv
|
ALLOWED_TYPES = image/jpeg|image/png|application/zip|application/gzip|application/pdf|text/csv
|
||||||
; ; Max size of each file. Defaults to 32MB
|
; ; Max size of each file. Defaults to 32MB
|
||||||
MAX_SIZE = 200
|
MAX_SIZE = 20
|
||||||
; ; Max number of files per upload. Defaults to 10
|
; ; Max number of files per upload. Defaults to 10
|
||||||
MAX_FILES = 10
|
MAX_FILES = 10
|
||||||
|
|
||||||
|
@ -225,11 +216,11 @@ MODE = console
|
||||||
; Buffer length of the channel, keep it as it is if you don't know what it is.
|
; Buffer length of the channel, keep it as it is if you don't know what it is.
|
||||||
BUFFER_LEN = 10000
|
BUFFER_LEN = 10000
|
||||||
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
||||||
LEVEL = Warn
|
LEVEL = Trace
|
||||||
REDIRECT_MACARON_LOG = true
|
REDIRECT_MACARON_LOG = true
|
||||||
ROUTER_LOG_LEVEL = Critical
|
ROUTER_LOG_LEVEL = Critical
|
||||||
logger.access.MODE=,
|
ENABLE_ACCESS_LOG = true
|
||||||
logger.xorm.MODE=,
|
ENABLE_XORM_LOG = false
|
||||||
|
|
||||||
[cron]
|
[cron]
|
||||||
; Enable running cron tasks periodically.
|
; Enable running cron tasks periodically.
|
||||||
|
@ -239,7 +230,7 @@ RUN_AT_START = false
|
||||||
|
|
||||||
[cron.archive_cleanup]
|
[cron.archive_cleanup]
|
||||||
RUN_AT_START = true
|
RUN_AT_START = true
|
||||||
SCHEDULE = @midnight
|
SCHEDULE = @every 24h
|
||||||
; Archives created more than OLDER_THAN ago are subject to deletion
|
; Archives created more than OLDER_THAN ago are subject to deletion
|
||||||
OLDER_THAN = 24h
|
OLDER_THAN = 24h
|
||||||
|
|
||||||
|
@ -250,7 +241,7 @@ SCHEDULE = @every 3h
|
||||||
|
|
||||||
; Repository health check
|
; Repository health check
|
||||||
[cron.repo_health_check]
|
[cron.repo_health_check]
|
||||||
SCHEDULE = @midnight
|
SCHEDULE = @every 24h
|
||||||
TIMEOUT = 60s
|
TIMEOUT = 60s
|
||||||
; Arguments for command 'git fsck', e.g. "--unreachable --tags"
|
; Arguments for command 'git fsck', e.g. "--unreachable --tags"
|
||||||
; see more on http://git-scm.com/docs/git-fsck
|
; see more on http://git-scm.com/docs/git-fsck
|
||||||
|
@ -259,7 +250,7 @@ ARGS =
|
||||||
; Check repository statistics
|
; Check repository statistics
|
||||||
[cron.check_repo_stats]
|
[cron.check_repo_stats]
|
||||||
RUN_AT_START = true
|
RUN_AT_START = true
|
||||||
SCHEDULE = @midnight
|
SCHEDULE = @every 24h
|
||||||
|
|
||||||
[api]
|
[api]
|
||||||
; Max number of items will response in a page
|
; Max number of items will response in a page
|
||||||
|
@ -274,40 +265,39 @@ SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
|
||||||
|
|
||||||
[openid]
|
[openid]
|
||||||
ENABLE_OPENID_SIGNIN = true
|
ENABLE_OPENID_SIGNIN = true
|
||||||
ENABLE_OPENID_SIGNUP = false
|
ENABLE_OPENID_SIGNUP = true
|
||||||
|
|
||||||
[metrics]
|
[metrics]
|
||||||
; Enables metrics endpoint. True or false; default is false.
|
; Enables metrics endpoint. True or false; default is false.
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
|
; If you want to add authorization, specify a token here
|
||||||
|
; TODO
|
||||||
|
TOKEN =
|
||||||
|
|
||||||
|
|
||||||
|
[git]
|
||||||
|
; Disables highlight of added and removed changes
|
||||||
|
DISABLE_DIFF_HIGHLIGHT = false
|
||||||
|
; Max number of lines allowed in a single file in diff view
|
||||||
|
MAX_GIT_DIFF_LINES = 1000
|
||||||
|
; Max number of allowed characters in a line in diff view
|
||||||
|
MAX_GIT_DIFF_LINE_CHARACTERS = 5000
|
||||||
|
; Max number of files shown in diff view
|
||||||
|
MAX_GIT_DIFF_FILES = 100
|
||||||
|
; Arguments for command 'git gc', e.g. "--aggressive --auto"
|
||||||
|
; see more on http://git-scm.com/docs/git-gc/
|
||||||
|
GC_ARGS =
|
||||||
|
|
||||||
|
; Operation timeout in seconds
|
||||||
|
[git.timeout]
|
||||||
|
DEFAULT = 360
|
||||||
|
MIGRATE = 600
|
||||||
|
MIRROR = 300
|
||||||
|
CLONE = 300
|
||||||
|
PULL = 300
|
||||||
|
GC = 60
|
||||||
|
|
||||||
[oauth2]
|
[oauth2]
|
||||||
ENABLE = false
|
ENABLE = false
|
||||||
; this is same as JWT secret above
|
; this is same as JWT secret above
|
||||||
JWT_SECRET = "${oauth2-jwt-secret}"
|
JWT_SECRET = "${oauth2-jwt-secret}"
|
||||||
|
|
||||||
[federation]
|
|
||||||
ENABLED=false
|
|
||||||
;; Enable/Disable user statistics for nodeinfo if federation is enabled
|
|
||||||
;SHARE_USER_STATISTICS = true
|
|
||||||
;;
|
|
||||||
;; Maximum federation request and response size (MB)
|
|
||||||
;MAX_SIZE = 4
|
|
||||||
;;
|
|
||||||
;; WARNING: Changing the settings below can break federation.
|
|
||||||
;;
|
|
||||||
;; HTTP signature algorithms
|
|
||||||
;ALGORITHMS = rsa-sha256, rsa-sha512, ed25519
|
|
||||||
;;
|
|
||||||
;; HTTP signature digest algorithm
|
|
||||||
;DIGEST_ALGORITHM = SHA-256
|
|
||||||
;;
|
|
||||||
;; GET headers for federation requests
|
|
||||||
;GET_HEADERS = (request-target), Date
|
|
||||||
;;
|
|
||||||
;; POST headers for federation requests
|
|
||||||
;POST_HEADERS = (request-target), Date, Digest
|
|
||||||
|
|
||||||
|
|
||||||
[packages]
|
|
||||||
;; Enable/Disable package registry capabilities
|
|
||||||
ENABLED = true
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
version="1.0"
|
|
||||||
width="2000.000000pt"
|
|
||||||
height="2000.000000pt"
|
|
||||||
viewBox="0 0 2000.000000 2000.000000"
|
|
||||||
preserveAspectRatio="xMidYMid meet"
|
|
||||||
id="svg10"
|
|
||||||
sodipodi:docname="favicon.svg"
|
|
||||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs14" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview12"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="pt"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="0.23281491"
|
|
||||||
inkscape:cx="1232.7389"
|
|
||||||
inkscape:cy="1415.2874"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1037"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="18"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="g8" />
|
|
||||||
<metadata
|
|
||||||
id="metadata2">
|
|
||||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
transform="translate(0.000000,2000.000000) scale(0.100000,-0.100000)"
|
|
||||||
fill="#000000"
|
|
||||||
stroke="none"
|
|
||||||
id="g8"
|
|
||||||
style="fill:#000080">
|
|
||||||
<path
|
|
||||||
d="M0 10000 l0 -10000 10000 0 10000 0 0 10000 0 10000 -10000 0 -10000 0 0 -10000z m11852 5356 c553 -141 882 -698 738 -1251 -27 -102 -104 -261 -168 -346 -71 -94 -197 -207 -296 -265 -109 -65 -274 -121 -405 -136 l-100 -12 -90 -221 c-69 -169 -87 -222 -76 -227 12 -7 1420 -613 2145 -923 162 -69 310 -132 328 -140 31 -14 32 -16 20 -44 -7 -15 -55 -127 -107 -247 -52 -121 -96 -221 -98 -223 -4 -5 -131 48 -1385 585 -608 261 -1111 474 -1116 474 -5 0 -19 -24 -31 -52 -76 -181 -1440 -3576 -1474 -3667 -16 -43 -21 -81 -21 -166 -1 -99 2 -116 26 -167 38 -81 83 -133 158 -182 160 -104 244 -120 614 -113 383 7 564 38 731 125 90 47 218 173 263 258 67 128 79 306 32 471 -11 40 -20 75 -20 78 0 3 91 5 203 5 402 0 680 43 1017 156 226 76 540 218 768 348 35 20 66 36 68 36 9 0 3 -122 -11 -237 -57 -462 -214 -845 -470 -1152 -100 -119 -281 -291 -403 -383 -92 -70 -344 -228 -363 -228 -4 0 -35 29 -70 65 -105 109 -219 151 -345 125 -36 -7 -108 -38 -184 -78 -489 -261 -847 -376 -1345 -434 -180 -21 -653 -15 -955 11 -140 13 -338 25 -440 28 l-185 5 125 -126 125 -126 75 6 c97 8 170 -17 234 -82 65 -64 90 -137 82 -234 l-6 -75 206 -206 206 -207 83 6 c73 4 89 2 137 -20 184 -84 232 -302 100 -449 -67 -75 -110 -94 -212 -94 -68 0 -93 5 -125 22 -51 27 -119 100 -140 150 -19 43 -24 127 -12 188 l8 40 -201 200 -200 200 0 -531 0 -531 26 -14 c41 -22 101 -96 118 -146 38 -110 8 -222 -80 -302 -96 -88 -207 -103 -321 -45 -134 69 -192 232 -130 367 26 58 83 119 128 139 l29 13 0 531 0 532 -28 11 c-42 18 -108 89 -132 144 -24 53 -28 144 -10 191 11 30 9 32 -203 245 -117 119 -219 230 -226 246 -44 103 -170 239 -486 523 -412 371 -643 616 -819 865 -236 336 -397 688 -501 1092 -44 170 -80 249 -141 305 -76 70 -138 92 -263 95 l-106 2 -28 109 c-49 190 -70 366 -71 589 -1 220 10 324 54 505 61 246 161 471 308 691 134 200 315 410 326 378 3 -8 19 -68 36 -134 136 -520 354 -976 638 -1332 95 -119 277 -319 322 -354 l33 -25 -89 -49 c-166 -93 -288 -240 -324 -393 -15 -66 -15 -212 0 -289 24 -120 126 -300 267 -476 139 -172 374 -408 455 -456 181 -106 352 -125 492 -54 66 33 153 123 193 198 17 33 365 794 773 1690 408 897 760 1668 782 1715 72 154 120 262 116 265 -1 1 -91 40 -198 85 -321 136 -871 371 -935 400 -33 15 -161 70 -285 123 -735 312 -1076 459 -1082 466 -11 10 201 501 216 501 6 0 200 -81 431 -181 1489 -641 2052 -882 2070 -886 17 -3 33 24 118 212 l97 217 -48 61 c-96 122 -154 239 -194 392 -30 114 -36 323 -13 436 23 114 72 242 131 341 58 96 199 245 293 308 124 83 285 146 437 170 97 15 276 4 386 -24z"
|
|
||||||
id="path4"
|
|
||||||
style="fill:#192a56;fill-opacity:1" />
|
|
||||||
<path
|
|
||||||
d="M11496 14790 c-110 -28 -228 -126 -281 -234 -103 -210 -11 -470 203 -577 65 -33 71 -34 187 -34 116 0 122 1 187 34 82 41 169 128 204 206 99 217 11 466 -202 571 -66 33 -83 37 -166 40 -51 2 -110 -1 -132 -6z"
|
|
||||||
id="path6"
|
|
||||||
style="fill:#192a56;fill-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.1 KiB |
|
@ -18,5 +18,3 @@ User-agent: Xenu’s
|
||||||
Disallow: /
|
Disallow: /
|
||||||
User-agent: Xenu’s Link Sleuth 1.1c
|
User-agent: Xenu’s Link Sleuth 1.1c
|
||||||
Disallow: /
|
Disallow: /
|
||||||
User-agent: AhrefsBot
|
|
||||||
Disallow: /
|
|
||||||
|
|
|
@ -18,5 +18,3 @@ User-agent: Xenu’s
|
||||||
Disallow: /
|
Disallow: /
|
||||||
User-agent: Xenu’s Link Sleuth 1.1c
|
User-agent: Xenu’s Link Sleuth 1.1c
|
||||||
Disallow: /
|
Disallow: /
|
||||||
User-agent: AhrefsBot
|
|
||||||
Disallow: /
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# https://github.com/go-gitea/gitea/releases
|
# https://github.com/go-gitea/gitea/releases
|
||||||
data "docker_registry_image" "gitea" {
|
data "docker_registry_image" "gitea" {
|
||||||
name = "gitea/gitea:1.21"
|
name = "gitea/gitea:1.13"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "docker_registry_image" "redis" {
|
data "docker_registry_image" "redis" {
|
||||||
|
@ -19,3 +19,4 @@ data "template_file" "gitea-config-file" {
|
||||||
oauth2-jwt-secret = var.oauth2-jwt-secret
|
oauth2-jwt-secret = var.oauth2-jwt-secret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
locals {
|
|
||||||
l = merge(var.traefik-labels, {
|
|
||||||
"traefik.port" = 3000
|
|
||||||
"traefik.frontend.rule" = "Host:${var.domain}"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "docker_container" "gitea" {
|
resource "docker_container" "gitea" {
|
||||||
name = "gitea"
|
name = "gitea"
|
||||||
image = docker_image.gitea.image_id
|
image = docker_image.gitea.latest
|
||||||
|
|
||||||
dynamic "labels" {
|
labels = merge(
|
||||||
for_each = local.l
|
var.traefik-labels,
|
||||||
content {
|
{
|
||||||
label = labels.key
|
"traefik.port" = 3000
|
||||||
value = labels.value
|
"traefik.frontend.rule" = "Host:${var.domain}"
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
|
|
||||||
volumes {
|
volumes {
|
||||||
volume_name = docker_volume.gitea_volume.name
|
volume_name = docker_volume.gitea_volume.name
|
||||||
|
@ -23,44 +16,29 @@ resource "docker_container" "gitea" {
|
||||||
host_path = docker_volume.gitea_volume.mountpoint
|
host_path = docker_volume.gitea_volume.mountpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
# For the following uploads, note that
|
|
||||||
# /data/gitea is GITEA_CUSTOM_PATH
|
|
||||||
|
|
||||||
# Logos
|
# Logos
|
||||||
|
# TODO: Add svg
|
||||||
|
|
||||||
# https://docs.gitea.com/next/administration/customizing-gitea#changing-the-logo
|
|
||||||
# PNG images
|
|
||||||
upload {
|
upload {
|
||||||
content_base64 = filebase64("${path.module}/conf/public/img/gitea-lg.png")
|
content = file("${path.module}/conf/public/img/gitea-lg.png")
|
||||||
file = "/data/gitea/public/img/logo.png"
|
file = "/data/gitea/public/img/gitea-lg.png"
|
||||||
}
|
}
|
||||||
upload {
|
upload {
|
||||||
content_base64 = filebase64("${path.module}/conf/public/img/gitea-lg.png")
|
content = file("${path.module}/conf/public/img/gitea-sm.png")
|
||||||
file = "/data/gitea/public/img/apple-touch-icon.png"
|
file = "/data/gitea/public/img/gitea-sm.png"
|
||||||
}
|
}
|
||||||
upload {
|
upload {
|
||||||
content_base64 = filebase64("${path.module}/conf/public/img/gitea-sm.png")
|
content = file("${path.module}/conf/public/img/gitea-sm.png")
|
||||||
file = "/data/gitea/public/img/favicon.png"
|
file = "/data/gitea/public/img/favicon.png"
|
||||||
|
executable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
# SVG images
|
|
||||||
upload {
|
|
||||||
content_base64 = filebase64("${path.module}/conf/public/img/favicon.svg")
|
|
||||||
file = "/data/gitea/public/img/logo.svg"
|
|
||||||
}
|
|
||||||
upload {
|
|
||||||
content_base64 = filebase64("${path.module}/conf/public/img/favicon.svg")
|
|
||||||
file = "/data/gitea/public/img/favicon.svg"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Some files at top-level
|
|
||||||
upload {
|
upload {
|
||||||
content = file("${path.module}/../docker/conf/humans.txt")
|
content = file("${path.module}/../docker/conf/humans.txt")
|
||||||
file = "/data/gitea/humans.txt"
|
file = "/data/gitea/public/humans.txt"
|
||||||
}
|
}
|
||||||
upload {
|
upload {
|
||||||
content = file("${path.module}/conf/public/robots.txt")
|
content = file("${path.module}/conf/public/robots.txt")
|
||||||
file = "/data/gitea/robots.txt"
|
file = "/data/gitea/public/robots.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Extra Links in header
|
# Extra Links in header
|
||||||
|
@ -74,12 +52,20 @@ resource "docker_container" "gitea" {
|
||||||
content = data.template_file.gitea-config-file.rendered
|
content = data.template_file.gitea-config-file.rendered
|
||||||
file = "/data/gitea/conf/app.ini"
|
file = "/data/gitea/conf/app.ini"
|
||||||
}
|
}
|
||||||
|
memory = 512
|
||||||
memory = 800
|
|
||||||
restart = "always"
|
restart = "always"
|
||||||
destroy_grace_seconds = 10
|
destroy_grace_seconds = 10
|
||||||
must_run = true
|
must_run = true
|
||||||
networks = ["gitea", "traefik"]
|
networks = [docker_network.gitea.id, var.traefik-network-id]
|
||||||
|
# This doesn't work.
|
||||||
|
# See https://github.com/terraform-providers/terraform-provider-docker/issues/48
|
||||||
|
# lifecycle {
|
||||||
|
# ignore_changes = [
|
||||||
|
# "upload.2151376053.content",
|
||||||
|
# "upload.2151376053.executable",
|
||||||
|
# "upload.2151376053.file",
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "docker_image" "gitea" {
|
resource "docker_image" "gitea" {
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
resource "docker_container" "redis" {
|
resource "docker_container" "redis" {
|
||||||
name = "gitea-redis"
|
name = "gitea-redis"
|
||||||
image = docker_image.redis.image_id
|
image = docker_image.redis.latest
|
||||||
|
|
||||||
volumes {
|
volumes {
|
||||||
host_path = "/mnt/xwing/cache/gitea"
|
host_path = "/mnt/xwing/cache/gitea"
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -1,24 +0,0 @@
|
||||||
module "home-assistant" {
|
|
||||||
name = "home-assistant"
|
|
||||||
source = "../modules/container"
|
|
||||||
|
|
||||||
image = "ghcr.io/home-assistant/home-assistant:stable"
|
|
||||||
|
|
||||||
resource = {
|
|
||||||
memory = 1024
|
|
||||||
memory_swap = 1024
|
|
||||||
}
|
|
||||||
|
|
||||||
env = [
|
|
||||||
"TZ=Asia/Kolkata",
|
|
||||||
]
|
|
||||||
|
|
||||||
network_mode = "host"
|
|
||||||
|
|
||||||
volumes = [
|
|
||||||
{
|
|
||||||
container_path = "/config"
|
|
||||||
host_path = "/mnt/zwing/config/home-assistant"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
28
jupyter.tf
28
jupyter.tf
|
@ -1,16 +1,12 @@
|
||||||
module "jupyter" {
|
# module "jupyter" {
|
||||||
name = "jupyter"
|
# name = "jupyter"
|
||||||
source = "./modules/container"
|
# source = "modules/container"
|
||||||
image = "jupyter/scipy-notebook"
|
# image = "jupyter/tensorflow-notebook"
|
||||||
resource = {
|
# ports = [
|
||||||
memory = 1024
|
# {
|
||||||
memory_swap = 4096
|
# internal = 8888
|
||||||
}
|
# external = 1112
|
||||||
web = {
|
# ip = "${var.ips["tun0"]}"
|
||||||
expose = "true"
|
# },
|
||||||
host = "j.${var.root-domain}"
|
# ]
|
||||||
port = 8888
|
# }
|
||||||
}
|
|
||||||
networks = ["bridge"]
|
|
||||||
gpu = true
|
|
||||||
}
|
|
||||||
|
|
16
kaarana.tf
16
kaarana.tf
|
@ -1,15 +1,15 @@
|
||||||
# kaarana related stuff
|
# kaarana related stuff
|
||||||
|
|
||||||
# module "kaarana" {
|
module "kaarana" {
|
||||||
# source = "./kaarana"
|
source = "./kaarana"
|
||||||
|
|
||||||
# root_db_password = data.pass_password.kaarana-root-db-password.password
|
root_db_password = data.pass_password.kaarana-root-db-password.password
|
||||||
# db_password = data.pass_password.kaarana-db-password.password
|
db_password = data.pass_password.kaarana-db-password.password
|
||||||
|
|
||||||
# providers = {
|
providers = {
|
||||||
# docker = docker.sydney
|
docker = docker.sydney
|
||||||
# }
|
}
|
||||||
# }
|
}
|
||||||
|
|
||||||
data "pass_password" "kaarana-root-db-password" {
|
data "pass_password" "kaarana-root-db-password" {
|
||||||
path = "KAARANA_DB_ROOT_PASSWORD"
|
path = "KAARANA_DB_ROOT_PASSWORD"
|
||||||
|
|
|
@ -18,7 +18,7 @@ resource "docker_network" "kaarana-db" {
|
||||||
// Run a small mySQL container in this subnet
|
// Run a small mySQL container in this subnet
|
||||||
|
|
||||||
resource "docker_container" "mysql" {
|
resource "docker_container" "mysql" {
|
||||||
image = docker_image.db.image_id
|
image = docker_image.db.latest
|
||||||
name = "kaarana-mariadb"
|
name = "kaarana-mariadb"
|
||||||
restart = "always"
|
restart = "always"
|
||||||
must_run = true
|
must_run = true
|
||||||
|
@ -35,6 +35,17 @@ resource "docker_container" "mysql" {
|
||||||
container_path = "/var/lib/mysql"
|
container_path = "/var/lib/mysql"
|
||||||
}
|
}
|
||||||
|
|
||||||
networks = ["kaarana-db"]
|
networks_advanced {
|
||||||
|
name = "kaarana-db"
|
||||||
|
# TF-UPGRADE-TODO: In Terraform v0.10 and earlier, it was sometimes necessary to
|
||||||
|
# force an interpolation expression to be interpreted as a list by wrapping it
|
||||||
|
# in an extra set of list brackets. That form was supported for compatibility in
|
||||||
|
# v0.11, but is no longer supported in Terraform v0.12.
|
||||||
|
#
|
||||||
|
# If the expression in the following list itself returns a list, remove the
|
||||||
|
# brackets to avoid interpretation as a list of lists. If the expression
|
||||||
|
# returns a single list item then leave it as-is and remove this TODO comment.
|
||||||
|
aliases = [local.db_hostname]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ resource "docker_network" "traefik" {
|
||||||
|
|
||||||
resource "docker_container" "traefik" {
|
resource "docker_container" "traefik" {
|
||||||
name = "traefik"
|
name = "traefik"
|
||||||
image = docker_image.traefik.image_id
|
image = docker_image.traefik.latest
|
||||||
|
|
||||||
# Do not offer HTTP2
|
# Do not offer HTTP2
|
||||||
# https://community.containo.us/t/traefikv2-http-2-0/1199
|
# https://community.containo.us/t/traefikv2-http-2-0/1199
|
||||||
|
@ -56,7 +56,6 @@ resource "docker_container" "traefik" {
|
||||||
networks_advanced {
|
networks_advanced {
|
||||||
name = "bridge"
|
name = "bridge"
|
||||||
}
|
}
|
||||||
|
|
||||||
networks_advanced {
|
networks_advanced {
|
||||||
name = "traefik"
|
name = "traefik"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
resource "docker_container" "wp" {
|
resource "docker_container" "wp" {
|
||||||
image = docker_image.wp.image_id
|
image = docker_image.wp.latest
|
||||||
name = "kaarana-wordpress"
|
name = "kaarana-wordpress"
|
||||||
|
|
||||||
restart = "always"
|
restart = "always"
|
||||||
|
@ -35,6 +35,16 @@ resource "docker_container" "wp" {
|
||||||
ip = "10.8.0.1"
|
ip = "10.8.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
networks = ["bridge", "kaarana-db"]
|
networks_advanced {
|
||||||
|
name = "kaarana-db"
|
||||||
|
}
|
||||||
|
networks_advanced {
|
||||||
|
// TODO: Once configuration/plugins have stabilized
|
||||||
|
// remove internet access from wordpress
|
||||||
|
name = "bridge"
|
||||||
|
}
|
||||||
|
networks_advanced {
|
||||||
|
name = "traefik"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
kavita.tf
33
kavita.tf
|
@ -1,33 +0,0 @@
|
||||||
# module "kavita" {
|
|
||||||
# name = "kavita"
|
|
||||||
# source = "./modules/container"
|
|
||||||
# image = "kizaing/kavita:latest"
|
|
||||||
|
|
||||||
# web = {
|
|
||||||
# expose = true
|
|
||||||
# port = 5000
|
|
||||||
# host = "kavita.bb8.fun"
|
|
||||||
# }
|
|
||||||
|
|
||||||
# resource = {
|
|
||||||
# memory = 1024
|
|
||||||
# memory_swap = 1024
|
|
||||||
# }
|
|
||||||
|
|
||||||
# volumes = [
|
|
||||||
# {
|
|
||||||
# host_path = "/mnt/xwing/media/EBooks"
|
|
||||||
# container_path = "/ebooks"
|
|
||||||
# },
|
|
||||||
# {
|
|
||||||
# host_path = "/mnt/xwing/config/kavita"
|
|
||||||
# container_path = "/kavita/config"
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# networks = ["traefik"]
|
|
||||||
|
|
||||||
# env = [
|
|
||||||
# "TZ=Asia/Kolkata",
|
|
||||||
# ]
|
|
||||||
# }
|
|
12
klaxon.tf
12
klaxon.tf
|
@ -35,6 +35,16 @@ module "klaxon" {
|
||||||
|
|
||||||
image = "themarshallproject/klaxon"
|
image = "themarshallproject/klaxon"
|
||||||
|
|
||||||
networks = ["postgres", "external"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "traefik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "postgres"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "external"
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
main.tf
17
main.tf
|
@ -68,8 +68,7 @@ module "media" {
|
||||||
domain = "bb8.fun"
|
domain = "bb8.fun"
|
||||||
traefik-labels = var.traefik-common-labels
|
traefik-labels = var.traefik-common-labels
|
||||||
ips = var.ips
|
ips = var.ips
|
||||||
# ToDO: Change this to lookup
|
traefik-network-id = module.docker.traefik-network-id
|
||||||
traefik-network-id = "ffc1e366849e"
|
|
||||||
lastfm_api_key = data.pass_password.navidrome-lastfm-api-key.password
|
lastfm_api_key = data.pass_password.navidrome-lastfm-api-key.password
|
||||||
lastfm_secret = data.pass_password.navidrome-lastfm-secret.password
|
lastfm_secret = data.pass_password.navidrome-lastfm-secret.password
|
||||||
spotify_id = data.pass_password.navidrome-spotify-id.password
|
spotify_id = data.pass_password.navidrome-spotify-id.password
|
||||||
|
@ -91,20 +90,6 @@ module "digitalocean" {
|
||||||
source = "./digitalocean"
|
source = "./digitalocean"
|
||||||
}
|
}
|
||||||
|
|
||||||
module "home-assistant" {
|
|
||||||
source = "./home-assistant"
|
|
||||||
}
|
|
||||||
|
|
||||||
module "mastodon" {
|
|
||||||
source = "./mastodon"
|
|
||||||
db-password = data.pass_password.mastodon-db-password.password
|
|
||||||
secret-key-base = data.pass_password.mastodon-secret-key-base.password
|
|
||||||
otp-secret = data.pass_password.mastodon-otp-secret.password
|
|
||||||
vapid-private-key = data.pass_password.mastodon-vapid-private-key.password
|
|
||||||
vapid-public-key = data.pass_password.mastodon-vapid-public-key.password
|
|
||||||
smtp-password = data.pass_password.mastodon-smtp-password.password
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used to force access to ISP related resources
|
// Used to force access to ISP related resources
|
||||||
# module "tinyproxy" {
|
# module "tinyproxy" {
|
||||||
# source = "./tinyproxy"
|
# source = "./tinyproxy"
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
module "mastodon-redis" {
|
|
||||||
name = "mastodon-redis"
|
|
||||||
source = "../modules/container"
|
|
||||||
image = "redis:alpine"
|
|
||||||
networks = ["mastodon"]
|
|
||||||
keep_image = true
|
|
||||||
|
|
||||||
resource = {
|
|
||||||
memory = 256
|
|
||||||
memory_swap = 256
|
|
||||||
}
|
|
||||||
|
|
||||||
# In case the cache dies,
|
|
||||||
# tootctl feeds build
|
|
||||||
# regenerates the feeds, run it from
|
|
||||||
# inside a mastodon container
|
|
||||||
volumes = [
|
|
||||||
{
|
|
||||||
host_path = "/mnt/zwing/cache/mastodon-redis"
|
|
||||||
container_path = "/data"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
module "mastodon-db" {
|
|
||||||
source = "../modules/postgres"
|
|
||||||
name = "mastodon"
|
|
||||||
password = var.db-password
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
locals {
|
|
||||||
version = "4.1.10"
|
|
||||||
env = [
|
|
||||||
"LOCAL_DOMAIN=tatooine.club",
|
|
||||||
"REDIS_HOST=mastodon-redis",
|
|
||||||
"REDIS_PORT=6379",
|
|
||||||
"DB_HOST=postgres",
|
|
||||||
"DB_USER=mastodon",
|
|
||||||
"DB_NAME=mastodon",
|
|
||||||
"DB_PASS=${var.db-password}",
|
|
||||||
"DB_PORT=5432",
|
|
||||||
"ES_ENABLED=false",
|
|
||||||
"SECRET_KEY_BASE=${var.secret-key-base}",
|
|
||||||
"OTP_SECRET=${var.otp-secret}",
|
|
||||||
"VAPID_PRIVATE_KEY=${var.vapid-private-key}",
|
|
||||||
"VAPID_PUBLIC_KEY=${var.vapid-public-key}",
|
|
||||||
"SMTP_SERVER=smtp.eu.mailgun.org",
|
|
||||||
"SMTP_PORT=587",
|
|
||||||
"SMTP_LOGIN=mastodon@mail.tatooine.club",
|
|
||||||
"SMTP_PASSWORD=${var.smtp-password}",
|
|
||||||
"SMTP_FROM_ADDRESS=mastodon@mail.tatooine.club",
|
|
||||||
]
|
|
||||||
}
|
|
103
mastodon/main.tf
103
mastodon/main.tf
|
@ -1,103 +0,0 @@
|
||||||
module "mastodon-web" {
|
|
||||||
name = "mastodon-web"
|
|
||||||
source = "../modules/container"
|
|
||||||
image = "ghcr.io/mastodon/mastodon:v${local.version}"
|
|
||||||
keep_image = true
|
|
||||||
|
|
||||||
networks = ["mastodon", "traefik", "external", "postgres"]
|
|
||||||
|
|
||||||
labels = {
|
|
||||||
"traefik.frontend.headers.STSPreload" = "true"
|
|
||||||
"traefik.frontend.headers.STSIncludeSubdomains" = "true"
|
|
||||||
"traefik.frontend.headers.STSSeconds" = "31536000"
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = 2048
|
|
||||||
memory_swap = 2048
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module "mastodon-streaming" {
|
|
||||||
name = "mastodon-streaming"
|
|
||||||
source = "../modules/container"
|
|
||||||
image = "ghcr.io/mastodon/mastodon:v${local.version}"
|
|
||||||
keep_image = true
|
|
||||||
|
|
||||||
# 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 = 512
|
|
||||||
memory_swap = 512
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module "mastodon-sidekiq" {
|
|
||||||
name = "mastodon-sidekiq"
|
|
||||||
source = "../modules/container"
|
|
||||||
image = "ghcr.io/mastodon/mastodon:v${local.version}"
|
|
||||||
keep_image = true
|
|
||||||
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 = 2048
|
|
||||||
memory_swap = 2048
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
resource "docker_network" "mastodon" {
|
|
||||||
name = "mastodon"
|
|
||||||
driver = "bridge"
|
|
||||||
internal = true
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
variable "db-password" {
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
variable "secret-key-base" {
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
variable "otp-secret" {
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
variable "vapid-private-key" {
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
variable "vapid-public-key" {
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
variable "smtp-password" {
|
|
||||||
type = string
|
|
||||||
}
|
|
|
@ -10,17 +10,17 @@
|
||||||
"bind-address-ipv6": "::",
|
"bind-address-ipv6": "::",
|
||||||
"blocklist-enabled": true,
|
"blocklist-enabled": true,
|
||||||
"blocklist-url": "http://john.bitsurge.net/public/biglist.p2p.gz",
|
"blocklist-url": "http://john.bitsurge.net/public/biglist.p2p.gz",
|
||||||
"cache-size-mb": 256,
|
"cache-size-mb": 16,
|
||||||
"dht-enabled": true,
|
"dht-enabled": true,
|
||||||
"download-dir": "/downloads",
|
"download-dir": "/downloads",
|
||||||
"download-queue-enabled": false,
|
"download-queue-enabled": true,
|
||||||
"download-queue-size": 5,
|
"download-queue-size": 5,
|
||||||
"encryption": 1,
|
"encryption": 1,
|
||||||
"idle-seeding-limit": 30,
|
"idle-seeding-limit": 30,
|
||||||
"idle-seeding-limit-enabled": false,
|
"idle-seeding-limit-enabled": false,
|
||||||
"incomplete-dir": "/downloads",
|
"incomplete-dir": "/downloads",
|
||||||
"incomplete-dir-enabled": true,
|
"incomplete-dir-enabled": true,
|
||||||
"lpd-enabled": true,
|
"lpd-enabled": false,
|
||||||
"message-level": 2,
|
"message-level": 2,
|
||||||
"peer-congestion-algorithm": "",
|
"peer-congestion-algorithm": "",
|
||||||
"peer-id-ttl-hours": 6,
|
"peer-id-ttl-hours": 6,
|
||||||
|
@ -31,13 +31,13 @@
|
||||||
"peer-port-random-low": 49152,
|
"peer-port-random-low": 49152,
|
||||||
"peer-port-random-on-start": false,
|
"peer-port-random-on-start": false,
|
||||||
"peer-socket-tos": "default",
|
"peer-socket-tos": "default",
|
||||||
"pex-enabled": false,
|
"pex-enabled": true,
|
||||||
"port-forwarding-enabled": true,
|
"port-forwarding-enabled": true,
|
||||||
"preallocation": 1,
|
"preallocation": 1,
|
||||||
"prefetch-enabled": true,
|
"prefetch-enabled": true,
|
||||||
"queue-stalled-enabled": false,
|
"queue-stalled-enabled": true,
|
||||||
"queue-stalled-minutes": 30,
|
"queue-stalled-minutes": 30,
|
||||||
"ratio-limit": 1.2,
|
"ratio-limit": 0.2,
|
||||||
"ratio-limit-enabled": true,
|
"ratio-limit-enabled": true,
|
||||||
"rename-partial-files": true,
|
"rename-partial-files": true,
|
||||||
"rpc-host-whitelist": "transmission.bb8.fun,transmission",
|
"rpc-host-whitelist": "transmission.bb8.fun,transmission",
|
||||||
|
@ -51,19 +51,19 @@
|
||||||
"rpc-username": "",
|
"rpc-username": "",
|
||||||
"rpc-whitelist": "127.0.0.1",
|
"rpc-whitelist": "127.0.0.1",
|
||||||
"rpc-whitelist-enabled": false,
|
"rpc-whitelist-enabled": false,
|
||||||
"scrape-paused-torrents-enabled": false,
|
"scrape-paused-torrents-enabled": true,
|
||||||
"script-torrent-done-enabled": false,
|
"script-torrent-done-enabled": false,
|
||||||
"script-torrent-done-filename": "",
|
"script-torrent-done-filename": "",
|
||||||
"seed-queue-enabled": true,
|
"seed-queue-enabled": false,
|
||||||
"seed-queue-size": 50,
|
"seed-queue-size": 10,
|
||||||
"speed-limit-down": 100,
|
"speed-limit-down": 100,
|
||||||
"speed-limit-down-enabled": false,
|
"speed-limit-down-enabled": false,
|
||||||
"speed-limit-up": 50,
|
"speed-limit-up": 50,
|
||||||
"speed-limit-up-enabled": false,
|
"speed-limit-up-enabled": true,
|
||||||
"start-added-torrents": true,
|
"start-added-torrents": true,
|
||||||
"trash-original-torrent-files": false,
|
"trash-original-torrent-files": false,
|
||||||
"umask": 2,
|
"umask": 2,
|
||||||
"upload-slots-per-torrent": 10,
|
"upload-slots-per-torrent": 14,
|
||||||
"utp-enabled": true,
|
"utp-enabled": true,
|
||||||
"watch-dir": "/watch",
|
"watch-dir": "/watch",
|
||||||
"watch-dir-enabled": true
|
"watch-dir-enabled": true
|
||||||
|
|
|
@ -1,48 +1,25 @@
|
||||||
|
|
||||||
locals {
|
|
||||||
emby_labels = merge(var.traefik-labels, {
|
|
||||||
"traefik.frontend.rule" = "Host:emby.in.${var.domain},emby.${var.domain}"
|
|
||||||
"traefik.frontend.passHostHeader" = "true"
|
|
||||||
"traefik.port" = 8096
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "docker_container" "emby" {
|
resource "docker_container" "emby" {
|
||||||
name = "emby"
|
name = "emby"
|
||||||
image = docker_image.emby.image_id
|
image = docker_image.emby.latest
|
||||||
|
|
||||||
# SSD holds both the cache and data
|
|
||||||
volumes {
|
volumes {
|
||||||
host_path = "/mnt/zwing/config/emby"
|
host_path = "/mnt/xwing/config/emby"
|
||||||
container_path = "/config"
|
container_path = "/config"
|
||||||
}
|
}
|
||||||
|
|
||||||
# We keep the cache separate
|
|
||||||
# So the config directory isn't bloated
|
|
||||||
volumes {
|
|
||||||
host_path = "/mnt/zwing/cache/emby"
|
|
||||||
container_path = "/config/cache"
|
|
||||||
}
|
|
||||||
|
|
||||||
# We want backups on the HDD
|
|
||||||
volumes {
|
|
||||||
host_path = "/mnt/xwing/backups/config/emby"
|
|
||||||
container_path = "/backups"
|
|
||||||
}
|
|
||||||
|
|
||||||
# And mount the media as well
|
|
||||||
volumes {
|
volumes {
|
||||||
host_path = "/mnt/xwing/media"
|
host_path = "/mnt/xwing/media"
|
||||||
container_path = "/media"
|
container_path = "/media"
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic "labels" {
|
labels = merge(
|
||||||
for_each = local.emby_labels
|
var.traefik-labels,
|
||||||
content {
|
{
|
||||||
label = labels.key
|
"traefik.frontend.rule" = "Host:emby.in.${var.domain},emby.${var.domain}"
|
||||||
value = labels.value
|
"traefik.frontend.passHostHeader" = "true"
|
||||||
}
|
"traefik.port" = 8096
|
||||||
}
|
},
|
||||||
|
)
|
||||||
|
|
||||||
networks = [docker_network.media.id, var.traefik-network-id]
|
networks = [docker_network.media.id, var.traefik-network-id]
|
||||||
|
|
||||||
|
@ -51,15 +28,13 @@ resource "docker_container" "emby" {
|
||||||
destroy_grace_seconds = 10
|
destroy_grace_seconds = 10
|
||||||
must_run = true
|
must_run = true
|
||||||
|
|
||||||
# This breaks every time we upgrade the kernel
|
|
||||||
# or the nvidia driver, and needs a reboot.
|
|
||||||
gpus = "all"
|
|
||||||
|
|
||||||
# Running as lounge:tatooine
|
# Running as lounge:tatooine
|
||||||
env = [
|
env = [
|
||||||
"UID=1004",
|
"APP_USER=lounge",
|
||||||
"GID=1003",
|
"APP_UID=1004",
|
||||||
"GIDLIST=1003"
|
"APP_GID=1003",
|
||||||
|
"APP_CONFIG=/mnt/xwing/config",
|
||||||
|
"TZ=Asia/Kolkata",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,25 +7,17 @@ resource "docker_image" "lidarr" {
|
||||||
pull_triggers = [data.docker_registry_image.lidarr.sha256_digest]
|
pull_triggers = [data.docker_registry_image.lidarr.sha256_digest]
|
||||||
}
|
}
|
||||||
|
|
||||||
locals {
|
|
||||||
lidarr_labels = merge(var.traefik-labels, {
|
|
||||||
"traefik.port" = 8686
|
|
||||||
"traefik.frontend.rule" = "Host:lidarr.${var.domain}"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "docker_container" "lidarr" {
|
resource "docker_container" "lidarr" {
|
||||||
name = "lidarr"
|
name = "lidarr"
|
||||||
image = docker_image.lidarr.image_id
|
image = docker_image.lidarr.latest
|
||||||
|
|
||||||
dynamic "labels" {
|
|
||||||
for_each = local.lidarr_labels
|
|
||||||
content {
|
|
||||||
label = labels.key
|
|
||||||
value = labels.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
labels = merge(
|
||||||
|
var.traefik-labels,
|
||||||
|
{
|
||||||
|
"traefik.port" = 8686
|
||||||
|
"traefik.frontend.rule" = "Host:lidarr.${var.domain}"
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
memory = 512
|
memory = 512
|
||||||
restart = "unless-stopped"
|
restart = "unless-stopped"
|
||||||
|
|
|
@ -17,7 +17,7 @@ module "navidrome" {
|
||||||
}
|
}
|
||||||
|
|
||||||
env = [
|
env = [
|
||||||
"ND_SCANINTERVAL=6h",
|
"ND_SCANINTERVAL=1h",
|
||||||
"ND_LOGLEVEL=info",
|
"ND_LOGLEVEL=info",
|
||||||
"ND_SESSIONTIMEOUT=300h",
|
"ND_SESSIONTIMEOUT=300h",
|
||||||
"ND_BASEURL=",
|
"ND_BASEURL=",
|
||||||
|
@ -31,14 +31,10 @@ module "navidrome" {
|
||||||
# TODO FIXME
|
# TODO FIXME
|
||||||
# networks = [docker_network.media.id, data.docker_network.bridge.id]
|
# networks = [docker_network.media.id, data.docker_network.bridge.id]
|
||||||
|
|
||||||
# Keep cache and data config so we can do easier backups
|
|
||||||
volumes = [
|
volumes = [
|
||||||
{
|
{
|
||||||
host_path = "/mnt/zwing/config/navidrome"
|
host_path = "/mnt/xwing/data/navidrome"
|
||||||
container_path = "/data"
|
container_path = "/data"
|
||||||
},{
|
|
||||||
host_path = "/mnt/zwing/cache/navidrome"
|
|
||||||
container_path = "/data/cache"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host_path = "/mnt/xwing/media/Music"
|
host_path = "/mnt/xwing/media/Music"
|
||||||
|
|
|
@ -3,7 +3,8 @@ resource "docker_network" "media" {
|
||||||
driver = "bridge"
|
driver = "bridge"
|
||||||
|
|
||||||
ipam_config {
|
ipam_config {
|
||||||
subnet = "172.18.0.0/24"
|
subnet = "172.18.0.0/16"
|
||||||
gateway = "172.18.0.1"
|
gateway = "172.18.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
module "prowlarr" {
|
|
||||||
name = "prowlarr"
|
|
||||||
source = "../modules/container"
|
|
||||||
image = "linuxserver/prowlarr:nightly"
|
|
||||||
|
|
||||||
web = {
|
|
||||||
expose = true
|
|
||||||
port = 9696
|
|
||||||
host = "prowlarr.${var.domain}"
|
|
||||||
auth = true
|
|
||||||
}
|
|
||||||
|
|
||||||
resource = {
|
|
||||||
memory = 512
|
|
||||||
memory_swap = 1024
|
|
||||||
}
|
|
||||||
|
|
||||||
volumes = [
|
|
||||||
{
|
|
||||||
host_path = "/mnt/xwing/config/prowlarr"
|
|
||||||
container_path = "/config"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
env = [
|
|
||||||
"PUID=1004",
|
|
||||||
"PGID=1003",
|
|
||||||
"TZ=Asia/Kolkata",
|
|
||||||
]
|
|
||||||
|
|
||||||
networks = [docker_network.media.id, data.docker_network.bridge.id]
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ module "radarr" {
|
||||||
source = "../modules/container"
|
source = "../modules/container"
|
||||||
image = "linuxserver/radarr:latest"
|
image = "linuxserver/radarr:latest"
|
||||||
|
|
||||||
networks = [docker_network.media.id, data.docker_network.bridge.id]
|
# TODO FIXME
|
||||||
|
# networks = [docker_network.media.id, data.docker_network.bridge.id]
|
||||||
|
|
||||||
web = {
|
web = {
|
||||||
expose = true
|
expose = true
|
||||||
|
@ -18,14 +19,9 @@ module "radarr" {
|
||||||
|
|
||||||
volumes = [
|
volumes = [
|
||||||
{
|
{
|
||||||
host_path = "/mnt/zwing/config/radarr"
|
host_path = "/mnt/xwing/config/radarr"
|
||||||
container_path = "/config"
|
container_path = "/config"
|
||||||
},
|
},
|
||||||
# Backups stay on spinning disks
|
|
||||||
{
|
|
||||||
host_path = "/mnt/xwing/backups/config/sonarr"
|
|
||||||
container_path = "/config/Backups"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
host_path = "/mnt/xwing/media/DL"
|
host_path = "/mnt/xwing/media/DL"
|
||||||
container_path = "/downloads"
|
container_path = "/downloads"
|
||||||
|
|
|
@ -21,6 +21,7 @@ module "requestrr" {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
networks = [docker_network.media.id, data.docker_network.bridge.id]
|
# TODO FIXME
|
||||||
|
# networks = [docker_network.media.id, data.docker_network.bridge.id]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,9 @@ module "sonarr-container" {
|
||||||
|
|
||||||
volumes = [
|
volumes = [
|
||||||
{
|
{
|
||||||
host_path = "/mnt/zwing/config/sonarr"
|
host_path = "/mnt/xwing/config/sonarr"
|
||||||
container_path = "/config"
|
container_path = "/config"
|
||||||
},
|
},
|
||||||
# Backups stay on spinning disks
|
|
||||||
{
|
|
||||||
host_path = "/mnt/xwing/backups/config/sonarr"
|
|
||||||
container_path = "/config/Backups"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
host_path = "/mnt/xwing/media/DL"
|
host_path = "/mnt/xwing/media/DL"
|
||||||
container_path = "/downloads"
|
container_path = "/downloads"
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
locals {
|
|
||||||
transmission_labels = merge(var.traefik-labels, {
|
|
||||||
"traefik.frontend.auth.basic" = var.basic_auth
|
|
||||||
"traefik.port" = 9091
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "docker_container" "transmission" {
|
resource "docker_container" "transmission" {
|
||||||
name = "transmission"
|
name = "transmission"
|
||||||
image = docker_image.transmission.image_id
|
image = docker_image.transmission.latest
|
||||||
|
|
||||||
dynamic "labels" {
|
labels = merge(
|
||||||
for_each = local.transmission_labels
|
var.traefik-labels,
|
||||||
content {
|
{
|
||||||
label = labels.key
|
"traefik.frontend.auth.basic" = var.basic_auth
|
||||||
value = labels.value
|
"traefik.port" = 9091
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
|
|
||||||
ports {
|
ports {
|
||||||
internal = 51413
|
internal = 51413
|
||||||
|
@ -34,11 +27,6 @@ resource "docker_container" "transmission" {
|
||||||
container_path = "/downloads"
|
container_path = "/downloads"
|
||||||
}
|
}
|
||||||
|
|
||||||
volumes {
|
|
||||||
host_path = "/mnt/xwing/media/Music/Audiobooks"
|
|
||||||
container_path = "/audiobooks"
|
|
||||||
}
|
|
||||||
|
|
||||||
volumes {
|
volumes {
|
||||||
host_path = "/mnt/xwing/data/watch/transmission"
|
host_path = "/mnt/xwing/data/watch/transmission"
|
||||||
container_path = "/watch"
|
container_path = "/watch"
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
14
miniflux.tf
14
miniflux.tf
|
@ -1,7 +1,7 @@
|
||||||
module "miniflux-container" {
|
module "miniflux-container" {
|
||||||
name = "miniflux"
|
name = "miniflux"
|
||||||
source = "./modules/container"
|
source = "./modules/container"
|
||||||
image = "miniflux/miniflux:2.0.50"
|
image = "miniflux/miniflux:2.0.28"
|
||||||
|
|
||||||
web = {
|
web = {
|
||||||
expose = true
|
expose = true
|
||||||
|
@ -9,17 +9,17 @@ module "miniflux-container" {
|
||||||
host = "rss.captnemo.in"
|
host = "rss.captnemo.in"
|
||||||
}
|
}
|
||||||
|
|
||||||
networks = ["bridge", "postgres"]
|
# TODO FIXME
|
||||||
|
# networks = [
|
||||||
|
# data.docker_network.bridge.id,
|
||||||
|
# module.docker.traefik-network-id,
|
||||||
|
# module.db.postgres-network-id,
|
||||||
|
# ]
|
||||||
|
|
||||||
env = [
|
env = [
|
||||||
"DATABASE_URL=postgres://miniflux:${data.pass_password.miniflux-db-password.password}@postgres/miniflux?sslmode=disable",
|
"DATABASE_URL=postgres://miniflux:${data.pass_password.miniflux-db-password.password}@postgres/miniflux?sslmode=disable",
|
||||||
"RUN_MIGRATIONS=1",
|
"RUN_MIGRATIONS=1",
|
||||||
]
|
]
|
||||||
|
|
||||||
resource = {
|
|
||||||
memory = 512
|
|
||||||
memory_swap = 1024
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module "miniflux-db" {
|
module "miniflux-db" {
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
data "docker_registry_image" "image" {
|
|
||||||
name = var.image
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "docker_image" "image" {
|
|
||||||
name = var.image
|
|
||||||
pull_triggers = [data.docker_registry_image.image.sha256_digest]
|
|
||||||
keep_locally = var.keep_image
|
|
||||||
}
|
|
|
@ -4,9 +4,14 @@ locals {
|
||||||
}
|
}
|
||||||
|
|
||||||
web = {
|
web = {
|
||||||
"traefik.port" = var.web.port != null ? var.web.port : 80
|
"traefik.port" = lookup(var.web, "port", "80")
|
||||||
"traefik.frontend.rule" = var.web.host != null ? "Host:${var.web.host}" : "Host:example.invalid"
|
"traefik.frontend.rule" = "Host:${lookup(var.web, "host", "example.invalid")}"
|
||||||
"traefik.protocol" = var.web.protocol != null ? var.web.protocol : "http"
|
"traefik.protocol" = lookup(var.web, "protocol", "http")
|
||||||
|
}
|
||||||
|
|
||||||
|
resource = {
|
||||||
|
memory = lookup(var.resource, "memory", 64)
|
||||||
|
memory_swap = lookup(var.resource, "memory_swap", 128)
|
||||||
}
|
}
|
||||||
|
|
||||||
traefik_common_labels = {
|
traefik_common_labels = {
|
||||||
|
@ -22,28 +27,8 @@ locals {
|
||||||
"traefik.docker.network" = "traefik"
|
"traefik.docker.network" = "traefik"
|
||||||
}
|
}
|
||||||
|
|
||||||
# if var.web.auth == true
|
|
||||||
traefik_auth_labels = {
|
traefik_auth_labels = {
|
||||||
"traefik.frontend.auth.basic" = var.auth_header
|
"traefik.frontend.auth.basic" = var.auth_header
|
||||||
}
|
}
|
||||||
|
|
||||||
resource = {
|
|
||||||
memory = lookup(var.resource, "memory", 64)
|
|
||||||
memory_swap = lookup(var.resource, "memory_swap", 128)
|
|
||||||
}
|
|
||||||
|
|
||||||
labels = merge(
|
|
||||||
# Default labels are applied to every container
|
|
||||||
local.default_labels,
|
|
||||||
# Add the common traefik labels
|
|
||||||
var.web.expose ? local.traefik_common_labels : null,
|
|
||||||
# Apply the overwritten web labels only if the container is exposed
|
|
||||||
var.web.expose ? local.web : null,
|
|
||||||
# And finally a label for Basic Authentication if the service wants it
|
|
||||||
var.web.auth != null ? (var.web.auth ? local.traefik_auth_labels : null) : null,
|
|
||||||
|
|
||||||
var.labels,
|
|
||||||
)
|
|
||||||
|
|
||||||
networks = concat(var.networks, var.web.expose ? ["traefik"] : [])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,20 @@
|
||||||
|
data "docker_registry_image" "image" {
|
||||||
|
name = var.image
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "docker_image" "image" {
|
||||||
|
name = var.image
|
||||||
|
pull_triggers = [data.docker_registry_image.image.sha256_digest]
|
||||||
|
keep_locally = var.keep_image
|
||||||
|
}
|
||||||
|
|
||||||
|
data "docker_network" "traefik" {
|
||||||
|
name = "traefik"
|
||||||
|
}
|
||||||
|
|
||||||
resource "docker_container" "container" {
|
resource "docker_container" "container" {
|
||||||
name = var.name
|
name = var.name
|
||||||
image = docker_image.image.image_id
|
image = docker_image.image.latest
|
||||||
|
|
||||||
dynamic "ports" {
|
dynamic "ports" {
|
||||||
for_each = var.ports
|
for_each = var.ports
|
||||||
content {
|
content {
|
||||||
|
@ -17,12 +30,8 @@ resource "docker_container" "container" {
|
||||||
entrypoint = var.entrypoint
|
entrypoint = var.entrypoint
|
||||||
user = var.user
|
user = var.user
|
||||||
|
|
||||||
privileged = var.privileged
|
|
||||||
|
|
||||||
network_mode = var.network_mode
|
network_mode = var.network_mode
|
||||||
|
|
||||||
gpus = var.gpu ? "all" : ""
|
|
||||||
|
|
||||||
dynamic "capabilities" {
|
dynamic "capabilities" {
|
||||||
for_each = [var.capabilities]
|
for_each = [var.capabilities]
|
||||||
content {
|
content {
|
||||||
|
@ -32,9 +41,17 @@ resource "docker_container" "container" {
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic "networks_advanced" {
|
dynamic "networks_advanced" {
|
||||||
for_each = local.networks
|
for_each = [var.networks_advanced]
|
||||||
content {
|
content {
|
||||||
name = networks_advanced.value
|
# TF-UPGRADE-TODO: The automatic upgrade tool can't predict
|
||||||
|
# which keys might be set in maps assigned here, so it has
|
||||||
|
# produced a comprehensive set here. Consider simplifying
|
||||||
|
# this after confirming which keys can be set in practice.
|
||||||
|
|
||||||
|
aliases = lookup(networks_advanced.value, "aliases", null)
|
||||||
|
ipv4_address = lookup(networks_advanced.value, "ipv4_address", null)
|
||||||
|
ipv6_address = lookup(networks_advanced.value, "ipv6_address", null)
|
||||||
|
name = networks_advanced.value.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +59,13 @@ resource "docker_container" "container" {
|
||||||
memory_swap = local.resource["memory_swap"]
|
memory_swap = local.resource["memory_swap"]
|
||||||
|
|
||||||
dynamic "volumes" {
|
dynamic "volumes" {
|
||||||
for_each = var.volumes
|
for_each = [var.volumes]
|
||||||
content {
|
content {
|
||||||
|
# TF-UPGRADE-TODO: The automatic upgrade tool can't predict
|
||||||
|
# which keys might be set in maps assigned here, so it has
|
||||||
|
# produced a comprehensive set here. Consider simplifying
|
||||||
|
# this after confirming which keys can be set in practice.
|
||||||
|
|
||||||
container_path = lookup(volumes.value, "container_path", null)
|
container_path = lookup(volumes.value, "container_path", null)
|
||||||
from_container = lookup(volumes.value, "from_container", null)
|
from_container = lookup(volumes.value, "from_container", null)
|
||||||
host_path = lookup(volumes.value, "host_path", null)
|
host_path = lookup(volumes.value, "host_path", null)
|
||||||
|
@ -51,36 +73,121 @@ resource "docker_container" "container" {
|
||||||
volume_name = lookup(volumes.value, "volume_name", null)
|
volume_name = lookup(volumes.value, "volume_name", null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic "devices" {
|
dynamic "devices" {
|
||||||
for_each = var.devices
|
for_each = [var.devices]
|
||||||
content {
|
content {
|
||||||
host_path = devices.value["host_path"]
|
# TF-UPGRADE-TODO: The automatic upgrade tool can't predict
|
||||||
container_path = devices.value["container_path"]
|
# which keys might be set in maps assigned here, so it has
|
||||||
permissions = devices.value["permissions"]
|
# produced a comprehensive set here. Consider simplifying
|
||||||
|
# this after confirming which keys can be set in practice.
|
||||||
|
|
||||||
|
container_path = lookup(devices.value, "container_path", null)
|
||||||
|
host_path = devices.value.host_path
|
||||||
|
permissions = lookup(devices.value, "permissions", null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic "upload" {
|
dynamic "upload" {
|
||||||
for_each = var.uploads
|
for_each = [var.uploads]
|
||||||
content {
|
content {
|
||||||
file = lookup(upload.value, "file", null)
|
# TF-UPGRADE-TODO: The automatic upgrade tool can't predict
|
||||||
|
# which keys might be set in maps assigned here, so it has
|
||||||
|
# produced a comprehensive set here. Consider simplifying
|
||||||
|
# this after confirming which keys can be set in practice.
|
||||||
|
|
||||||
content = lookup(upload.value, "content", null)
|
content = lookup(upload.value, "content", null)
|
||||||
content_base64 = lookup(upload.value, "content_base64", null)
|
content_base64 = lookup(upload.value, "content_base64", null)
|
||||||
executable = lookup(upload.value, "executable", null)
|
executable = lookup(upload.value, "executable", null)
|
||||||
|
file = upload.value.file
|
||||||
source = lookup(upload.value, "source", null)
|
source = lookup(upload.value, "source", null)
|
||||||
source_hash = lookup(upload.value, "source_hash", null)
|
source_hash = lookup(upload.value, "source_hash", null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Look at this monstrosity
|
||||||
|
# And then https://github.com/hashicorp/terraform/issues/12453#issuecomment-365569618
|
||||||
|
# for why this is needed
|
||||||
|
|
||||||
dynamic "labels" {
|
dynamic "labels" {
|
||||||
for_each = local.labels
|
for_each = merge(
|
||||||
|
local.default_labels,
|
||||||
|
zipmap(
|
||||||
|
concat(
|
||||||
|
keys(local.default_labels),
|
||||||
|
split(
|
||||||
|
"~",
|
||||||
|
lookup(var.web, "expose", "false") == "false" ? "" : join("~", keys(local.traefik_common_labels)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
concat(
|
||||||
|
values(local.default_labels),
|
||||||
|
split(
|
||||||
|
"~",
|
||||||
|
lookup(var.web, "expose", "false") == "false" ? "" : join("~", values(local.traefik_common_labels)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
zipmap(
|
||||||
|
concat(
|
||||||
|
keys(local.default_labels),
|
||||||
|
split(
|
||||||
|
"~",
|
||||||
|
lookup(var.web, "expose", "false") == "false" ? "" : join("~", keys(local.web)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
concat(
|
||||||
|
values(local.default_labels),
|
||||||
|
split(
|
||||||
|
"~",
|
||||||
|
lookup(var.web, "expose", "false") == "false" ? "" : join("~", values(local.web)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
zipmap(
|
||||||
|
concat(
|
||||||
|
keys(local.default_labels),
|
||||||
|
split(
|
||||||
|
"~",
|
||||||
|
lookup(var.web, "expose", "false") == "false" ? "" : join("~", keys(local.traefik_common_labels)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
concat(
|
||||||
|
values(local.default_labels),
|
||||||
|
split(
|
||||||
|
"~",
|
||||||
|
lookup(var.web, "expose", "false") == "false" ? "" : join("~", values(local.traefik_common_labels)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
zipmap(
|
||||||
|
concat(
|
||||||
|
keys(local.default_labels),
|
||||||
|
split(
|
||||||
|
"~",
|
||||||
|
lookup(var.web, "auth", "false") == "false" ? "" : join("~", keys(local.traefik_auth_labels)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
concat(
|
||||||
|
values(local.default_labels),
|
||||||
|
split(
|
||||||
|
"~",
|
||||||
|
lookup(var.web, "auth", "false") == "false" ? "" : join("~", values(local.traefik_auth_labels)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
content {
|
content {
|
||||||
label = labels.key
|
# TF-UPGRADE-TODO: The automatic upgrade tool can't predict
|
||||||
value = labels.value
|
# which keys might be set in maps assigned here, so it has
|
||||||
|
# produced a comprehensive set here. Consider simplifying
|
||||||
|
# this after confirming which keys can be set in practice.
|
||||||
|
|
||||||
|
label = labels.value.label
|
||||||
|
value = labels.value.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_grace_seconds = var.destroy_grace_seconds
|
destroy_grace_seconds = var.destroy_grace_seconds
|
||||||
must_run = var.must_run
|
must_run = var.must_run
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,14 +8,16 @@ variable "name" {
|
||||||
|
|
||||||
variable "ports" {
|
variable "ports" {
|
||||||
description = "list of port mappings"
|
description = "list of port mappings"
|
||||||
type = list(map(string))
|
type = list(string)
|
||||||
default = []
|
default = []
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "networks" {
|
variable "networks_advanced" {
|
||||||
description = "list of names of networks to attach to"
|
description = "list of networks_advanced"
|
||||||
type = list(string)
|
type = map
|
||||||
default = []
|
default = {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "restart" {
|
variable "restart" {
|
||||||
|
@ -57,7 +59,7 @@ variable "env" {
|
||||||
|
|
||||||
variable "labels" {
|
variable "labels" {
|
||||||
description = "labels"
|
description = "labels"
|
||||||
default = {}
|
default = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "xpoweredby" {
|
variable "xpoweredby" {
|
||||||
|
@ -66,20 +68,10 @@ variable "xpoweredby" {
|
||||||
|
|
||||||
variable "web" {
|
variable "web" {
|
||||||
description = "Web Configuration"
|
description = "Web Configuration"
|
||||||
type = object({
|
|
||||||
expose = bool
|
|
||||||
auth = optional(bool)
|
|
||||||
port = optional(number)
|
|
||||||
host = optional(string)
|
|
||||||
protocol = optional(string)
|
|
||||||
})
|
|
||||||
|
|
||||||
default = {
|
default = {
|
||||||
expose = false
|
expose = "false"
|
||||||
auth = false
|
auth = "false"
|
||||||
port = 80
|
|
||||||
host = ""
|
|
||||||
protocol = "http"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,11 +94,6 @@ variable "volumes" {
|
||||||
default = {}
|
default = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "privileged" {
|
|
||||||
description = " If true, the container runs in privileged mode."
|
|
||||||
default = false
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "capabilities" {
|
variable "capabilities" {
|
||||||
description = "capabilities"
|
description = "capabilities"
|
||||||
|
|
||||||
|
@ -117,10 +104,8 @@ variable "capabilities" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "devices" {
|
variable "devices" {
|
||||||
description = "list of devices"
|
description = "devices"
|
||||||
type = list(map(string))
|
default = {}
|
||||||
|
|
||||||
default = []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "keep_image" {
|
variable "keep_image" {
|
||||||
|
@ -129,20 +114,6 @@ variable "keep_image" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "uploads" {
|
variable "uploads" {
|
||||||
description = "Files to Upload"
|
|
||||||
type = list(object({
|
|
||||||
file = string
|
|
||||||
content = optional(string)
|
|
||||||
content_base64 = optional(string)
|
|
||||||
executable = optional(bool)
|
|
||||||
source = optional(string)
|
|
||||||
source_hash = optional(string)
|
|
||||||
}))
|
|
||||||
|
|
||||||
default = []
|
default = []
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "gpu" {
|
|
||||||
type = bool
|
|
||||||
default = false
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -12,6 +12,6 @@ resource "docker_image" "image" {
|
||||||
}
|
}
|
||||||
|
|
||||||
output "image" {
|
output "image" {
|
||||||
value = docker_image.image.image_id
|
value = docker_image.image.latest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
resource "docker_container" "redis" {
|
resource "docker_container" "redis" {
|
||||||
name = "outline-redis"
|
name = "outline-redis"
|
||||||
image = "${docker_image.redis.image_id}"
|
image = "${docker_image.redis.latest}"
|
||||||
|
|
||||||
volumes {
|
volumes {
|
||||||
host_path = "/mnt/xwing/cache/outline"
|
host_path = "/mnt/xwing/cache/outline"
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
data "docker_registry_image" "act-exporter" {
|
||||||
|
name = "captn3m0/prometheus-act-exporter:latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "docker_container" "act-exporter" {
|
||||||
|
name = "act-exporter"
|
||||||
|
image = docker_image.act-exporter.latest
|
||||||
|
|
||||||
|
entrypoint = ["/usr/local/bin/node", "server.js"]
|
||||||
|
|
||||||
|
networks_advanced {
|
||||||
|
name = "monitoring"
|
||||||
|
aliases = ["act-exporter", "act-exporter.docker"]
|
||||||
|
}
|
||||||
|
|
||||||
|
// So it can talk to ACT
|
||||||
|
networks_advanced {
|
||||||
|
name = "bridge"
|
||||||
|
}
|
||||||
|
|
||||||
|
restart = "unless-stopped"
|
||||||
|
destroy_grace_seconds = 10
|
||||||
|
must_run = true
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module "cadvisor" {
|
module "cadvisor" {
|
||||||
source = "../modules/container"
|
source = "../modules/container"
|
||||||
name = "cadvisor"
|
name = "cadvisor"
|
||||||
image = "gcr.io/cadvisor/cadvisor"
|
image = "google/cadvisor:latest"
|
||||||
|
|
||||||
resource = {
|
resource = {
|
||||||
memory = 512
|
memory = 512
|
||||||
|
@ -11,7 +11,6 @@ module "cadvisor" {
|
||||||
restart = "unless-stopped"
|
restart = "unless-stopped"
|
||||||
destroy_grace_seconds = 10
|
destroy_grace_seconds = 10
|
||||||
must_run = true
|
must_run = true
|
||||||
privileged = true
|
|
||||||
|
|
||||||
volumes = [
|
volumes = [
|
||||||
{
|
{
|
||||||
|
@ -37,11 +36,17 @@ module "cadvisor" {
|
||||||
{
|
{
|
||||||
host_path = "/var/run"
|
host_path = "/var/run"
|
||||||
container_path = "/var/run"
|
container_path = "/var/run"
|
||||||
read_only = true
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
networks = ["monitoring"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "traefik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "monitoring"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
web = {
|
web = {
|
||||||
expose = true
|
expose = true
|
||||||
|
|
|
@ -34,5 +34,11 @@ scrape_configs:
|
||||||
static_configs:
|
static_configs:
|
||||||
- targets: ["192.168.1.111:1111"]
|
- targets: ["192.168.1.111:1111"]
|
||||||
|
|
||||||
|
- job_name: "act"
|
||||||
|
scrape_interval: 1h
|
||||||
|
scrape_timeout: 1m
|
||||||
|
static_configs:
|
||||||
|
- targets: ["act-exporter:3000"]
|
||||||
|
|
||||||
rule_files:
|
rule_files:
|
||||||
- "alert.rules"
|
- "alert.rules"
|
||||||
|
|
|
@ -2,15 +2,10 @@
|
||||||
module "grafana" {
|
module "grafana" {
|
||||||
name = "grafana"
|
name = "grafana"
|
||||||
source = "../modules/container"
|
source = "../modules/container"
|
||||||
image = "grafana/grafana-oss:latest"
|
image = "grafana/grafana:latest"
|
||||||
|
|
||||||
// grafana
|
// grafana:grafana
|
||||||
user = "472"
|
user = "984:982"
|
||||||
|
|
||||||
resource = {
|
|
||||||
memory = 512
|
|
||||||
memory_swap = 512
|
|
||||||
}
|
|
||||||
|
|
||||||
web = {
|
web = {
|
||||||
port = 3000
|
port = 3000
|
||||||
|
@ -25,7 +20,14 @@ module "grafana" {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
networks = ["monitoring"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "traefik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "monitoring"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
env = [
|
env = [
|
||||||
"GF_SERVER_ROOT_URL=https://grafana.${var.domain}",
|
"GF_SERVER_ROOT_URL=https://grafana.${var.domain}",
|
||||||
|
|
|
@ -2,3 +2,10 @@ resource "docker_image" "prometheus" {
|
||||||
name = data.docker_registry_image.prometheus.name
|
name = data.docker_registry_image.prometheus.name
|
||||||
pull_triggers = [data.docker_registry_image.prometheus.sha256_digest]
|
pull_triggers = [data.docker_registry_image.prometheus.sha256_digest]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "docker_image" "act-exporter" {
|
||||||
|
name = data.docker_registry_image.act-exporter.name
|
||||||
|
pull_triggers = [data.docker_registry_image.act-exporter.sha256_digest]
|
||||||
|
keep_locally = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
resource "docker_container" "prometheus" {
|
resource "docker_container" "prometheus" {
|
||||||
name = "prometheus"
|
name = "prometheus"
|
||||||
image = docker_image.prometheus.image_id
|
image = docker_image.prometheus.latest
|
||||||
|
|
||||||
# prometheus:prometheus
|
# prometheus:prometheus
|
||||||
user = "985:983"
|
user = "985:983"
|
||||||
|
@ -29,7 +29,18 @@ resource "docker_container" "prometheus" {
|
||||||
file = "/etc/prometheus/prometheus.yml"
|
file = "/etc/prometheus/prometheus.yml"
|
||||||
}
|
}
|
||||||
|
|
||||||
networks = ["monitoring", "bridge"]
|
networks_advanced {
|
||||||
|
name = "monitoring"
|
||||||
|
}
|
||||||
|
|
||||||
|
networks_advanced {
|
||||||
|
name = "bridge"
|
||||||
|
}
|
||||||
|
|
||||||
|
networks = [
|
||||||
|
data.docker_network.bridge.id,
|
||||||
|
docker_network.monitoring.id,
|
||||||
|
]
|
||||||
|
|
||||||
restart = "unless-stopped"
|
restart = "unless-stopped"
|
||||||
destroy_grace_seconds = 10
|
destroy_grace_seconds = 10
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,7 +7,15 @@ module "speedtest" {
|
||||||
image = "captn3m0/speedtest-exporter:alpine"
|
image = "captn3m0/speedtest-exporter:alpine"
|
||||||
source = "../modules/container"
|
source = "../modules/container"
|
||||||
|
|
||||||
networks = ["monitoring"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "monitoring"
|
||||||
|
aliases = ["speedtest", "speedtest.docker"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "bridge"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
resource = {
|
resource = {
|
||||||
memory = 256
|
memory = 256
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
23
nextcloud.tf
23
nextcloud.tf
|
@ -37,7 +37,17 @@ module "nextcloud-container" {
|
||||||
host = "c.${var.root-domain}"
|
host = "c.${var.root-domain}"
|
||||||
}
|
}
|
||||||
|
|
||||||
networks = ["nextcloud", "postgres"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "traefik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "nextcloud"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "postgres"
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "docker_network" "nextcloud" {
|
resource "docker_network" "nextcloud" {
|
||||||
|
@ -51,7 +61,16 @@ module "nextcloud-redis" {
|
||||||
image = "redis:alpine"
|
image = "redis:alpine"
|
||||||
keep_image = true
|
keep_image = true
|
||||||
|
|
||||||
networks = ["nextcloud"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "nextcloud"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
# ThisSucks
|
||||||
|
web = {
|
||||||
|
expose = "false"
|
||||||
|
}
|
||||||
|
|
||||||
resource = {
|
resource = {
|
||||||
memory = 256
|
memory = 256
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
33
providers.tf
33
providers.tf
|
@ -1,14 +1,23 @@
|
||||||
provider "docker" {
|
provider "docker" {
|
||||||
host = "tcp://docker.vpn.bb8.fun:2376"
|
host = "tcp://docker.vpn.bb8.fun:2376"
|
||||||
cert_path = "./secrets/tatooine"
|
cert_path = "./secrets/tatooine"
|
||||||
|
version = "~> 2.2.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "docker" {
|
provider "docker" {
|
||||||
host = "tcp://docker.dovpn.bb8.fun:2376"
|
host = "tcp://docker.dovpn.bb8.fun:2376"
|
||||||
cert_path = "./secrets/sydney"
|
cert_path = "./secrets/sydney"
|
||||||
|
version = "~> 2.2.0"
|
||||||
alias = "sydney"
|
alias = "sydney"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provider "kubernetes" {
|
||||||
|
# version = "1.3.0-custom"
|
||||||
|
host = "https://k8s.bb8.fun:6443"
|
||||||
|
|
||||||
|
config_path = "${path.root}/k8s/auth/kubeconfig"
|
||||||
|
}
|
||||||
|
|
||||||
provider "cloudflare" {
|
provider "cloudflare" {
|
||||||
email = "bb8@captnemo.in"
|
email = "bb8@captnemo.in"
|
||||||
api_key = data.pass_password.cloudflare_key.password
|
api_key = data.pass_password.cloudflare_key.password
|
||||||
|
@ -27,27 +36,7 @@ provider "digitalocean" {
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "pass" {
|
provider "pass" {
|
||||||
|
store_dir = "/home/nemo/.password-store/Nebula/"
|
||||||
|
refresh_store = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
terraform {
|
|
||||||
required_version = ">= 1.3.0"
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
version = "~> 2.23"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,24 +5,21 @@ hosts = 0.0.0.0:5232
|
||||||
# Max parallel connections
|
# Max parallel connections
|
||||||
max_connections = 10
|
max_connections = 10
|
||||||
|
|
||||||
|
# Message displayed in the client when a password is needed
|
||||||
|
realm = Authentication required
|
||||||
|
|
||||||
[auth]
|
[auth]
|
||||||
|
|
||||||
# Authentication method
|
# Authentication method
|
||||||
# Value: none | htpasswd | remote_user | http_x_remote_user
|
# Value: none | htpasswd | remote_user | http_x_remote_user
|
||||||
type = htpasswd
|
type = htpasswd
|
||||||
htpasswd_filename = /config/users
|
htpasswd_filename = /config/users
|
||||||
htpasswd_encryption = bcrypt
|
|
||||||
|
|
||||||
# Message displayed in the client when a password is needed
|
|
||||||
realm = Authentication required
|
|
||||||
|
|
||||||
[storage]
|
[storage]
|
||||||
filesystem_folder = /data/collections
|
filesystem_folder = /data/collections
|
||||||
|
|
||||||
[logging]
|
[logging]
|
||||||
|
|
||||||
level = warning
|
|
||||||
|
|
||||||
# For more information about the syntax of the configuration file, see:
|
# For more information about the syntax of the configuration file, see:
|
||||||
# http://docs.python.org/library/logging.config.html
|
# http://docs.python.org/library/logging.config.html
|
||||||
# config = /config/logging
|
# config = /config/logging
|
||||||
|
|
|
@ -4,39 +4,97 @@ module "container" {
|
||||||
image = "tomsquest/docker-radicale:amd64"
|
image = "tomsquest/docker-radicale:amd64"
|
||||||
|
|
||||||
resource = {
|
resource = {
|
||||||
memory = 2000
|
memory = 512
|
||||||
memory_swap = 2000
|
memory_swap = 512
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO Drop Capabilities
|
|
||||||
# https://github.com/tomsquest/docker-radicale#option-2-recommended-production-grade-instruction-secured-safe-rocket
|
|
||||||
|
|
||||||
web = {
|
web = {
|
||||||
expose = true
|
expose = true
|
||||||
port = 5232
|
port = 5232
|
||||||
host = var.domain
|
host = var.domain
|
||||||
}
|
}
|
||||||
|
|
||||||
# SSD
|
|
||||||
volumes = [
|
volumes = [
|
||||||
{
|
{
|
||||||
host_path = "/mnt/zwing/config/radicale"
|
host_path = "/mnt/xwing/data/radicale"
|
||||||
container_path = "/data"
|
container_path = "/data"
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
host_path = "/mnt/xwing/config/radicale"
|
||||||
|
container_path = "/config"
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
uploads = [
|
uploads = [
|
||||||
{
|
{
|
||||||
content = file("${path.module}/config")
|
content = <<EOT
|
||||||
file = "/config/config"
|
# See radicale.org/configuration/
|
||||||
|
[server]
|
||||||
|
hosts = 0.0.0.0:5232
|
||||||
|
|
||||||
|
# Max parallel connections
|
||||||
|
max_connections = 10
|
||||||
|
|
||||||
|
# Message displayed in the client when a password is needed
|
||||||
|
realm = Authentication required
|
||||||
|
|
||||||
|
[auth]
|
||||||
|
|
||||||
|
# Authentication method
|
||||||
|
# Value: none | htpasswd | remote_user | http_x_remote_user
|
||||||
|
type = htpasswd
|
||||||
|
htpasswd_filename = /config/users
|
||||||
|
|
||||||
|
[storage]
|
||||||
|
filesystem_folder = /data/collections
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
|
||||||
|
# For more information about the syntax of the configuration file, see:
|
||||||
|
# http://docs.python.org/library/logging.config.html
|
||||||
|
# config = /config/logging
|
||||||
|
|
||||||
|
[headers]
|
||||||
|
|
||||||
|
# Additional HTTP headers
|
||||||
|
X-Powered-By: Allomancy
|
||||||
|
Server: Blackbox
|
||||||
|
EOT
|
||||||
|
|
||||||
|
file = "/config/config"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content = file("${path.module}/logging.conf")
|
content = <<EOT
|
||||||
file = "/config/logging"
|
[loggers]
|
||||||
|
keys = root
|
||||||
|
|
||||||
|
[handlers]
|
||||||
|
keys = file
|
||||||
|
|
||||||
|
[formatters]
|
||||||
|
keys = full
|
||||||
|
|
||||||
|
[logger_root]
|
||||||
|
# Change this to DEBUG or INFO for higher verbosity.
|
||||||
|
level = WARNING
|
||||||
|
handlers = file
|
||||||
|
|
||||||
|
[handler_file]
|
||||||
|
class = FileHandler
|
||||||
|
# Specify the output file here.
|
||||||
|
args = ('/var/log/radicale/log',)
|
||||||
|
formatter = full
|
||||||
|
|
||||||
|
[formatter_full]
|
||||||
|
format = %(asctime)s - [%(thread)x] %(levelname)s: %(message)s
|
||||||
|
EOT
|
||||||
|
|
||||||
|
file = "/config/logging"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content = file("${path.module}/users")
|
content = "nemo:$2y$05$vC1WTAuKn2xuDYZ6I3ucxuPnCrtZrVKzdDHSYhqCegi97RM/pdzXW"
|
||||||
file = "/config/users"
|
file = "/config/users"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ module "rss-bridge" {
|
||||||
name = "rss-bridge"
|
name = "rss-bridge"
|
||||||
source = "./modules/container"
|
source = "./modules/container"
|
||||||
|
|
||||||
image = "ghcr.io/rss-bridge/rss-bridge:latest"
|
image = "captn3m0/rss-bridge:develop"
|
||||||
|
|
||||||
resource = {
|
resource = {
|
||||||
memory = 256
|
memory = 256
|
||||||
|
@ -14,7 +14,14 @@ module "rss-bridge" {
|
||||||
host = "rss-bridge.${var.root-domain}"
|
host = "rss-bridge.${var.root-domain}"
|
||||||
}
|
}
|
||||||
|
|
||||||
networks = ["bridge"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "external"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "traefik"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
volumes = [
|
volumes = [
|
||||||
{
|
{
|
||||||
|
|
108
secrets.tf
108
secrets.tf
|
@ -1,196 +1,174 @@
|
||||||
data "pass_password" "airsonic-smtp-password" {
|
data "pass_password" "airsonic-smtp-password" {
|
||||||
path = "Nebula/AIRSONIC_SMTP_PASSWORD"
|
path = "AIRSONIC_SMTP_PASSWORD"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "digitalocean-token" {
|
data "pass_password" "digitalocean-token" {
|
||||||
path = "Nebula/DO_TOKEN"
|
path = "DO_TOKEN"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "gitea-internal-token" {
|
data "pass_password" "gitea-internal-token" {
|
||||||
path = "Nebula/GITEA_INTERNAL_TOKEN"
|
path = "GITEA_INTERNAL_TOKEN"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "gitea-lfs-jwt-secret" {
|
data "pass_password" "gitea-lfs-jwt-secret" {
|
||||||
path = "Nebula/GITEA_LFS_JWT_SECRET"
|
path = "GITEA_LFS_JWT_SECRET"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "gitea-secret-key" {
|
data "pass_password" "gitea-secret-key" {
|
||||||
path = "Nebula/GITEA_SECRET_KEY"
|
path = "GITEA_SECRET_KEY"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "gitea-oauth2-jwt-secret" {
|
data "pass_password" "gitea-oauth2-jwt-secret" {
|
||||||
path = "Nebula/GITEA_OAUTH2_JWT_SECRET"
|
path = "GITEA_OAUTH2_JWT_SECRET"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "gf-security-admin-password" {
|
data "pass_password" "gf-security-admin-password" {
|
||||||
path = "Nebula/GRAFANA_ADMIN_PASSWORD"
|
path = "GRAFANA_ADMIN_PASSWORD"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "gitea-smtp-password" {
|
data "pass_password" "gitea-smtp-password" {
|
||||||
path = "Nebula/GITEA_SMTP_PASSWORD"
|
path = "GITEA_SMTP_PASSWORD"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "miniflux-db-password" {
|
data "pass_password" "miniflux-db-password" {
|
||||||
path = "Nebula/MINIFLUX_DB_PASSWORD"
|
path = "MINIFLUX_DB_PASSWORD"
|
||||||
}
|
|
||||||
|
|
||||||
data "pass_password" "firesync-db-password" {
|
|
||||||
path = "Nebula/FIRESYNC_DB_PASSWORD"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "cloudflare_key" {
|
data "pass_password" "cloudflare_key" {
|
||||||
path = "Nebula/CLOUDFLARE_KEY"
|
path = "CLOUDFLARE_KEY"
|
||||||
}
|
}
|
||||||
|
|
||||||
// /me gives up on upper casing here and scripts it instead
|
// /me gives up on upper casing here and scripts it instead
|
||||||
|
|
||||||
data "pass_password" "monica-app-key" {
|
data "pass_password" "monica-app-key" {
|
||||||
path = "Nebula/monica-app-key"
|
path = "monica-app-key"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "monica-db-password" {
|
data "pass_password" "monica-db-password" {
|
||||||
path = "Nebula/monica-db-password"
|
path = "monica-db-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "monica-hash-salt" {
|
data "pass_password" "monica-hash-salt" {
|
||||||
path = "Nebula/monica-hash-salt"
|
path = "monica-hash-salt"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "monica-smtp-password" {
|
data "pass_password" "monica-smtp-password" {
|
||||||
path = "Nebula/monica-smtp-password"
|
path = "monica-smtp-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "nextcloud-db-password" {
|
data "pass_password" "nextcloud-db-password" {
|
||||||
path = "Nebula/nextcloud-db-password"
|
path = "nextcloud-db-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "opml-github-client-id" {
|
data "pass_password" "opml-github-client-id" {
|
||||||
path = "Nebula/opml-github-client-id"
|
path = "opml-github-client-id"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "opml-github-client-secret" {
|
data "pass_password" "opml-github-client-secret" {
|
||||||
path = "Nebula/opml-github-client-secret"
|
path = "opml-github-client-secret"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "outline_secret_key" {
|
data "pass_password" "outline_secret_key" {
|
||||||
path = "Nebula/outline-secret-key"
|
path = "outline-secret-key"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "outline_slack_app_id" {
|
data "pass_password" "outline_slack_app_id" {
|
||||||
path = "Nebula/outline-slack-app-id"
|
path = "outline-slack-app-id"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "outline_slack_key" {
|
data "pass_password" "outline_slack_key" {
|
||||||
path = "Nebula/outline-slack-key"
|
path = "outline-slack-key"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "outline_slack_secret" {
|
data "pass_password" "outline_slack_secret" {
|
||||||
path = "Nebula/outline-slack-secret"
|
path = "outline-slack-secret"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "outline_slack_verification_token" {
|
data "pass_password" "outline_slack_verification_token" {
|
||||||
path = "Nebula/outline-slack-verification-token"
|
path = "outline-slack-verification-token"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "outline_smtp_password" {
|
data "pass_password" "outline_smtp_password" {
|
||||||
path = "Nebula/outline-smtp-password"
|
path = "outline-smtp-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "pihole_password" {
|
data "pass_password" "pihole_password" {
|
||||||
path = "Nebula/pihole_password"
|
path = "pihole-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "syncserver_secret" {
|
data "pass_password" "syncserver_secret" {
|
||||||
path = "Nebula/SYNCSERVER_SECRET"
|
path = "SYNCSERVER_SECRET"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "timemachine-password-1" {
|
data "pass_password" "timemachine-password-1" {
|
||||||
path = "Nebula/timemachine-password-1"
|
path = "timemachine-password-1"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "timemachine-password-2" {
|
data "pass_password" "timemachine-password-2" {
|
||||||
path = "Nebula/timemachine-password-2"
|
path = "timemachine-password-2"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "postgres-root-password" {
|
data "pass_password" "postgres-root-password" {
|
||||||
path = "Nebula/postgres-root-password"
|
path = "postgres-root-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "znc_pass" {
|
data "pass_password" "znc_pass" {
|
||||||
path = "Nebula/znc-pass"
|
path = "znc-pass"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "znc_user" {
|
data "pass_password" "znc_user" {
|
||||||
path = "Nebula/znc-user"
|
path = "znc-user"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "wiki_session_secret" {
|
data "pass_password" "wiki_session_secret" {
|
||||||
path = "Nebula/wiki_session_secret"
|
path = "wiki_session_secret"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "web_username" {
|
data "pass_password" "web_username" {
|
||||||
path = "Nebula/web_username"
|
path = "web_username"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "web_password" {
|
data "pass_password" "web_password" {
|
||||||
path = "Nebula/web_password"
|
path = "web_password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "stringer-db-password" {
|
data "pass_password" "stringer-db-password" {
|
||||||
path = "Nebula/stringer-db-password"
|
path = "stringer-db-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "stringer-secret-token" {
|
data "pass_password" "stringer-secret-token" {
|
||||||
path = "Nebula/stringer-secret-token"
|
path = "stringer-secret-token"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "wiki-db-password" {
|
data "pass_password" "wiki-db-password" {
|
||||||
path = "Nebula/wiki-db-password"
|
path = "wiki-db-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "klaxon-db-password" {
|
data "pass_password" "klaxon-db-password" {
|
||||||
path = "Nebula/klaxon-db-password"
|
path = "klaxon-db-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "klaxon-secret-key" {
|
data "pass_password" "klaxon-secret-key" {
|
||||||
path = "Nebula/klaxon-secret-key"
|
path = "klaxon-secret-key"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "klaxon-sendgrid-password" {
|
data "pass_password" "klaxon-sendgrid-password" {
|
||||||
path = "Nebula/klaxon-sendgrid-password"
|
path = "klaxon-sendgrid-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "navidrome-lastfm-api-key" {
|
data "pass_password" "navidrome-lastfm-api-key" {
|
||||||
path = "Nebula/navidrome-lastfm-api-key"
|
path = "navidrome-lastfm-api-key"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "navidrome-lastfm-secret" {
|
data "pass_password" "navidrome-lastfm-secret" {
|
||||||
path = "Nebula/navidrome-lastfm-secret"
|
path = "navidrome-lastfm-secret"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "navidrome-spotify-id" {
|
data "pass_password" "navidrome-spotify-id" {
|
||||||
path = "Nebula/navidrome-spotify-id"
|
path = "navidrome-spotify-id"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "navidrome-spotify-secret" {
|
data "pass_password" "navidrome-spotify-secret" {
|
||||||
path = "Nebula/navidrome-spotify-secret"
|
path = "navidrome-spotify-secret"
|
||||||
}
|
}
|
||||||
|
|
||||||
data "pass_password" "mastodon-db-password" {
|
|
||||||
path = "Nebula/MASTODON_DB_PASSWORD"
|
|
||||||
}
|
|
||||||
data "pass_password" "mastodon-secret-key-base" {
|
|
||||||
path = "Nebula/MASTODON_SECRET_KEY_BASE"
|
|
||||||
}
|
|
||||||
data "pass_password" "mastodon-otp-secret" {
|
|
||||||
path = "Nebula/MASTODON_OTP_SECRET"
|
|
||||||
}
|
|
||||||
data "pass_password" "mastodon-vapid-private-key" {
|
|
||||||
path = "Nebula/MASTODON_VAPID_PRIVATE_KEY"
|
|
||||||
}
|
|
||||||
data "pass_password" "mastodon-vapid-public-key" {
|
|
||||||
path = "Nebula/MASTODON_VAPID_PUBLIC_KEY"
|
|
||||||
}
|
|
||||||
data "pass_password" "mastodon-smtp-password" {
|
|
||||||
path = "Nebula/MASTODON_SMTP_PASSWORD"
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ resource "docker_image" "timemachine" {
|
||||||
|
|
||||||
resource "docker_container" "timemachine" {
|
resource "docker_container" "timemachine" {
|
||||||
name = "timemachine"
|
name = "timemachine"
|
||||||
image = docker_image.timemachine.image_id
|
image = docker_image.timemachine.latest
|
||||||
|
|
||||||
volumes {
|
volumes {
|
||||||
host_path = "/mnt/xwing/data/timemachine"
|
host_path = "/mnt/xwing/data/timemachine"
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
pass = {
|
|
||||||
source = "camptocamp/pass"
|
|
||||||
}
|
|
||||||
digitalocean = {
|
|
||||||
source = "digitalocean/digitalocean"
|
|
||||||
}
|
|
||||||
postgresql = {
|
|
||||||
source = "cyrilgdn/postgresql"
|
|
||||||
}
|
|
||||||
cloudflare = {
|
|
||||||
source = "cloudflare/cloudflare"
|
|
||||||
}
|
|
||||||
docker = {
|
|
||||||
source = "kreuzwerker/docker"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
|
@ -21,7 +21,10 @@ variable "traefik-common-labels" {
|
||||||
"traefik.frontend.headers.STSIncludeSubdomains" = "false"
|
"traefik.frontend.headers.STSIncludeSubdomains" = "false"
|
||||||
// X-Powered-By, Server headers
|
// X-Powered-By, Server headers
|
||||||
"traefik.frontend.headers.customResponseHeaders" = "X-Powered-By:Allomancy||X-Server:Blackbox||X-Clacks-Overhead:GNU Terry Pratchett"
|
"traefik.frontend.headers.customResponseHeaders" = "X-Powered-By:Allomancy||X-Server:Blackbox||X-Clacks-Overhead:GNU Terry Pratchett"
|
||||||
"traefik.frontend.headers.browserXSSFilter" = "true"
|
// X-Frame-Options
|
||||||
|
"traefik.frontend.headers.customFrameOptionsValue" = "ALLOW-FROM https://bb8.fun/"
|
||||||
|
"traefik.frontend.headers.contentTypeNosniff" = "true"
|
||||||
|
"traefik.frontend.headers.browserXSSFilter" = "true"
|
||||||
// Use the Traefik network
|
// Use the Traefik network
|
||||||
"traefik.docker.network" = "traefik"
|
"traefik.docker.network" = "traefik"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.12"
|
||||||
|
}
|
12
wiki.tf
12
wiki.tf
|
@ -26,7 +26,17 @@ module "wiki-container" {
|
||||||
host = "wiki.bb8.fun"
|
host = "wiki.bb8.fun"
|
||||||
}
|
}
|
||||||
|
|
||||||
networks = ["postgres", "external"]
|
networks_advanced = [
|
||||||
|
{
|
||||||
|
name = "traefik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "postgres"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "external"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
uploads = [
|
uploads = [
|
||||||
{
|
{
|
||||||
|
|
9
znc.tf
9
znc.tf
|
@ -3,6 +3,11 @@ module "znc" {
|
||||||
image = "znc:latest"
|
image = "znc:latest"
|
||||||
name = "znc"
|
name = "znc"
|
||||||
|
|
||||||
|
web = {
|
||||||
|
expose = "false"
|
||||||
|
host = ""
|
||||||
|
}
|
||||||
|
|
||||||
volumes = [
|
volumes = [
|
||||||
{
|
{
|
||||||
container_path = "/znc-data"
|
container_path = "/znc-data"
|
||||||
|
@ -12,8 +17,8 @@ module "znc" {
|
||||||
|
|
||||||
ports = [
|
ports = [
|
||||||
{
|
{
|
||||||
internal = "6697"
|
internal = 6697
|
||||||
external = "6697"
|
external = 6697
|
||||||
ip = var.ips["tun0"]
|
ip = var.ips["tun0"]
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue