Compare commits
1 Commits
master
...
kaarana-wo
Author | SHA1 | Date |
---|---|---|
Nemo | 7f6ad55873 |
|
@ -3,11 +3,8 @@
|
|||
.terraform
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
||||
*.terraform.lock.hcl
|
||||
*.out
|
||||
*.backup
|
||||
secrets
|
||||
k8s/
|
||||
k8s2/
|
||||
docker/conf/wiki.yml
|
||||
plan
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.3.6
|
||||
0.11.13
|
||||
|
|
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
|
||||
````
|
|
@ -11,7 +11,6 @@ Manages the local infrastructure of my home server. I'm also doing blog posts ar
|
|||
3. [Part 3, Learnings](https://captnemo.in/blog/2017/12/18/home-server-learnings/)
|
||||
4. [Part 4, Migrating from Google (and more)](https://captnemo.in/blog/2017/12/31/migrating-from-google/)
|
||||
5. [Part 5, Networking](https://captnemo.in/blog/2018/04/22/home-server-networking/)
|
||||
6. [Part 6, RAID](https://captnemo.in/blog/2019/02/24/btrfs-raid-device-replacement-story/)
|
||||
|
||||
The canonical URL for this repo is https://git.captnemo.in/nemo/nebula/. A mirror is maintained on GitHub at <https://github.com/captn3m0/nebula>
|
||||
|
||||
|
@ -41,7 +40,9 @@ Currently running the following (all links are to the `store.docker.com` links f
|
|||
|
||||
| image | tag | module/link |
|
||||
| -------------------------------- | ---------- | ---------------------------------------------------- |
|
||||
| bleenco/abstruse | latest | ci |
|
||||
| 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/speedtest-exporter | alpine | https://github.com/stefanwalther/speedtest-exporter |
|
||||
| emby/embyserver | latest | https://emby.media |
|
||||
|
@ -50,14 +51,19 @@ Currently running the following (all links are to the `store.docker.com` links f
|
|||
| grafana/grafana | latest | monitoring |
|
||||
| jankysolutions/requestbin | latest | tools |
|
||||
| linuxserver/airsonic | latest | media |
|
||||
| linuxserver/heimdall | latest | tools |
|
||||
| linuxserver/jackett | latest | media |
|
||||
| linuxserver/lidarr | latest | media |
|
||||
| linuxserver/lychee | latest | media |
|
||||
| linuxserver/radarr | latest | media |
|
||||
| linuxserver/resilio-sync | latest | sync |
|
||||
| linuxserver/sonarr | latest | media |
|
||||
| linuxserver/transmission | latest | media |
|
||||
| linuxserver/ubooquity | latest | media |
|
||||
| miniflux/miniflux | 2.0.9 | tools |
|
||||
| monicahq/monicahq | latest | services |
|
||||
| odarriba/timemachine | latest | tools |
|
||||
| percona/percona-server-mongodb | 3.4 | database |
|
||||
| postgres | 10-alpine | database |
|
||||
| prom/node-exporter | v0.15.2 | monitoring |
|
||||
| prom/prometheus | latest | monitoring |
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
data "docker_registry_image" "abstruse" {
|
||||
name = "bleenco/abstruse:latest"
|
||||
}
|
||||
|
||||
resource "docker_image" "abstruse" {
|
||||
name = "${data.docker_registry_image.abstruse.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.abstruse.sha256_digest}"]
|
||||
}
|
||||
|
||||
resource "docker_container" "abstruse" {
|
||||
name = "abstruse"
|
||||
image = "${docker_image.abstruse.latest}"
|
||||
|
||||
labels = "${merge(
|
||||
var.traefik-labels, map(
|
||||
"traefik.port", 6500,
|
||||
"traefik.frontend.rule","Host:${var.domain}"
|
||||
))}"
|
||||
|
||||
networks = ["${var.traefik-network-id}"]
|
||||
|
||||
volumes {
|
||||
host_path = "/var/run/docker.sock"
|
||||
container_path = "/var/run/docker.sock"
|
||||
}
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/config/abstruse"
|
||||
container_path = "/root/.abstruse"
|
||||
}
|
||||
|
||||
restart = "unless-stopped"
|
||||
destroy_grace_seconds = 60
|
||||
must_run = true
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
variable "domain" {
|
||||
description = "domain to be used by traefik"
|
||||
}
|
||||
|
||||
variable "traefik-labels" {
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "traefik-network-id" {}
|
|
@ -0,0 +1,36 @@
|
|||
module "audioserve" {
|
||||
name = "audioserve"
|
||||
source = "modules/container"
|
||||
|
||||
web {
|
||||
expose = true
|
||||
port = "3000"
|
||||
host = "audioserve.${var.root-domain}"
|
||||
auth = "true"
|
||||
}
|
||||
|
||||
resource {
|
||||
memory = 256
|
||||
memory_swap = 256
|
||||
}
|
||||
|
||||
command = [
|
||||
"--no-authentication",
|
||||
"/audiobooks",
|
||||
]
|
||||
|
||||
restart = "always"
|
||||
|
||||
image = "izderadicka/audioserve"
|
||||
|
||||
volumes = [
|
||||
{
|
||||
host_path = "/mnt/xwing/media/Music/Audiobooks"
|
||||
container_path = "/audiobooks"
|
||||
},
|
||||
]
|
||||
|
||||
networks_advanced = [{
|
||||
name = "traefik"
|
||||
}]
|
||||
}
|
|
@ -4,16 +4,16 @@
|
|||
*/
|
||||
|
||||
resource "cloudflare_record" "home" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "in"
|
||||
value = var.ips["eth0"]
|
||||
value = "${var.ips["eth0"]}"
|
||||
type = "A"
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "home-wildcard" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "*.in"
|
||||
value = cloudflare_record.home.hostname
|
||||
value = "${cloudflare_record.home.hostname}"
|
||||
type = "CNAME"
|
||||
ttl = 3600
|
||||
}
|
||||
|
@ -23,38 +23,38 @@ resource "cloudflare_record" "home-wildcard" {
|
|||
* *.bb8.fun -> bb8.fun
|
||||
*/
|
||||
resource "cloudflare_record" "internet" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "@"
|
||||
value = var.droplet_ip
|
||||
value = "${var.droplet_ip}"
|
||||
type = "A"
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "internet-wildcard" {
|
||||
zone_id = var.zone_id
|
||||
name = var.domain
|
||||
value = cloudflare_record.internet.hostname
|
||||
domain = "${var.domain}"
|
||||
name = "*.${var.domain}"
|
||||
value = "${cloudflare_record.internet.hostname}"
|
||||
type = "CNAME"
|
||||
ttl = 3600
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "dns" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "dns"
|
||||
value = var.ips["static"]
|
||||
value = "${var.ips["static"]}"
|
||||
type = "A"
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "doh" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "doh"
|
||||
value = var.ips["static"]
|
||||
value = "${var.ips["static"]}"
|
||||
type = "A"
|
||||
}
|
||||
|
||||
// This ensures that _acme-challenge is not a CNAME
|
||||
// alongside the above wildcard CNAME entry.
|
||||
resource "cloudflare_record" "acme-no-cname-1" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "_acme-challenge.${var.domain}"
|
||||
type = "A"
|
||||
value = "127.0.0.1"
|
||||
|
@ -66,16 +66,16 @@ resource "cloudflare_record" "acme-no-cname-1" {
|
|||
* *.vpn.bb8.fun
|
||||
*/
|
||||
resource "cloudflare_record" "vpn" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "vpn"
|
||||
value = var.ips["tun0"]
|
||||
value = "${var.ips["tun0"]}"
|
||||
type = "A"
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "vpn_wildcard" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "*.vpn.${var.domain}"
|
||||
value = cloudflare_record.vpn.hostname
|
||||
value = "${cloudflare_record.vpn.hostname}"
|
||||
type = "CNAME"
|
||||
ttl = 3600
|
||||
}
|
||||
|
@ -85,24 +85,24 @@ resource "cloudflare_record" "vpn_wildcard" {
|
|||
* *.vpn.bb8.fun
|
||||
*/
|
||||
resource "cloudflare_record" "dovpn" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "dovpn"
|
||||
value = var.ips["dovpn"]
|
||||
value = "${var.ips["dovpn"]}"
|
||||
type = "A"
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "dovpn_wildcard" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "*.dovpn.${var.domain}"
|
||||
value = cloudflare_record.dovpn.hostname
|
||||
value = "${cloudflare_record.dovpn.hostname}"
|
||||
type = "CNAME"
|
||||
ttl = 3600
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "etcd" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "etcd"
|
||||
value = var.ips["dovpn"]
|
||||
value = "${var.ips["dovpn"]}"
|
||||
type = "A"
|
||||
}
|
||||
|
||||
|
@ -111,21 +111,21 @@ resource "cloudflare_record" "etcd" {
|
|||
########################
|
||||
|
||||
resource "cloudflare_record" "mailgun-spf" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "l"
|
||||
value = "v=spf1 include:mailgun.org ~all"
|
||||
type = "TXT"
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "mailgun-dkim" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "k1._domainkey.l"
|
||||
value = "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnbP+IQkuPkgmUhpqCKzIdDSZ0HazaMp+cdBH++LBed8oY8/jmV8BhxMp5JwyePzRTxneT8ASsRtcp7CQ3z4nMC7aFX0kH6Bnu2v+u2JWudxs8x0I02OrPbSaQ5QVQdbAaCUCEfCQ06LJsn8aqPNrRIOWEMnxln+ebFJ0wKGscFQIDAQAB"
|
||||
type = "TXT"
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "mailgun-mxa" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "l"
|
||||
value = "mxa.mailgun.org"
|
||||
type = "MX"
|
||||
|
@ -133,7 +133,7 @@ resource "cloudflare_record" "mailgun-mxa" {
|
|||
}
|
||||
|
||||
resource "cloudflare_record" "mailgun-mxb" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "l"
|
||||
value = "mxb.mailgun.org"
|
||||
type = "MX"
|
||||
|
@ -141,7 +141,7 @@ resource "cloudflare_record" "mailgun-mxb" {
|
|||
}
|
||||
|
||||
resource "cloudflare_record" "k8s" {
|
||||
zone_id = var.zone_id
|
||||
domain = "${var.domain}"
|
||||
name = "k8s"
|
||||
value = "10.8.0.1"
|
||||
type = "A"
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
variable "domain" {
|
||||
type = string
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ips" {
|
||||
type = map
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "droplet_ip" {}
|
||||
variable "zone_id" {}
|
||||
|
|
8
data.tf
8
data.tf
|
@ -1,11 +1,3 @@
|
|||
data "docker_network" "bridge" {
|
||||
name = "bridge"
|
||||
}
|
||||
|
||||
data "cloudflare_zones" "bb8" {
|
||||
filter {
|
||||
name = "bb8"
|
||||
lookup_type = "exact"
|
||||
match = "bb8.fun"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
resource "docker_container" "mongorocks" {
|
||||
name = "mongorocks"
|
||||
image = "${docker_image.percona-mongodb-server.latest}"
|
||||
|
||||
restart = "unless-stopped"
|
||||
destroy_grace_seconds = 30
|
||||
must_run = true
|
||||
memory = 256
|
||||
|
||||
volumes {
|
||||
volume_name = "${docker_volume.mongorocks_data_volume.name}"
|
||||
container_path = "/data/db"
|
||||
host_path = "${docker_volume.mongorocks_data_volume.mountpoint}"
|
||||
}
|
||||
|
||||
command = [
|
||||
"--storageEngine=rocksdb",
|
||||
"--httpinterface",
|
||||
"--rest",
|
||||
"--master",
|
||||
]
|
||||
|
||||
networks = ["${docker_network.mongorocks.id}"]
|
||||
}
|
||||
|
||||
resource "docker_image" "percona-mongodb-server" {
|
||||
name = "${data.docker_registry_image.percona-mongodb-server.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.percona-mongodb-server.sha256_digest}"]
|
||||
}
|
||||
|
||||
# Database versions shouldn't be upgraded
|
||||
data "docker_registry_image" "percona-mongodb-server" {
|
||||
name = "percona/percona-server-mongodb:3.4"
|
||||
}
|
|
@ -1,10 +1,21 @@
|
|||
resource "docker_network" "mongorocks" {
|
||||
name = "mongorocks"
|
||||
driver = "bridge"
|
||||
internal = false
|
||||
|
||||
ipam_config {
|
||||
subnet = "172.20.0.0/29"
|
||||
gateway = "172.20.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
resource "docker_network" "postgres" {
|
||||
name = "postgres"
|
||||
driver = "bridge"
|
||||
internal = true
|
||||
|
||||
ipam_config {
|
||||
subnet = "172.20.0.8/27"
|
||||
subnet = "172.20.0.8/29"
|
||||
gateway = "172.20.0.9"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
output "postgres-network-id" {
|
||||
value = docker_network.postgres.name
|
||||
output "networks-mongorocks" {
|
||||
value = "${docker_network.mongorocks.name}"
|
||||
}
|
||||
|
||||
output "postgres-network-id" {
|
||||
value = "${docker_network.postgres.name}"
|
||||
}
|
||||
|
|
|
@ -1,26 +1,18 @@
|
|||
resource "docker_container" "postgres" {
|
||||
name = "postgres"
|
||||
image = docker_image.postgres.image_id
|
||||
|
||||
command = [
|
||||
"postgres",
|
||||
"-c",
|
||||
"max_connections=250",
|
||||
"-c",
|
||||
"shared_buffers=500MB",
|
||||
]
|
||||
image = "${docker_image.postgres.latest}"
|
||||
|
||||
volumes {
|
||||
volume_name = docker_volume.pg_data.name
|
||||
volume_name = "${docker_volume.postgres_volume.name}"
|
||||
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
|
||||
ports {
|
||||
internal = 5432
|
||||
external = 5432
|
||||
ip = var.ips["eth0"]
|
||||
ip = "${var.ips["eth0"]}"
|
||||
}
|
||||
|
||||
// This is a not-so-great idea
|
||||
|
@ -28,11 +20,10 @@ resource "docker_container" "postgres" {
|
|||
ports {
|
||||
internal = 5432
|
||||
external = 5432
|
||||
ip = var.ips["tun0"]
|
||||
ip = "${var.ips["tun0"]}"
|
||||
}
|
||||
|
||||
memory = 2048
|
||||
memory_swap = 2048
|
||||
memory = 256
|
||||
restart = "unless-stopped"
|
||||
destroy_grace_seconds = 10
|
||||
must_run = true
|
||||
|
@ -41,12 +32,12 @@ resource "docker_container" "postgres" {
|
|||
"POSTGRES_PASSWORD=${var.postgres-root-password}",
|
||||
]
|
||||
|
||||
networks = [docker_network.postgres.id, data.docker_network.bridge.id]
|
||||
networks = ["${docker_network.postgres.id}", "${data.docker_network.bridge.id}"]
|
||||
}
|
||||
|
||||
resource "docker_image" "postgres" {
|
||||
name = data.docker_registry_image.postgres.name
|
||||
pull_triggers = [data.docker_registry_image.postgres.sha256_digest]
|
||||
name = "${data.docker_registry_image.postgres.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.postgres.sha256_digest}"]
|
||||
}
|
||||
|
||||
data "docker_registry_image" "postgres" {
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
postgresql = {
|
||||
source = "cyrilgdn/postgresql"
|
||||
}
|
||||
docker = {
|
||||
source = "kreuzwerker/docker"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,10 @@
|
|||
variable "postgres-version" {
|
||||
description = "postgres version to use for fetching the docker image"
|
||||
default = "14-alpine"
|
||||
default = "10-alpine"
|
||||
}
|
||||
|
||||
variable "ips" {
|
||||
type = map(string)
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "postgres-root-password" {
|
||||
}
|
||||
variable "postgres-root-password" {}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
resource "docker_volume" "pg_data" {
|
||||
name = "pg_data"
|
||||
resource "docker_volume" "postgres_volume" {
|
||||
name = "postgres_volume"
|
||||
}
|
||||
|
||||
resource "docker_volume" "mongorocks_data_volume" {
|
||||
name = "mongorocks_data_volume"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
resource "digitalocean_droplet" "sydney" {
|
||||
image = "??"
|
||||
image = ""
|
||||
name = "sydney.captnemo.in"
|
||||
region = "blr1"
|
||||
size = "s-1vcpu-2gb"
|
||||
|
@ -18,6 +18,5 @@ resource "digitalocean_droplet" "sydney" {
|
|||
}
|
||||
|
||||
output "droplet_ipv4" {
|
||||
value = digitalocean_droplet.sydney.ipv4_address
|
||||
value = "${digitalocean_droplet.sydney.ipv4_address}"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,38 @@
|
|||
resource "digitalocean_firewall" "web" {
|
||||
name = "web-inbound"
|
||||
|
||||
inbound_rule {
|
||||
inbound_rule = [
|
||||
{
|
||||
protocol = "tcp"
|
||||
port_range = "80"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
inbound_rule {
|
||||
},
|
||||
{
|
||||
protocol = "tcp"
|
||||
port_range = "443"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
resource "digitalocean_firewall" "ssh" {
|
||||
name = "ssh-inbound"
|
||||
|
||||
inbound_rule {
|
||||
inbound_rule = [
|
||||
{
|
||||
protocol = "tcp"
|
||||
port_range = "22"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
inbound_rule {
|
||||
},
|
||||
{
|
||||
protocol = "tcp"
|
||||
port_range = "222"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
inbound_rule {
|
||||
},
|
||||
{
|
||||
protocol = "tcp"
|
||||
port_range = "24"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
resource "digitalocean_floating_ip" "sydney" {
|
||||
droplet_id = digitalocean_droplet.sydney.id
|
||||
region = digitalocean_droplet.sydney.region
|
||||
droplet_id = "${digitalocean_droplet.sydney.id}"
|
||||
region = "${digitalocean_droplet.sydney.region}"
|
||||
}
|
||||
|
||||
|
|
|
@ -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,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
|
|
@ -1,4 +1,7 @@
|
|||
defaultEntryPoints = ["http", "https"]
|
||||
# logLevel = "DEBUG"
|
||||
# Have to enable this because of heimdall
|
||||
InsecureSkipVerify = true
|
||||
sendAnonymousUsage = true
|
||||
checkNewVersion = false
|
||||
|
||||
|
@ -6,6 +9,10 @@ checkNewVersion = false
|
|||
[accessLog]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
[entryPoints.http.redirect]
|
||||
entryPoint = "https"
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
# This is required for ACME support
|
||||
|
@ -16,15 +23,9 @@ checkNewVersion = false
|
|||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "/etc/traefik/rss.captnemo.in.crt"
|
||||
keyFile = "/etc/traefik/rss.captnemo.in.key"
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "/etc/traefik/tatooine.club.crt"
|
||||
keyFile = "/etc/traefik/tatooine.club.key"
|
||||
|
||||
[docker]
|
||||
# Make sure you mount this as readonly
|
||||
# NOTE: readonly doesn't reduce the risk because
|
||||
# it is a unix socket - it doesn't automatically translate
|
||||
# read|write perms to GET/POST requests.
|
||||
endpoint = "unix:///var/run/docker.sock"
|
||||
domain = "bb8.fun"
|
||||
watch = true
|
||||
|
@ -37,6 +38,33 @@ checkNewVersion = false
|
|||
# Since I can't apply a authentication
|
||||
# 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]
|
||||
address = ":1111"
|
||||
readOnly = true
|
||||
|
@ -57,8 +85,7 @@ acmelogging = true
|
|||
|
||||
[acme.dnsChallenge]
|
||||
provider = "cloudflare"
|
||||
delayBeforeCheck = 120
|
||||
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
|
||||
delayBeforeCheck = 30
|
||||
|
||||
# Primary 2 wildcard certs
|
||||
[[acme.domains]]
|
||||
|
|
|
@ -164,7 +164,7 @@
|
|||
"booksPaginationNumber": 30,
|
||||
"minimizeToTray": false,
|
||||
"minimizeOnStartup": false,
|
||||
"autoscanPeriod" : 1440,
|
||||
"autoscanPeriod": 0,
|
||||
"isRemoteAdminEnabled": true,
|
||||
"theme": "default",
|
||||
"isShrinkingCacheEnabled": false,
|
||||
|
@ -181,7 +181,5 @@
|
|||
"enableFolderMetadataDisplay": true,
|
||||
"bookmarkUsingCookies": false,
|
||||
"displayTitleInsteadOfFileName": true,
|
||||
"keepUnreachableSharedFolders" : false,
|
||||
"isCalibreLibrary" : false,
|
||||
"instanceId" : "3a0e4425a8e14c719ca2eb382f85292e"
|
||||
"keepUnreachableSharedFolders": false
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
port: 3000
|
||||
db:
|
||||
type: postgres
|
||||
host: postgres
|
||||
port: 5432
|
||||
user: wikijs
|
||||
db: wikijs
|
||||
pass: ${DB_PASSWORD}
|
||||
ssl:
|
||||
enabled: false
|
||||
bindIP: 0.0.0.0
|
||||
logLevel: silly
|
||||
offline: true
|
||||
ha: false
|
||||
dataPath: /data
|
|
@ -0,0 +1,142 @@
|
|||
#######################################################################
|
||||
# Wiki.js - CONFIGURATION #
|
||||
#######################################################################
|
||||
# Full explanation + examples in the documentation:
|
||||
# https://docs.requarks.io/wiki/install
|
||||
# You can use an ENV variable by using $(ENV_VAR_NAME) as the value
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Title of this site
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
title: Scarif Wiki
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Full public path to the site, without the trailing slash
|
||||
# ---------------------------------------------------------------------
|
||||
# INCLUDE CLIENT PORT IF NOT 80/443!
|
||||
|
||||
host: https://wiki.bb8.fun
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Port the main server should listen to (80 by default)
|
||||
# ---------------------------------------------------------------------
|
||||
# To use process.env.PORT, comment the line below:
|
||||
|
||||
port: 9999
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Data Directories
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
paths:
|
||||
repo: /repo
|
||||
data: /data
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Upload Limits
|
||||
# ---------------------------------------------------------------------
|
||||
# In megabytes (MB)
|
||||
|
||||
uploads:
|
||||
maxImageFileSize: 5
|
||||
maxOtherFileSize: 100
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Site Language
|
||||
# ---------------------------------------------------------------------
|
||||
# Possible values: en, de, es, fa, fr, ja, ko, nl, pt, ru, sr, tr or zh
|
||||
|
||||
lang: en
|
||||
|
||||
# Enable for right to left languages (e.g. arabic):
|
||||
langRtl: false
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Site Authentication
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
public: true
|
||||
|
||||
auth:
|
||||
defaultReadAccess: false
|
||||
local:
|
||||
enabled: true
|
||||
google:
|
||||
enabled: false
|
||||
clientId: GOOGLE_CLIENT_ID
|
||||
clientSecret: GOOGLE_CLIENT_SECRET
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Secret key to use when encrypting sessions
|
||||
# ---------------------------------------------------------------------
|
||||
# Use a long and unique random string (256-bit keys are perfect!)
|
||||
|
||||
sessionSecret: $(SESSION_SECRET)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Database Connection String
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
db: mongodb://mongorocks:27017/wiki
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Git Connection Info (force disabled)
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# git: false
|
||||
git:
|
||||
url: https://git.captnemo.in/nemo/wiki
|
||||
branch: master
|
||||
# auth:
|
||||
|
||||
# # Type: basic or ssh
|
||||
# type: ssh
|
||||
|
||||
# # Only for Basic authentication:
|
||||
# username: marty
|
||||
# password: MartyMcFly88
|
||||
|
||||
# # Only for SSH authentication:
|
||||
# privateKey: /etc/wiki/keys/git.pem
|
||||
|
||||
# sslVerify: true
|
||||
|
||||
# # Default email to use as commit author
|
||||
# serverEmail: marty@example.com
|
||||
|
||||
# # Whether to use user email as author in commits
|
||||
# showUserEmail: true
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Features
|
||||
# ---------------------------------------------------------------------
|
||||
# You can enable / disable specific features below
|
||||
|
||||
features:
|
||||
linebreaks: true
|
||||
mathjax: false
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# External Logging
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
externalLogging:
|
||||
bugsnag: false
|
||||
loggly: false
|
||||
papertrail: false
|
||||
rollbar: false
|
||||
sentry: false
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Color Theme
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
theme:
|
||||
primary: indigo
|
||||
alt: blue-grey
|
||||
viewSource: all # all | write | false
|
||||
footer: blue-grey
|
||||
code:
|
||||
dark: true
|
||||
colorize: true
|
|
@ -2,6 +2,10 @@ data "docker_registry_image" "traefik" {
|
|||
name = "traefik:1.7"
|
||||
}
|
||||
|
||||
data "docker_registry_image" "wikijs" {
|
||||
name = "requarks/wiki:latest"
|
||||
}
|
||||
|
||||
data "docker_registry_image" "ubooquity" {
|
||||
name = "linuxserver/ubooquity:latest"
|
||||
}
|
||||
|
@ -9,4 +13,3 @@ data "docker_registry_image" "ubooquity" {
|
|||
data "docker_registry_image" "lychee" {
|
||||
name = "linuxserver/lychee:latest"
|
||||
}
|
||||
|
||||
|
|
|
@ -6,15 +6,22 @@ data "docker_registry_image" "gotviz" {
|
|||
# name = "${data.docker_registry_image.gotviz.name}"
|
||||
# pull_triggers = ["${data.docker_registry_image.gotviz.sha256_digest}"]
|
||||
# }
|
||||
|
||||
|
||||
# resource "docker_container" "gotviz" {
|
||||
# name = "gotviz"
|
||||
# image = "${docker_image.gotviz.image_id}"
|
||||
# image = "${docker_image.gotviz.latest}"
|
||||
|
||||
|
||||
# labels = "${merge(
|
||||
# local.traefik_common_labels, map(
|
||||
# "traefik.port", 8080,
|
||||
# "traefik.frontend.rule","Host:got-relationships.${var.domain}"
|
||||
# ))}"
|
||||
|
||||
|
||||
# restart = "unless-stopped"
|
||||
# destroy_grace_seconds = 60
|
||||
# must_run = true
|
||||
# }
|
||||
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
resource "docker_image" "traefik17" {
|
||||
name = data.docker_registry_image.traefik.name
|
||||
pull_triggers = [data.docker_registry_image.traefik.sha256_digest]
|
||||
name = "${data.docker_registry_image.traefik.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.traefik.sha256_digest}"]
|
||||
}
|
||||
|
||||
resource "docker_image" "wikijs" {
|
||||
name = "${data.docker_registry_image.wikijs.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.wikijs.sha256_digest}"]
|
||||
}
|
||||
|
||||
resource "docker_image" "ubooquity" {
|
||||
name = data.docker_registry_image.ubooquity.name
|
||||
pull_triggers = [data.docker_registry_image.ubooquity.sha256_digest]
|
||||
name = "${data.docker_registry_image.ubooquity.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.ubooquity.sha256_digest}"]
|
||||
}
|
||||
|
||||
# resource "docker_image" "lychee" {
|
||||
# name = "${data.docker_registry_image.lychee.name}"
|
||||
# pull_triggers = ["${data.docker_registry_image.lychee.sha256_digest}"]
|
||||
# }
|
||||
resource "docker_image" "lychee" {
|
||||
name = "${data.docker_registry_image.lychee.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.lychee.sha256_digest}"]
|
||||
}
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
locals {
|
||||
traefik_common_labels = {
|
||||
traefik_common_labels {
|
||||
"traefik.enable" = "true"
|
||||
|
||||
// HSTS
|
||||
"traefik.frontend.headers.SSLTemporaryRedirect" = "true"
|
||||
"traefik.frontend.headers.STSSeconds" = "2592000"
|
||||
"traefik.frontend.headers.STSIncludeSubdomains" = "false"
|
||||
|
||||
// X-Powered-By, Server headers
|
||||
"traefik.frontend.headers.customResponseHeaders" = var.xpoweredby
|
||||
"traefik.frontend.headers.customResponseHeaders" = "${var.xpoweredby}"
|
||||
|
||||
// X-Frame-Options
|
||||
"traefik.frontend.headers.customFrameOptionsValue" = var.xfo_allow
|
||||
"traefik.frontend.headers.customFrameOptionsValue" = "${var.xfo_allow}"
|
||||
"traefik.frontend.headers.contentTypeNosniff" = "true"
|
||||
"traefik.frontend.headers.browserXSSFilter" = "true"
|
||||
|
||||
"traefik.docker.network" = "traefik"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# resource "docker_container" "lychee" {
|
||||
# name = "lychee"
|
||||
# image = "${docker_image.lychee.image_id}"
|
||||
# image = "${docker_image.lychee.latest}"
|
||||
# restart = "unless-stopped"
|
||||
# destroy_grace_seconds = 10
|
||||
# must_run = true
|
||||
|
@ -28,3 +28,4 @@
|
|||
# ]
|
||||
# # links = ["${var.links-mariadb}"]
|
||||
# }
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -3,4 +3,3 @@ resource "docker_network" "traefik" {
|
|||
driver = "bridge"
|
||||
internal = true
|
||||
}
|
||||
|
||||
|
|
|
@ -3,14 +3,13 @@
|
|||
# }
|
||||
|
||||
output "names-traefik" {
|
||||
value = docker_container.traefik.name
|
||||
value = "${docker_container.traefik.name}"
|
||||
}
|
||||
|
||||
output "traefik-network-id" {
|
||||
value = docker_network.traefik.id
|
||||
value = "${docker_network.traefik.id}"
|
||||
}
|
||||
|
||||
output "auth-header" {
|
||||
value = var.basic_auth
|
||||
value = "${var.basic_auth}"
|
||||
}
|
||||
|
||||
|
|
|
@ -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,94 +1,69 @@
|
|||
resource "docker_container" "traefik" {
|
||||
name = "traefik"
|
||||
image = docker_image.traefik17.image_id
|
||||
image = "${docker_image.traefik17.latest}"
|
||||
|
||||
|
||||
labels {
|
||||
label = "traefik.enable"
|
||||
value = "true"
|
||||
# Admin Backend
|
||||
ports {
|
||||
internal = 1111
|
||||
external = 1111
|
||||
ip = "${var.ips["eth0"]}"
|
||||
}
|
||||
|
||||
labels {
|
||||
label = "traefik.http.routers.api.rule"
|
||||
value = "Host('traefik.in.bb8.fun')"
|
||||
}
|
||||
|
||||
labels {
|
||||
label = "traefik.http.routers.api.service"
|
||||
value = "api@internal"
|
||||
ports {
|
||||
internal = 1111
|
||||
external = 1111
|
||||
ip = "${var.ips["tun0"]}"
|
||||
}
|
||||
|
||||
# Local Web Server
|
||||
ports {
|
||||
internal = 80
|
||||
external = 80
|
||||
ip = var.ips["eth0"]
|
||||
ip = "${var.ips["eth0"]}"
|
||||
}
|
||||
|
||||
# Local Web Server (HTTPS)
|
||||
ports {
|
||||
internal = 443
|
||||
external = 443
|
||||
ip = var.ips["eth0"]
|
||||
ip = "${var.ips["eth0"]}"
|
||||
}
|
||||
|
||||
# Proxied via sydney.captnemo.in
|
||||
ports {
|
||||
internal = 443
|
||||
external = 443
|
||||
ip = var.ips["tun0"]
|
||||
ip = "${var.ips["tun0"]}"
|
||||
}
|
||||
|
||||
ports {
|
||||
internal = 80
|
||||
external = 80
|
||||
ip = var.ips["tun0"]
|
||||
ip = "${var.ips["tun0"]}"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file("${path.module}/conf/traefik.toml")
|
||||
content = "${file("${path.module}/conf/traefik.toml")}"
|
||||
file = "/etc/traefik/traefik.toml"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file(
|
||||
"/home/nemo/projects/personal/certs/git.captnemo.in/fullchain.pem",
|
||||
)
|
||||
content = "${file("/home/nemo/projects/personal/certs/git.captnemo.in/fullchain.pem")}"
|
||||
file = "/etc/traefik/git.captnemo.in.crt"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file(
|
||||
"/home/nemo/projects/personal/certs/git.captnemo.in/privkey.pem",
|
||||
)
|
||||
content = "${file("/home/nemo/projects/personal/certs/git.captnemo.in/privkey.pem")}"
|
||||
file = "/etc/traefik/git.captnemo.in.key"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file(
|
||||
"/home/nemo/projects/personal/certs/lego/certificates/tatooine.club.key",
|
||||
)
|
||||
file = "/etc/traefik/tatooine.club.key"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file(
|
||||
"/home/nemo/projects/personal/certs/lego/certificates/tatooine.club.crt",
|
||||
)
|
||||
file = "/etc/traefik/tatooine.club.crt"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file(
|
||||
"/home/nemo/projects/personal/certs/rss.captnemo.in/fullchain.pem",
|
||||
)
|
||||
content = "${file("/home/nemo/projects/personal/certs/rss.captnemo.in/fullchain.pem")}"
|
||||
file = "/etc/traefik/rss.captnemo.in.crt"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file(
|
||||
"/home/nemo/projects/personal/certs/rss.captnemo.in/privkey.pem",
|
||||
)
|
||||
content = "${file("/home/nemo/projects/personal/certs/rss.captnemo.in/privkey.pem")}"
|
||||
file = "/etc/traefik/rss.captnemo.in.key"
|
||||
}
|
||||
|
||||
|
@ -110,16 +85,17 @@ resource "docker_container" "traefik" {
|
|||
|
||||
// `bridge` is auto-connected for now
|
||||
// https://github.com/terraform-providers/terraform-provider-docker/issues/10
|
||||
networks_advanced {
|
||||
name = "traefik"
|
||||
}
|
||||
|
||||
networks_advanced {
|
||||
name = "bridge"
|
||||
}
|
||||
networks = [
|
||||
"${docker_network.traefik.id}",
|
||||
"${data.docker_network.bridge.id}",
|
||||
]
|
||||
|
||||
env = [
|
||||
"CLOUDFLARE_EMAIL=${var.cloudflare_email}",
|
||||
"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" {
|
||||
name = "ubooquity"
|
||||
image = docker_image.ubooquity.image_id
|
||||
image = "${docker_image.ubooquity.latest}"
|
||||
|
||||
restart = "unless-stopped"
|
||||
destroy_grace_seconds = 30
|
||||
|
@ -32,37 +25,32 @@ resource "docker_container" "ubooquity" {
|
|||
host_path = "/mnt/xwing/media/EBooks/Comics"
|
||||
container_path = "/comics"
|
||||
}
|
||||
|
||||
labels {
|
||||
label = "traefik.enable"
|
||||
value = "true"
|
||||
}
|
||||
labels {
|
||||
label = "traefik.admin.port"
|
||||
value = 2203
|
||||
}
|
||||
labels {
|
||||
label = "traefik.admin.frontend.rule"
|
||||
value = "Host:library.${var.domain}"
|
||||
}
|
||||
labels {
|
||||
label = "traefik.admin.frontend.auth.basic"
|
||||
value = var.basic_auth
|
||||
}
|
||||
labels {
|
||||
label = "traefik.read.port"
|
||||
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"
|
||||
"traefik.enable" = "true"
|
||||
|
||||
"traefik.admin.port" = 2203
|
||||
"traefik.admin.frontend.rule" = "Host:library.${var.domain}"
|
||||
|
||||
# I do not trust the Ubooquity authentication
|
||||
# it does some shady JS encryption
|
||||
"traefik.admin.frontend.auth.basic" = "${var.basic_auth}"
|
||||
|
||||
"traefik.read.port" = 2202
|
||||
"traefik.read.frontend.rule" = "Host:read.${var.domain},comics.${var.domain},books.${var.domain}"
|
||||
|
||||
"traefik.read.frontend.headers.SSLTemporaryRedirect" = "true"
|
||||
"traefik.read.frontend.headers.STSSeconds" = "2592000"
|
||||
"traefik.read.frontend.headers.STSIncludeSubdomains" = "false"
|
||||
"traefik.read.frontend.headers.contentTypeNosniff" = "true"
|
||||
"traefik.read.frontend.headers.browserXSSFilter" = "true"
|
||||
"traefik.read.frontend.headers.customResponseHeaders" = "${var.xpoweredby}"
|
||||
"traefik.frontend.headers.customFrameOptionsValue" = "${var.xfo_allow}"
|
||||
"traefik.docker.network" = "traefik"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file("${path.module}/conf/ubooquity.json")
|
||||
content = "${file("${path.module}/conf/ubooquity.json")}"
|
||||
file = "/config/preferences.json"
|
||||
}
|
||||
|
||||
|
@ -73,4 +61,3 @@ resource "docker_container" "ubooquity" {
|
|||
"MAXMEM=800",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
variable "web_username" {
|
||||
type = string
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "web_password" {
|
||||
type = string
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cloudflare_key" {
|
||||
type = string
|
||||
type = "string"
|
||||
description = "cloudflare API Key"
|
||||
}
|
||||
|
||||
variable "cloudflare_email" {
|
||||
type = string
|
||||
type = "string"
|
||||
description = "cloudflare email address"
|
||||
}
|
||||
|
||||
|
@ -39,15 +39,17 @@ variable "refpolicy" {
|
|||
}
|
||||
|
||||
variable "wiki_session_secret" {
|
||||
type = string
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
type = string
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ips" {
|
||||
type = map(string)
|
||||
type = "map"
|
||||
}
|
||||
|
||||
# variable "links-mariadb" {}
|
||||
|
||||
variable "networks-mongorocks" {}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
resource "docker_container" "wiki" {
|
||||
name = "wiki"
|
||||
image = "${docker_image.wikijs.latest}"
|
||||
|
||||
restart = "unless-stopped"
|
||||
destroy_grace_seconds = 30
|
||||
must_run = true
|
||||
memory = 300
|
||||
|
||||
upload {
|
||||
content = "${file("${path.module}/conf/wiki.yml")}"
|
||||
file = "/var/wiki/config.yml"
|
||||
}
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/logs/wiki"
|
||||
container_path = "/logs"
|
||||
}
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/data/wiki/repo"
|
||||
container_path = "/repo"
|
||||
}
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/data/wiki/data"
|
||||
container_path = "/data"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = "${file("${path.module}/conf/humans.txt")}"
|
||||
file = "/var/wiki/assets/humans.txt"
|
||||
}
|
||||
|
||||
// The last header is a workaround for double header traefik bug
|
||||
// This might be actually breaking iframe till the 1.5 Final release.
|
||||
|
||||
labels = "${merge(
|
||||
local.traefik_common_labels,
|
||||
map(
|
||||
"traefik.frontend.rule", "Host:wiki.${var.domain}",
|
||||
"traefik.frontend.passHostHeader", "true",
|
||||
"traefik.port", 9999,
|
||||
"traefik.frontend.headers.customResponseHeaders", "${var.xpoweredby}||Referrer-Policy:${var.refpolicy}||X-Frame-Options:${var.xfo_allow}",
|
||||
))}"
|
||||
networks = [
|
||||
"${var.networks-mongorocks}",
|
||||
"${docker_network.traefik.id}",
|
||||
]
|
||||
env = [
|
||||
"WIKI_ADMIN_EMAIL=me@captnemo.in",
|
||||
"SESSION_SECRET=${var.wiki_session_secret}",
|
||||
]
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
module "echo-server" {
|
||||
source = "./modules/container"
|
||||
source = "modules/container"
|
||||
name = "echo-server"
|
||||
image = "jmalloc/echo-server:latest"
|
||||
|
||||
web = {
|
||||
web {
|
||||
expose = "true"
|
||||
port = 8080
|
||||
host = "debug.${var.root-domain},debug.in.${var.root-domain}"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
27
elibsrv.tf
27
elibsrv.tf
|
@ -1,14 +1,9 @@
|
|||
module "elibsrv" {
|
||||
name = "elibsrv"
|
||||
source = "./modules/container"
|
||||
image = "captn3m0/elibsrv"
|
||||
image = "captn3m0/elibsrv:latest"
|
||||
|
||||
resource = {
|
||||
memory = 512
|
||||
memory_swap = 512
|
||||
}
|
||||
|
||||
web = {
|
||||
web {
|
||||
expose = true
|
||||
host = "ebooks.${var.root-domain}"
|
||||
auth = true
|
||||
|
@ -18,12 +13,10 @@ module "elibsrv" {
|
|||
{
|
||||
host_path = "/mnt/xwing/media/EBooks"
|
||||
container_path = "/books"
|
||||
read_only = true
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/config/elibsrv"
|
||||
container_path = "/config"
|
||||
read_only = true
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/cache/elibsrv"
|
||||
|
@ -31,15 +24,17 @@ module "elibsrv" {
|
|||
},
|
||||
]
|
||||
|
||||
# The corresponding scan command is run using a cronjob
|
||||
# `docker run --volume "/mnt/xwing/media/EBooks:/books:ro" --volume "/mnt/xwing/config/elibsrv:/config" --env "elibsrv_thumbheight=320" captn3m0/elibsrv scan
|
||||
|
||||
command = ["serve"]
|
||||
keep_image = true
|
||||
env = [
|
||||
"elibsrv_thumbheight=320",
|
||||
"elibsrv_title=Scarif Media Archives",
|
||||
]
|
||||
networks = ["bridge"]
|
||||
}
|
||||
|
||||
networks_advanced = [
|
||||
{
|
||||
name = "traefik"
|
||||
},
|
||||
{
|
||||
name = "bridge"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
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}"
|
||||
}
|
||||
|
||||
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,26 +2,21 @@
|
|||
; Copy required sections to your own app.ini (default is custom/conf/app.ini)
|
||||
; and modify as needed.
|
||||
; 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 = Nemo's code
|
||||
RUN_MODE = prod
|
||||
RUN_USER = git
|
||||
WORK_PATH=/data/gitea
|
||||
|
||||
[repository]
|
||||
ROOT = /data/git/repositories
|
||||
USE_COMPAT_SSH_URI = false
|
||||
USE_COMPAT_SSH_URI = true
|
||||
|
||||
[repository.upload]
|
||||
TEMP_PATH = /data/gitea/uploads
|
||||
|
||||
[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
|
||||
; 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
|
||||
|
@ -41,11 +36,6 @@ NOTICE_PAGING_NUM = 25
|
|||
; Number of organization that are showed in one page
|
||||
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]
|
||||
; Number of repos that are showed in one page
|
||||
REPO_PAGING_NUM = 15
|
||||
|
@ -63,9 +53,6 @@ ENABLE_HARD_LINE_BREAK = false
|
|||
CUSTOM_URL_SCHEMES = git,magnet,steam,irc,slack
|
||||
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)
|
||||
[ssh.minimum_key_sizes]
|
||||
ED25519 = 256
|
||||
|
@ -73,16 +60,16 @@ ECDSA = 256
|
|||
RSA = 2048
|
||||
DSA = 1024
|
||||
|
||||
[lfs]
|
||||
PATH=/data/gitea/lfs
|
||||
|
||||
[server]
|
||||
APP_DATA_PATH = /data/gitea
|
||||
SSH_DOMAIN = code.captnemo.in
|
||||
HTTP_PORT = 3000
|
||||
ROOT_URL = https://git.captnemo.in/
|
||||
DISABLE_SSH = true
|
||||
DISABLE_SSH = false
|
||||
SSH_PORT = 22
|
||||
DOMAIN = git.captnemo.in
|
||||
LFS_START_SERVER = true
|
||||
LFS_CONTENT_PATH = /data/gitea/lfs
|
||||
LFS_JWT_SECRET = "${lfs-jwt-secret}"
|
||||
OFFLINE_MODE = true
|
||||
LANDING_PAGE = explore
|
||||
|
@ -114,7 +101,10 @@ SQLITE_TIMEOUT = 500
|
|||
; ITERATE_BUFFER_SIZE = 50
|
||||
; Show the database generated SQL
|
||||
LOG_SQL = false
|
||||
SQLITE_JOURNAL_MODE = WAL
|
||||
|
||||
[session]
|
||||
PROVIDER_CONFIG = /data/gitea/sessions
|
||||
PROVIDER = file
|
||||
|
||||
[picture]
|
||||
AVATAR_UPLOAD_PATH = /data/gitea/avatars
|
||||
|
@ -126,11 +116,9 @@ ISSUE_INDEXER_PATH = indexers/issues.bleve
|
|||
; repo indexer by default disabled, since it uses a lot of disk space
|
||||
REPO_INDEXER_ENABLED = true
|
||||
REPO_INDEXER_PATH = indexers/repos.bleve
|
||||
UPDATE_BUFFER_LEN = 20
|
||||
MAX_FILE_SIZE = 1048576
|
||||
|
||||
[queue.issue_indexer]
|
||||
LENGTH = 100
|
||||
|
||||
[admin]
|
||||
; Disable regular (non-admin) users to create organizations
|
||||
DISABLE_REGULAR_ORG_CREATION = false
|
||||
|
@ -155,16 +143,15 @@ ACTIVE_CODE_LIVE_MINUTES = 15
|
|||
RESET_PASSWD_CODE_LIVE_MINUTES = 30
|
||||
REGISTER_EMAIL_CONFIRM = true
|
||||
ENABLE_NOTIFY_MAIL = true
|
||||
DISABLE_REGISTRATION = true
|
||||
DISABLE_REGISTRATION = false
|
||||
; ; Enable captcha validation for registration
|
||||
ENABLE_CAPTCHA = true
|
||||
REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA = true
|
||||
CAPTCHA_TYPE = image
|
||||
; ; User must sign in to view anything.
|
||||
REQUIRE_SIGNIN_VIEW = false
|
||||
; ; Default value for KeepEmailPrivate
|
||||
; ; 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
|
||||
; ; New user will have rights set to create organizations depending on this setting
|
||||
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||
|
@ -182,54 +169,60 @@ ENABLED = true
|
|||
FROM = git@captnemo.in
|
||||
USER = git@captnemo.in
|
||||
PASSWD = ${smtp_password}
|
||||
PROTOCOL = smtps
|
||||
SMTP_ADDR = smtp.migadu.com
|
||||
SMTP_PORT = 465
|
||||
HOST = smtp.migadu.com:587
|
||||
SEND_AS_PLAIN_TEXT = true
|
||||
SUBJECT_PREFIX = "[git.captnemo.in] "
|
||||
|
||||
[cache]
|
||||
ADAPTER = redis
|
||||
INTERVAL = 60
|
||||
HOST = "network=tcp,addr=gitea-redis:6379,db=0,pool_size=100,idle_timeout=180"
|
||||
ITEM_TTL = 16h
|
||||
|
||||
[session]
|
||||
; ; Either "memory", "file", or "redis", default is "memory"
|
||||
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"
|
||||
; ; Session cookie name
|
||||
COOKIE_NAME = i_like_gitea
|
||||
; ; If you use session in https only, default is false
|
||||
COOKIE_SECURE = true
|
||||
; SameSite settings. Either "none", "lax", or "strict"
|
||||
SAME_SITE = strict
|
||||
; ; Enable set cookie, default is true
|
||||
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]
|
||||
ALLOWED_DOMAINS = github.com
|
||||
ALLOW_LOCALNETWORKS = false
|
||||
[picture]
|
||||
|
||||
ENABLE_FEDERATED_AVATAR = true
|
||||
|
||||
[attachment]
|
||||
; ; Whether attachments are enabled. Defaults to `true`
|
||||
ENABLE = true
|
||||
; ; Path for attachments. Defaults to `data/attachments`
|
||||
PATH = data/attachments
|
||||
; ; 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
|
||||
; ; Max size of each file. Defaults to 32MB
|
||||
MAX_SIZE = 200
|
||||
MAX_SIZE = 20
|
||||
; ; Max number of files per upload. Defaults to 10
|
||||
MAX_FILES = 10
|
||||
|
||||
[log]
|
||||
ROOT_PATH =
|
||||
; Either "console", "file", "conn", "smtp" or "database", default is "console"
|
||||
; Use comma to separate multiple modes, e.g. "console, file"
|
||||
MODE = console
|
||||
; Buffer length of the channel, keep it as it is if you don't know what it is.
|
||||
BUFFER_LEN = 10000
|
||||
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
||||
LEVEL = Warn
|
||||
LEVEL = Critical
|
||||
REDIRECT_MACARON_LOG = true
|
||||
ROUTER_LOG_LEVEL = Critical
|
||||
logger.access.MODE=,
|
||||
logger.xorm.MODE=,
|
||||
ENABLE_ACCESS_LOG = true
|
||||
ENABLE_XORM_LOG = false
|
||||
|
||||
[cron]
|
||||
; Enable running cron tasks periodically.
|
||||
|
@ -239,7 +232,7 @@ RUN_AT_START = false
|
|||
|
||||
[cron.archive_cleanup]
|
||||
RUN_AT_START = true
|
||||
SCHEDULE = @midnight
|
||||
SCHEDULE = @every 24h
|
||||
; Archives created more than OLDER_THAN ago are subject to deletion
|
||||
OLDER_THAN = 24h
|
||||
|
||||
|
@ -250,7 +243,7 @@ SCHEDULE = @every 3h
|
|||
|
||||
; Repository health check
|
||||
[cron.repo_health_check]
|
||||
SCHEDULE = @midnight
|
||||
SCHEDULE = @every 24h
|
||||
TIMEOUT = 60s
|
||||
; Arguments for command 'git fsck', e.g. "--unreachable --tags"
|
||||
; see more on http://git-scm.com/docs/git-fsck
|
||||
|
@ -259,7 +252,7 @@ ARGS =
|
|||
; Check repository statistics
|
||||
[cron.check_repo_stats]
|
||||
RUN_AT_START = true
|
||||
SCHEDULE = @midnight
|
||||
SCHEDULE = @every 24h
|
||||
|
||||
[api]
|
||||
; Max number of items will response in a page
|
||||
|
@ -274,40 +267,39 @@ SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
|
|||
|
||||
[openid]
|
||||
ENABLE_OPENID_SIGNIN = true
|
||||
ENABLE_OPENID_SIGNUP = false
|
||||
ENABLE_OPENID_SIGNUP = true
|
||||
|
||||
[metrics]
|
||||
; Enables metrics endpoint. True or false; default is false.
|
||||
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]
|
||||
ENABLE = false
|
||||
; this is same as JWT secret above
|
||||
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: /
|
||||
User-agent: Xenu’s Link Sleuth 1.1c
|
||||
Disallow: /
|
||||
User-agent: AhrefsBot
|
||||
Disallow: /
|
||||
|
|
|
@ -18,5 +18,3 @@ User-agent: Xenu’s
|
|||
Disallow: /
|
||||
User-agent: Xenu’s Link Sleuth 1.1c
|
||||
Disallow: /
|
||||
User-agent: AhrefsBot
|
||||
Disallow: /
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# https://github.com/go-gitea/gitea/releases
|
||||
data "docker_registry_image" "gitea" {
|
||||
name = "gitea/gitea:1.21"
|
||||
# not bleeding, this is hemorrhaging edge
|
||||
name = "gitea/gitea:1.9"
|
||||
}
|
||||
|
||||
data "docker_registry_image" "redis" {
|
||||
|
@ -8,14 +9,14 @@ data "docker_registry_image" "redis" {
|
|||
}
|
||||
|
||||
data "template_file" "gitea-config-file" {
|
||||
template = file("${path.module}/conf/conf.ini.tpl")
|
||||
template = "${file("${path.module}/conf/conf.ini.tpl")}"
|
||||
|
||||
vars = {
|
||||
secret_key = var.secret-key
|
||||
internal_token = var.internal-token
|
||||
smtp_password = var.smtp-password
|
||||
lfs-jwt-secret = var.lfs-jwt-secret
|
||||
mysql-password = var.mysql-password
|
||||
oauth2-jwt-secret = var.oauth2-jwt-secret
|
||||
vars {
|
||||
secret_key = "${var.secret-key}"
|
||||
internal_token = "${var.internal-token}"
|
||||
smtp_password = "${var.smtp-password}"
|
||||
lfs-jwt-secret = "${var.lfs-jwt-secret}"
|
||||
mysql-password = "${var.mysql-password}"
|
||||
oauth2-jwt-secret = "${var.oauth2-jwt-secret}"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,89 +1,83 @@
|
|||
locals {
|
||||
l = merge(var.traefik-labels, {
|
||||
"traefik.port" = 3000
|
||||
"traefik.frontend.rule" = "Host:${var.domain}"
|
||||
})
|
||||
}
|
||||
|
||||
resource "docker_container" "gitea" {
|
||||
name = "gitea"
|
||||
image = docker_image.gitea.image_id
|
||||
image = "${docker_image.gitea.latest}"
|
||||
|
||||
dynamic "labels" {
|
||||
for_each = local.l
|
||||
content {
|
||||
label = labels.key
|
||||
value = labels.value
|
||||
labels = "${merge(
|
||||
var.traefik-labels, map(
|
||||
"traefik.port", 3000,
|
||||
"traefik.frontend.rule","Host:${var.domain}"
|
||||
))}"
|
||||
|
||||
ports {
|
||||
internal = 22
|
||||
external = 2222
|
||||
ip = "${var.ips["eth0"]}"
|
||||
}
|
||||
|
||||
ports {
|
||||
internal = 22
|
||||
external = 2222
|
||||
ip = "${var.ips["tun0"]}"
|
||||
}
|
||||
|
||||
volumes {
|
||||
volume_name = docker_volume.gitea_volume.name
|
||||
volume_name = "${docker_volume.gitea_volume.name}"
|
||||
container_path = "/data"
|
||||
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
|
||||
# TODO: Add svg
|
||||
|
||||
# https://docs.gitea.com/next/administration/customizing-gitea#changing-the-logo
|
||||
# PNG images
|
||||
upload {
|
||||
content_base64 = filebase64("${path.module}/conf/public/img/gitea-lg.png")
|
||||
file = "/data/gitea/public/img/logo.png"
|
||||
content = "${file("${path.module}/conf/public/img/gitea-lg.png")}"
|
||||
file = "/data/gitea/public/img/gitea-lg.png"
|
||||
}
|
||||
upload {
|
||||
content_base64 = filebase64("${path.module}/conf/public/img/gitea-lg.png")
|
||||
file = "/data/gitea/public/img/apple-touch-icon.png"
|
||||
content = "${file("${path.module}/conf/public/img/gitea-sm.png")}"
|
||||
file = "/data/gitea/public/img/gitea-sm.png"
|
||||
}
|
||||
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"
|
||||
}
|
||||
|
||||
# SVG images
|
||||
upload {
|
||||
content_base64 = filebase64("${path.module}/conf/public/img/favicon.svg")
|
||||
file = "/data/gitea/public/img/logo.svg"
|
||||
executable = false
|
||||
}
|
||||
upload {
|
||||
content_base64 = filebase64("${path.module}/conf/public/img/favicon.svg")
|
||||
file = "/data/gitea/public/img/favicon.svg"
|
||||
}
|
||||
|
||||
# Some files at top-level
|
||||
upload {
|
||||
content = file("${path.module}/../docker/conf/humans.txt")
|
||||
file = "/data/gitea/humans.txt"
|
||||
content = "${file("${path.module}/../docker/conf/humans.txt")}"
|
||||
file = "/data/gitea/public/humans.txt"
|
||||
}
|
||||
upload {
|
||||
content = file("${path.module}/conf/public/robots.txt")
|
||||
file = "/data/gitea/robots.txt"
|
||||
content = "${file("${path.module}/conf/public/robots.txt")}"
|
||||
file = "/data/gitea/public/robots.txt"
|
||||
}
|
||||
|
||||
# Extra Links in header
|
||||
upload {
|
||||
content = file("${path.module}/conf/extra_links.tmpl")
|
||||
content = "${file("${path.module}/conf/extra_links.tmpl")}"
|
||||
file = "/data/gitea/templates/custom/extra_links.tmpl"
|
||||
}
|
||||
|
||||
# This is the main configuration file
|
||||
upload {
|
||||
content = data.template_file.gitea-config-file.rendered
|
||||
content = "${data.template_file.gitea-config-file.rendered}"
|
||||
file = "/data/gitea/conf/app.ini"
|
||||
}
|
||||
|
||||
memory = 800
|
||||
memory = 256
|
||||
restart = "always"
|
||||
destroy_grace_seconds = 10
|
||||
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" {
|
||||
name = data.docker_registry_image.gitea.name
|
||||
pull_triggers = [data.docker_registry_image.gitea.sha256_digest]
|
||||
name = "${data.docker_registry_image.gitea.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.gitea.sha256_digest}"]
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -2,4 +2,3 @@ resource "docker_network" "gitea" {
|
|||
name = "gitea"
|
||||
driver = "bridge"
|
||||
}
|
||||
|
||||
|
|
|
@ -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" {
|
||||
name = "gitea-redis"
|
||||
image = docker_image.redis.image_id
|
||||
image = "${docker_image.redis.latest}"
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/cache/gitea"
|
||||
|
@ -12,12 +12,11 @@ resource "docker_container" "redis" {
|
|||
destroy_grace_seconds = 10
|
||||
must_run = true
|
||||
|
||||
networks = [docker_network.gitea.id]
|
||||
networks = ["${docker_network.gitea.id}"]
|
||||
}
|
||||
|
||||
resource "docker_image" "redis" {
|
||||
name = data.docker_registry_image.redis.name
|
||||
pull_triggers = [data.docker_registry_image.redis.sha256_digest]
|
||||
name = "${data.docker_registry_image.redis.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.redis.sha256_digest}"]
|
||||
keep_locally = true
|
||||
}
|
||||
|
||||
|
|
|
@ -1,32 +1,18 @@
|
|||
variable "traefik-labels" {
|
||||
type = map(string)
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
}
|
||||
variable "domain" {}
|
||||
|
||||
variable "ips" {
|
||||
type = map(string)
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "secret-key" {
|
||||
}
|
||||
|
||||
variable "internal-token" {
|
||||
}
|
||||
|
||||
variable "smtp-password" {
|
||||
}
|
||||
|
||||
variable "lfs-jwt-secret" {
|
||||
}
|
||||
|
||||
variable "oauth2-jwt-secret" {
|
||||
}
|
||||
|
||||
variable "mysql-password" {
|
||||
}
|
||||
|
||||
variable "traefik-network-id" {
|
||||
}
|
||||
variable "secret-key" {}
|
||||
variable "internal-token" {}
|
||||
variable "smtp-password" {}
|
||||
variable "lfs-jwt-secret" {}
|
||||
variable "oauth2-jwt-secret" {}
|
||||
variable "mysql-password" {}
|
||||
|
||||
variable "traefik-network-id" {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
resource "docker_volume" "gitea_volume" {
|
||||
name = "gitea_volume"
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# module "heimdall" {
|
||||
# name = "heimdall"
|
||||
# source = "modules/container"
|
||||
# image = "linuxserver/heimdall:latest"
|
||||
# web {
|
||||
# expose = true
|
||||
# port = 443
|
||||
# protocol = "https"
|
||||
# basicauth = "true"
|
||||
# host = "home.bb8.fun"
|
||||
# }
|
||||
# networks = "${list(module.docker.traefik-network-id)}"
|
||||
# env = [
|
||||
# "TZ=Asia/Kolkata",
|
||||
# ]
|
||||
# }
|
||||
|
|
@ -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"
|
||||
},
|
||||
]
|
||||
}
|
29
jupyter.tf
29
jupyter.tf
|
@ -1,16 +1,13 @@
|
|||
module "jupyter" {
|
||||
name = "jupyter"
|
||||
source = "./modules/container"
|
||||
image = "jupyter/scipy-notebook"
|
||||
resource = {
|
||||
memory = 1024
|
||||
memory_swap = 4096
|
||||
}
|
||||
web = {
|
||||
expose = "true"
|
||||
host = "j.${var.root-domain}"
|
||||
port = 8888
|
||||
}
|
||||
networks = ["bridge"]
|
||||
gpu = true
|
||||
}
|
||||
# module "jupyter" {
|
||||
# name = "jupyter"
|
||||
# source = "modules/container"
|
||||
# image = "jupyter/tensorflow-notebook"
|
||||
# ports = [
|
||||
# {
|
||||
# internal = 8888
|
||||
# external = 1112
|
||||
# ip = "${var.ips["tun0"]}"
|
||||
# },
|
||||
# ]
|
||||
# }
|
||||
|
||||
|
|
17
kaarana.tf
17
kaarana.tf
|
@ -1,15 +1,15 @@
|
|||
# kaarana related stuff
|
||||
|
||||
# module "kaarana" {
|
||||
# source = "./kaarana"
|
||||
module "kaarana" {
|
||||
source = "./kaarana"
|
||||
|
||||
# root_db_password = data.pass_password.kaarana-root-db-password.password
|
||||
# db_password = data.pass_password.kaarana-db-password.password
|
||||
root_db_password = "${data.pass_password.kaarana-root-db-password.password}"
|
||||
db_password = "${data.pass_password.kaarana-db-password.password}"
|
||||
|
||||
# providers = {
|
||||
# docker = docker.sydney
|
||||
# }
|
||||
# }
|
||||
providers = {
|
||||
docker = "docker.sydney"
|
||||
}
|
||||
}
|
||||
|
||||
data "pass_password" "kaarana-root-db-password" {
|
||||
path = "KAARANA_DB_ROOT_PASSWORD"
|
||||
|
@ -18,4 +18,3 @@ data "pass_password" "kaarana-root-db-password" {
|
|||
data "pass_password" "kaarana-db-password" {
|
||||
path = "KAARANA_DB_PASSWORD"
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ resource "docker_network" "kaarana-db" {
|
|||
// Run a small mySQL container in this subnet
|
||||
|
||||
resource "docker_container" "mysql" {
|
||||
image = docker_image.db.image_id
|
||||
image = "${docker_image.db.latest}"
|
||||
name = "kaarana-mariadb"
|
||||
restart = "always"
|
||||
must_run = true
|
||||
|
@ -35,6 +35,8 @@ resource "docker_container" "mysql" {
|
|||
container_path = "/var/lib/mysql"
|
||||
}
|
||||
|
||||
networks = ["kaarana-db"]
|
||||
networks_advanced {
|
||||
name = "kaarana-db"
|
||||
aliases = ["${local.db_hostname}"]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
[http.middlewares]
|
||||
[http.middlewares.redirect.redirectScheme]
|
||||
scheme = "https"
|
||||
|
||||
[tcp.routers]
|
||||
[tcp.routers.forwardtohome]
|
||||
entryPoints = ["web-secure"]
|
||||
# TODO: Somehow change this back to:
|
||||
# `*.bb8.fun`, `rss.captnemo.in`, `git.captnemo.in`
|
||||
rule = "HostSNI(`airsonic.bb8.fun`,`audioserve.bb8.fun`,`bazarr.bb8.fun`,`debug.bb8.fun`,`ebooks.bb8.fun`,`emby.bb8.fun`,`firesync.bb8.fun`,`git.captnemo.in`,`grafana.bb8.fun`,`jackett.bb8.fun`,`lidarr.bb8.fun`,`media.bb8.fun`,`mylar.bb8.fun`,`opml.bb8.fun`,`radarr.bb8.fun`,`radicale.bb8.fun`,`rss-bridge.bb8.fun`,`rss.captnemo.in`,`sonarr.bb8.fun`,`transmission.bb8.fun`,`wiki.bb8.fun`,`library.bb8.fun`,`read.bb8.fun`,`comics.bb8.fun`,`books.bb8.fun`)"
|
||||
# rule= "HostSNI(*)"
|
||||
# Give this lower priority
|
||||
priority = 1
|
||||
service = "homeserver"
|
||||
[tcp.routers.forwardtohome.tls]
|
||||
passthrough = true
|
||||
|
||||
[tcp.services]
|
||||
[tcp.services.homeserver.loadBalancer]
|
||||
[[tcp.services.homeserver.loadBalancer.servers]]
|
||||
address = "10.8.0.14:443"
|
|
@ -4,7 +4,7 @@ data "docker_registry_image" "wp" {
|
|||
|
||||
resource "docker_image" "wp" {
|
||||
name = "wordpress"
|
||||
pull_triggers = [data.docker_registry_image.wp.sha256_digest]
|
||||
pull_triggers = ["${data.docker_registry_image.wp.sha256_digest}"]
|
||||
}
|
||||
|
||||
data "docker_registry_image" "db" {
|
||||
|
@ -13,7 +13,7 @@ data "docker_registry_image" "db" {
|
|||
|
||||
resource "docker_image" "db" {
|
||||
name = "mariadb"
|
||||
pull_triggers = [data.docker_registry_image.db.sha256_digest]
|
||||
pull_triggers = ["${data.docker_registry_image.db.sha256_digest}"]
|
||||
}
|
||||
|
||||
data "docker_registry_image" "traefik" {
|
||||
|
@ -22,6 +22,5 @@ data "docker_registry_image" "traefik" {
|
|||
|
||||
resource "docker_image" "traefik" {
|
||||
name = "traefik"
|
||||
pull_triggers = [data.docker_registry_image.db.sha256_digest]
|
||||
pull_triggers = ["${data.docker_registry_image.db.sha256_digest}"]
|
||||
}
|
||||
|
||||
|
|
|
@ -12,19 +12,18 @@ resource "docker_network" "traefik" {
|
|||
|
||||
resource "docker_container" "traefik" {
|
||||
name = "traefik"
|
||||
image = docker_image.traefik.image_id
|
||||
|
||||
# Do not offer HTTP2
|
||||
# https://community.containo.us/t/traefikv2-http-2-0/1199
|
||||
env = [
|
||||
"GODEBUG=http2client=0",
|
||||
]
|
||||
image = "${docker_image.traefik.latest}"
|
||||
|
||||
upload {
|
||||
content = file("${path.module}/traefik.toml")
|
||||
content = "${file("${path.module}/traefik.toml")}"
|
||||
file = "/etc/traefik/traefik.toml"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = "${file("${path.module}/dyn.toml")}"
|
||||
file = "/etc/traefik/dyn.toml"
|
||||
}
|
||||
|
||||
volumes {
|
||||
host_path = "/var/run/docker.sock"
|
||||
container_path = "/var/run/docker.sock"
|
||||
|
@ -38,7 +37,7 @@ resource "docker_container" "traefik" {
|
|||
|
||||
ports {
|
||||
internal = 443
|
||||
external = 8443
|
||||
external = 443
|
||||
ip = "139.59.22.234"
|
||||
}
|
||||
|
||||
|
@ -53,12 +52,12 @@ resource "docker_container" "traefik" {
|
|||
destroy_grace_seconds = 10
|
||||
must_run = true
|
||||
|
||||
networks_advanced {
|
||||
networks_advanced = [
|
||||
{
|
||||
name = "bridge"
|
||||
}
|
||||
|
||||
networks_advanced {
|
||||
},
|
||||
{
|
||||
name = "traefik"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
# This configures docker service discovery
|
||||
# traefik.toml
|
||||
# Static configuration
|
||||
|
||||
[providers.docker]
|
||||
exposedByDefault = false
|
||||
network = "traefik"
|
||||
defaultRule = ""
|
||||
|
||||
[providers.file]
|
||||
filename = "/etc/traefik/dyn.toml"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
|
@ -11,35 +15,9 @@ defaultRule = ""
|
|||
[entryPoints.web-secure]
|
||||
address = ":443"
|
||||
|
||||
[http.middlewares]
|
||||
[http.middlewares.everything.redirectScheme]
|
||||
scheme = "https"
|
||||
|
||||
[tcp.routers]
|
||||
[tcp.routers.forwardtohome]
|
||||
entryPoints = ["web-secure"]
|
||||
rule = "HostSNI(`emby.bb8.fun`, `git.captnemo.in`)"
|
||||
service = "homeserver"
|
||||
[tcp.routers.forwardtohome.tls]
|
||||
passthrough = true
|
||||
|
||||
[tcp.services]
|
||||
[tcp.services.homeserver.loadBalancer]
|
||||
[[tcp.services.homeserver.loadBalancer.servers]]
|
||||
address = "10.8.0.14:443"
|
||||
|
||||
[certificatesResolvers.default.acme]
|
||||
email = "certs@captnemo.in"
|
||||
storage = "/acme/acme.json"
|
||||
[certificatesResolvers.default.acme.httpChallenge]
|
||||
# used during the challenge
|
||||
entryPoint = "web"
|
||||
|
||||
|
||||
[tls.options]
|
||||
[tls.options.foo]
|
||||
minVersion = "VersionTLS12"
|
||||
cipherSuites = [
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_RSA_WITH_AES_256_GCM_SHA384"
|
||||
]
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
variable "root_db_password" {
|
||||
}
|
||||
|
||||
variable "db_password" {
|
||||
}
|
||||
variable "root_db_password" {}
|
||||
variable "db_password" {}
|
||||
|
||||
locals {
|
||||
username = "wordpress"
|
||||
database = "wordpress"
|
||||
db_hostname = "kaarana.db"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
resource "docker_container" "wp" {
|
||||
image = docker_image.wp.image_id
|
||||
image = "${docker_image.wp.latest}"
|
||||
name = "kaarana-wordpress"
|
||||
|
||||
restart = "always"
|
||||
must_run = true
|
||||
|
||||
labels = {
|
||||
labels {
|
||||
"traefik.enable" = "true"
|
||||
"traefik.tcp.routers.kaarana.rule" = "HostSNI(`kaarana.captnemo.in`)"
|
||||
"traefik.tcp.routers.kaarana.tls" = "true"
|
||||
# "traefik.tcp.routers.kaarana.tls.options" = "foo"
|
||||
"traefik.tcp.services.wordpress.loadbalancer.server.port" = "80"
|
||||
# "traefik.tcp.routers.kaarana.entrypoints" = "web-secure"
|
||||
"traefik.tcp.routers.kaarana.tls.certResolver" = "default"
|
||||
"traefik.tcp.routers.kaarana.tls.domains[0].main" = "kaarana.captnemo.in"
|
||||
|
||||
# Redirect Setup
|
||||
"traefik.http.routers.kaarana-insecure.rule" = "Host(`kaarana.captnemo.in`)"
|
||||
"traefik.http.routers.kaarana-insecure.entrypoints" = "web"
|
||||
"traefik.http.routers.kaarana-insecure.middlewares" = "redirect"
|
||||
"traefik.http.middlewares.redirect.redirectScheme.scheme" = "https"
|
||||
|
||||
"traefik.http.routers.kaarana" = "true"
|
||||
"traefik.http.routers.kaarana.priority" = "2" #Doesn't help
|
||||
"traefik.http.routers.kaarana.entrypoints" = "web-secure"
|
||||
"traefik.http.routers.kaarana.rule" = "Host(`kaarana.captnemo.in`)"
|
||||
"traefik.http.routers.kaarana.tls.certResolver" = "default"
|
||||
}
|
||||
|
||||
env = [
|
||||
|
@ -29,12 +34,17 @@ resource "docker_container" "wp" {
|
|||
container_path = "/var/www/html"
|
||||
}
|
||||
|
||||
ports {
|
||||
internal = 80
|
||||
external = 8213
|
||||
ip = "10.8.0.1"
|
||||
networks_advanced = [
|
||||
{
|
||||
name = "kaarana-db"
|
||||
},
|
||||
{
|
||||
// TODO: Once configuration/plugins have stabilized
|
||||
// remove internet access from wordpress
|
||||
name = "bridge"
|
||||
},
|
||||
{
|
||||
name = "traefik"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
networks = ["bridge", "kaarana-db"]
|
||||
}
|
||||
|
||||
|
|
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",
|
||||
# ]
|
||||
# }
|
40
klaxon.tf
40
klaxon.tf
|
@ -1,40 +0,0 @@
|
|||
module "klaxon-db" {
|
||||
source = "./modules/postgres"
|
||||
name = "klaxon"
|
||||
password = data.pass_password.klaxon-db-password.password
|
||||
}
|
||||
|
||||
module "klaxon" {
|
||||
name = "klaxon"
|
||||
source = "./modules/container"
|
||||
|
||||
web = {
|
||||
expose = true
|
||||
port = "3000"
|
||||
host = "klaxon.${var.root-domain}"
|
||||
}
|
||||
|
||||
resource = {
|
||||
memory = 1024
|
||||
memory_swap = 1024
|
||||
}
|
||||
|
||||
env = [
|
||||
"DATABASE_URL=postgres://klaxon:${data.pass_password.klaxon-db-password.password}@postgres/klaxon",
|
||||
"ADMIN_EMAILS=klaxon.admin@captnemo.in",
|
||||
"RAILS_ENV=production",
|
||||
"SECRET_KEY_BASE=${data.pass_password.klaxon-secret-key.password}",
|
||||
"SENDGRID_USERNAME=apikey",
|
||||
"SENDGRID_PASSWORD=${data.pass_password.klaxon-sendgrid-password.password}",
|
||||
"KLAXON_FORCE_SSL=false",
|
||||
"KLAXON_COMPILE_ASSETS=true",
|
||||
"ADMIN_EMAILS=klaxon@captnemo.in",
|
||||
"MAILER_FROM_ADDRESS=klaxon@sendgrid.captnemo.in",
|
||||
]
|
||||
restart = "always"
|
||||
|
||||
image = "themarshallproject/klaxon"
|
||||
|
||||
networks = ["postgres", "external"]
|
||||
}
|
||||
|
|
@ -17,3 +17,4 @@
|
|||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
|
|
124
main.tf
124
main.tf
|
@ -1,112 +1,110 @@
|
|||
module "cloudflare" {
|
||||
source = "./cloudflare"
|
||||
source = "cloudflare"
|
||||
domain = "bb8.fun"
|
||||
zone_id = lookup(data.cloudflare_zones.bb8.zones[0], "id")
|
||||
ips = var.ips
|
||||
ips = "${var.ips}"
|
||||
|
||||
droplet_ip = module.digitalocean.droplet_ipv4
|
||||
droplet_ip = "${module.digitalocean.droplet_ipv4}"
|
||||
}
|
||||
|
||||
module "docker" {
|
||||
source = "./docker"
|
||||
web_username = data.pass_password.web_username.password
|
||||
web_password = data.pass_password.web_password.password
|
||||
cloudflare_key = data.pass_password.cloudflare_key.password
|
||||
source = "docker"
|
||||
web_username = "${data.pass_password.web_username.password}"
|
||||
web_password = "${data.pass_password.web_password.password}"
|
||||
cloudflare_key = "${data.pass_password.cloudflare_key.password}"
|
||||
cloudflare_email = "bb8@captnemo.in"
|
||||
wiki_session_secret = data.pass_password.wiki_session_secret.password
|
||||
ips = var.ips
|
||||
wiki_session_secret = "${data.pass_password.wiki_session_secret.password}"
|
||||
networks-mongorocks = "${module.db.networks-mongorocks}"
|
||||
ips = "${var.ips}"
|
||||
domain = "bb8.fun"
|
||||
}
|
||||
|
||||
module "db" {
|
||||
source = "./db"
|
||||
postgres-root-password = data.pass_password.postgres-root-password.password
|
||||
ips = var.ips
|
||||
source = "db"
|
||||
postgres-root-password = "${data.pass_password.postgres-root-password.password}"
|
||||
ips = "${var.ips}"
|
||||
}
|
||||
|
||||
module "timemachine" {
|
||||
source = "./timemachine"
|
||||
ips = var.ips
|
||||
source = "timemachine"
|
||||
ips = "${var.ips}"
|
||||
username-1 = "vikalp"
|
||||
username-2 = "rishav"
|
||||
password-1 = data.pass_password.timemachine-password-1.password
|
||||
password-2 = data.pass_password.timemachine-password-2.password
|
||||
password-1 = "${data.pass_password.timemachine-password-1.password}"
|
||||
password-2 = "${data.pass_password.timemachine-password-2.password}"
|
||||
}
|
||||
|
||||
module "gitea" {
|
||||
source = "./gitea"
|
||||
source = "gitea"
|
||||
domain = "git.captnemo.in"
|
||||
traefik-labels = var.traefik-common-labels
|
||||
ips = var.ips
|
||||
secret-key = data.pass_password.gitea-secret-key.password
|
||||
internal-token = data.pass_password.gitea-internal-token.password
|
||||
smtp-password = data.pass_password.gitea-smtp-password.password
|
||||
lfs-jwt-secret = data.pass_password.gitea-lfs-jwt-secret.password
|
||||
oauth2-jwt-secret = data.pass_password.gitea-oauth2-jwt-secret.password
|
||||
traefik-labels = "${var.traefik-common-labels}"
|
||||
ips = "${var.ips}"
|
||||
secret-key = "${data.pass_password.gitea-secret-key.password}"
|
||||
internal-token = "${data.pass_password.gitea-internal-token.password}"
|
||||
smtp-password = "${data.pass_password.gitea-smtp-password.password}"
|
||||
lfs-jwt-secret = "${data.pass_password.gitea-lfs-jwt-secret.password}"
|
||||
oauth2-jwt-secret = "${data.pass_password.gitea-oauth2-jwt-secret.password}"
|
||||
|
||||
//passed, but not used
|
||||
mysql-password = ""
|
||||
|
||||
traefik-network-id = module.docker.traefik-network-id
|
||||
traefik-network-id = "${module.docker.traefik-network-id}"
|
||||
}
|
||||
|
||||
module "opml" {
|
||||
source = "./opml"
|
||||
source = "opml"
|
||||
domain = "opml.bb8.fun"
|
||||
client-id = data.pass_password.opml-github-client-id.password
|
||||
client-secret = data.pass_password.opml-github-client-secret.password
|
||||
traefik-network-id = module.docker.traefik-network-id
|
||||
client-id = "${data.pass_password.opml-github-client-id.password}"
|
||||
client-secret = "${data.pass_password.opml-github-client-secret.password}"
|
||||
traefik-network-id = "${module.docker.traefik-network-id}"
|
||||
}
|
||||
|
||||
module "radicale" {
|
||||
source = "./radicale"
|
||||
source = "radicale"
|
||||
domain = "radicale.bb8.fun"
|
||||
}
|
||||
|
||||
# module "resilio" {
|
||||
# source = "resilio"
|
||||
# domain = "sync.bb8.fun"
|
||||
# traefik-labels = "${var.traefik-common-labels}"
|
||||
# ips = "${var.ips}"
|
||||
# traefik-network-id = "${module.docker.traefik-network-id}"
|
||||
# }
|
||||
|
||||
module "media" {
|
||||
source = "./media"
|
||||
source = "media"
|
||||
domain = "bb8.fun"
|
||||
traefik-labels = var.traefik-common-labels
|
||||
ips = var.ips
|
||||
# ToDO: Change this to lookup
|
||||
traefik-network-id = "ffc1e366849e"
|
||||
lastfm_api_key = data.pass_password.navidrome-lastfm-api-key.password
|
||||
lastfm_secret = data.pass_password.navidrome-lastfm-secret.password
|
||||
spotify_id = data.pass_password.navidrome-spotify-id.password
|
||||
spotify_secret = data.pass_password.navidrome-spotify-secret.password
|
||||
traefik-labels = "${var.traefik-common-labels}"
|
||||
ips = "${var.ips}"
|
||||
traefik-network-id = "${module.docker.traefik-network-id}"
|
||||
}
|
||||
|
||||
module "monitoring" {
|
||||
source = "./monitoring"
|
||||
gf-security-admin-password = data.pass_password.gf-security-admin-password.password
|
||||
source = "monitoring"
|
||||
gf-security-admin-password = "${data.pass_password.gf-security-admin-password.password}"
|
||||
domain = "bb8.fun"
|
||||
transmission = module.media.names-transmission
|
||||
traefik-labels = var.traefik-common-labels
|
||||
ips = var.ips
|
||||
links-traefik = module.docker.names-traefik
|
||||
traefik-network-id = module.docker.traefik-network-id
|
||||
transmission = "${module.media.names-transmission}"
|
||||
traefik-labels = "${var.traefik-common-labels}"
|
||||
ips = "${var.ips}"
|
||||
links-traefik = "${module.docker.names-traefik}"
|
||||
traefik-network-id = "${module.docker.traefik-network-id}"
|
||||
}
|
||||
|
||||
module "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
|
||||
source = "digitalocean"
|
||||
}
|
||||
|
||||
// Used to force access to ISP related resources
|
||||
# module "tinyproxy" {
|
||||
# source = "./tinyproxy"
|
||||
# source = "tinyproxy"
|
||||
# ips = "${var.ips}"
|
||||
# }
|
||||
|
||||
|
||||
# module "abstruse" {
|
||||
# source = "abstruse"
|
||||
# domain = "ci.bb8.fun"
|
||||
# traefik-labels = "${var.traefik-common-labels}"
|
||||
# traefik-network-id = "${module.docker.traefik-network-id}"
|
||||
# }
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -1,62 +1,77 @@
|
|||
# module "airsonic" {
|
||||
# source = "../modules/container"
|
||||
# image = "linuxserver/airsonic:latest"
|
||||
# name = "airsonic"
|
||||
# resource {
|
||||
# memory = "1024"
|
||||
# memory_swap = "1024"
|
||||
# }
|
||||
# web {
|
||||
# port = 4040
|
||||
# host = "airsonic.bb8.fun"
|
||||
# expose = true
|
||||
# }
|
||||
# networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
|
||||
# env = [
|
||||
# "PUID=1004",
|
||||
# "PGID=1003",
|
||||
# "TZ=Asia/Kolkata",
|
||||
# "JAVA_OPTS=-Xmx512m -Dserver.use-forward-headers=true -Dserver.context-path=/",
|
||||
module "airsonic" {
|
||||
source = "../modules/container"
|
||||
image = "linuxserver/airsonic:latest"
|
||||
name = "airsonic"
|
||||
|
||||
resource {
|
||||
memory = "1024"
|
||||
memory_swap = "1024"
|
||||
}
|
||||
|
||||
web {
|
||||
port = 4040
|
||||
host = "airsonic.bb8.fun"
|
||||
expose = true
|
||||
}
|
||||
|
||||
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
|
||||
|
||||
env = [
|
||||
"PUID=1004",
|
||||
"PGID=1003",
|
||||
"TZ=Asia/Kolkata",
|
||||
"JAVA_OPTS=-Xmx512m -Dserver.use-forward-headers=true -Dserver.context-path=/",
|
||||
]
|
||||
|
||||
devices = [{
|
||||
host_path = "/dev/snd"
|
||||
container_path = "/dev/snd"
|
||||
}]
|
||||
|
||||
# files = [
|
||||
# "/usr/lib/jvm/java-1.8-openjdk/jre/lib/airsonic.properties",
|
||||
# "/usr/lib/jvm/java-1.8-openjdk/jre/lib/sound.properties",
|
||||
# ]
|
||||
# devices = [{
|
||||
# host_path = "/dev/snd"
|
||||
# container_path = "/dev/snd"
|
||||
# }]
|
||||
# # files = [
|
||||
# # "/usr/lib/jvm/java-1.8-openjdk/jre/lib/airsonic.properties",
|
||||
# # "/usr/lib/jvm/java-1.8-openjdk/jre/lib/sound.properties",
|
||||
# # ]
|
||||
# # contents = [
|
||||
# # "${data.template_file.airsonic-properties-file.rendered}",
|
||||
# # "${file("${path.module}/conf/airsonic.sound.properties")}",
|
||||
# # ]
|
||||
# volumes = [
|
||||
# {
|
||||
# host_path = "/mnt/xwing/config/airsonic2"
|
||||
# container_path = "/config"
|
||||
# },
|
||||
# {
|
||||
# host_path = "/mnt/xwing/media/Music"
|
||||
# container_path = "/music"
|
||||
# },
|
||||
# {
|
||||
# host_path = "/mnt/xwing/config/airsonic/playlists"
|
||||
# container_path = "/playlists"
|
||||
# },
|
||||
# {
|
||||
# host_path = "/mnt/xwing/config/airsonic/podcasts"
|
||||
# container_path = "/podcasts"
|
||||
# },
|
||||
# {
|
||||
# host_path = "/mnt/xwing/config/airsonic/jre"
|
||||
# container_path = "/usr/lib/jvm/java-1.8-openjdk/jre/lib/"
|
||||
# },
|
||||
|
||||
|
||||
# contents = [
|
||||
# "${data.template_file.airsonic-properties-file.rendered}",
|
||||
# "${file("${path.module}/conf/airsonic.sound.properties")}",
|
||||
# ]
|
||||
# }
|
||||
|
||||
volumes = [
|
||||
{
|
||||
host_path = "/mnt/xwing/config/airsonic2"
|
||||
container_path = "/config"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/media/Music"
|
||||
container_path = "/music"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/config/airsonic/playlists"
|
||||
container_path = "/playlists"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/config/airsonic/podcasts"
|
||||
container_path = "/podcasts"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/config/airsonic/jre"
|
||||
container_path = "/usr/lib/jvm/java-1.8-openjdk/jre/lib/"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
# data "template_file" "airsonic-properties-file" {
|
||||
# template = "${file("${path.module}/conf/airsonic.properties.tpl")}"
|
||||
|
||||
|
||||
# vars {
|
||||
# smtp-password = "${var.airsonic-smtp-password}"
|
||||
|
||||
|
||||
# # db-password = "${var.airsonic-db-password}"
|
||||
# }
|
||||
# }
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
module "bazarr-container" {
|
||||
name = "bazarr"
|
||||
source = "../modules/container"
|
||||
image = "linuxserver/bazarr:latest"
|
||||
|
||||
web {
|
||||
expose = true
|
||||
port = 6767
|
||||
host = "bazarr.${var.domain}"
|
||||
}
|
||||
|
||||
resource {
|
||||
memory = 512
|
||||
memory_swap = 1024
|
||||
}
|
||||
|
||||
volumes = [
|
||||
{
|
||||
host_path = "/mnt/xwing/config/bazarr"
|
||||
container_path = "/config"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/media/TV"
|
||||
container_path = "/tv"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/media/Movies"
|
||||
container_path = "/movies"
|
||||
},
|
||||
]
|
||||
|
||||
env = [
|
||||
"PUID=1004",
|
||||
"PGID=1003",
|
||||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
|
||||
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
|
||||
}
|
|
@ -10,17 +10,17 @@
|
|||
"bind-address-ipv6": "::",
|
||||
"blocklist-enabled": true,
|
||||
"blocklist-url": "http://john.bitsurge.net/public/biglist.p2p.gz",
|
||||
"cache-size-mb": 256,
|
||||
"cache-size-mb": 16,
|
||||
"dht-enabled": true,
|
||||
"download-dir": "/downloads",
|
||||
"download-queue-enabled": false,
|
||||
"download-queue-enabled": true,
|
||||
"download-queue-size": 5,
|
||||
"encryption": 1,
|
||||
"idle-seeding-limit": 30,
|
||||
"idle-seeding-limit-enabled": false,
|
||||
"incomplete-dir": "/downloads",
|
||||
"incomplete-dir-enabled": true,
|
||||
"lpd-enabled": true,
|
||||
"lpd-enabled": false,
|
||||
"message-level": 2,
|
||||
"peer-congestion-algorithm": "",
|
||||
"peer-id-ttl-hours": 6,
|
||||
|
@ -31,13 +31,13 @@
|
|||
"peer-port-random-low": 49152,
|
||||
"peer-port-random-on-start": false,
|
||||
"peer-socket-tos": "default",
|
||||
"pex-enabled": false,
|
||||
"pex-enabled": true,
|
||||
"port-forwarding-enabled": true,
|
||||
"preallocation": 1,
|
||||
"prefetch-enabled": true,
|
||||
"queue-stalled-enabled": false,
|
||||
"queue-stalled-enabled": true,
|
||||
"queue-stalled-minutes": 30,
|
||||
"ratio-limit": 1.2,
|
||||
"ratio-limit": 0.2,
|
||||
"ratio-limit-enabled": true,
|
||||
"rename-partial-files": true,
|
||||
"rpc-host-whitelist": "transmission.bb8.fun,transmission",
|
||||
|
@ -51,19 +51,19 @@
|
|||
"rpc-username": "",
|
||||
"rpc-whitelist": "127.0.0.1",
|
||||
"rpc-whitelist-enabled": false,
|
||||
"scrape-paused-torrents-enabled": false,
|
||||
"scrape-paused-torrents-enabled": true,
|
||||
"script-torrent-done-enabled": false,
|
||||
"script-torrent-done-filename": "",
|
||||
"seed-queue-enabled": true,
|
||||
"seed-queue-size": 50,
|
||||
"seed-queue-enabled": false,
|
||||
"seed-queue-size": 10,
|
||||
"speed-limit-down": 100,
|
||||
"speed-limit-down-enabled": false,
|
||||
"speed-limit-up": 50,
|
||||
"speed-limit-up-enabled": false,
|
||||
"speed-limit-up-enabled": true,
|
||||
"start-added-torrents": true,
|
||||
"trash-original-torrent-files": false,
|
||||
"umask": 2,
|
||||
"upload-slots-per-torrent": 10,
|
||||
"upload-slots-per-torrent": 14,
|
||||
"utp-enabled": true,
|
||||
"watch-dir": "/watch",
|
||||
"watch-dir-enabled": true
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
data "docker_network" "bridge" {
|
||||
name = "bridge"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,74 +1,47 @@
|
|||
|
||||
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" {
|
||||
name = "emby"
|
||||
image = docker_image.emby.image_id
|
||||
image = "${docker_image.emby.latest}"
|
||||
|
||||
# SSD holds both the cache and data
|
||||
volumes {
|
||||
host_path = "/mnt/zwing/config/emby"
|
||||
host_path = "/mnt/xwing/config/emby"
|
||||
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 {
|
||||
host_path = "/mnt/xwing/media"
|
||||
container_path = "/media"
|
||||
}
|
||||
|
||||
dynamic "labels" {
|
||||
for_each = local.emby_labels
|
||||
content {
|
||||
label = labels.key
|
||||
value = labels.value
|
||||
}
|
||||
}
|
||||
labels = "${merge(
|
||||
var.traefik-labels,
|
||||
map(
|
||||
"traefik.frontend.rule", "Host:emby.in.${var.domain},emby.${var.domain}",
|
||||
"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}"]
|
||||
|
||||
memory = 2048
|
||||
restart = "unless-stopped"
|
||||
destroy_grace_seconds = 10
|
||||
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
|
||||
env = [
|
||||
"UID=1004",
|
||||
"GID=1003",
|
||||
"GIDLIST=1003"
|
||||
"APP_USER=lounge",
|
||||
"APP_UID=1004",
|
||||
"APP_GID=1003",
|
||||
"APP_CONFIG=/mnt/xwing/config",
|
||||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
}
|
||||
|
||||
resource "docker_image" "emby" {
|
||||
name = data.docker_registry_image.emby.name
|
||||
pull_triggers = [data.docker_registry_image.emby.sha256_digest]
|
||||
name = "${data.docker_registry_image.emby.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.emby.sha256_digest}"]
|
||||
}
|
||||
|
||||
data "docker_registry_image" "emby" {
|
||||
name = "emby/embyserver:latest"
|
||||
}
|
||||
|
||||
|
|
|
@ -2,23 +2,21 @@ module "jackett" {
|
|||
name = "jackett"
|
||||
source = "../modules/container"
|
||||
image = "linuxserver/jackett:latest"
|
||||
# TODO FIXME
|
||||
# networks = [data.docker_network.bridge.id]
|
||||
|
||||
web = {
|
||||
networks = "${list(data.docker_network.bridge.id)}"
|
||||
|
||||
web {
|
||||
expose = true
|
||||
port = 9117
|
||||
host = "jackett.${var.domain}"
|
||||
}
|
||||
|
||||
volumes = [
|
||||
{
|
||||
volumes = [{
|
||||
host_path = "/mnt/xwing/config/jackett"
|
||||
container_path = "/config"
|
||||
},
|
||||
]
|
||||
}]
|
||||
|
||||
resource = {
|
||||
resource {
|
||||
memory = "256"
|
||||
memory_swap = "512"
|
||||
}
|
||||
|
@ -29,4 +27,3 @@ module "jackett" {
|
|||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
resource "docker_container" "jellyfin" {
|
||||
name = "jellyfin"
|
||||
image = "${docker_image.jellyfin.latest}"
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/config/jellyfin"
|
||||
container_path = "/config"
|
||||
}
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/media"
|
||||
container_path = "/media"
|
||||
}
|
||||
|
||||
labels = "${merge(
|
||||
var.traefik-labels,
|
||||
map(
|
||||
"traefik.frontend.rule", "Host:media.in.${var.domain},media.${var.domain}",
|
||||
"traefik.frontend.passHostHeader", "true",
|
||||
"traefik.port", 8096,
|
||||
))}"
|
||||
|
||||
networks = ["${docker_network.media.id}", "${var.traefik-network-id}"]
|
||||
|
||||
memory = 2048
|
||||
restart = "unless-stopped"
|
||||
destroy_grace_seconds = 10
|
||||
must_run = true
|
||||
|
||||
# Running as lounge:tatooine
|
||||
env = [
|
||||
"APP_USER=lounge",
|
||||
"APP_UID=1004",
|
||||
"APP_GID=1003",
|
||||
"APP_CONFIG=/mnt/xwing/config",
|
||||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
}
|
||||
|
||||
resource "docker_image" "jellyfin" {
|
||||
name = "${data.docker_registry_image.jellyfin.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.jellyfin.sha256_digest}"]
|
||||
}
|
||||
|
||||
data "docker_registry_image" "jellyfin" {
|
||||
name = "jellyfin/jellyfin:latest"
|
||||
}
|
|
@ -3,29 +3,19 @@ data "docker_registry_image" "lidarr" {
|
|||
}
|
||||
|
||||
resource "docker_image" "lidarr" {
|
||||
name = data.docker_registry_image.lidarr.name
|
||||
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}"
|
||||
})
|
||||
name = "${data.docker_registry_image.lidarr.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.lidarr.sha256_digest}"]
|
||||
}
|
||||
|
||||
resource "docker_container" "lidarr" {
|
||||
name = "lidarr"
|
||||
image = docker_image.lidarr.image_id
|
||||
|
||||
dynamic "labels" {
|
||||
for_each = local.lidarr_labels
|
||||
content {
|
||||
label = labels.key
|
||||
value = labels.value
|
||||
}
|
||||
}
|
||||
image = "${docker_image.lidarr.latest}"
|
||||
|
||||
labels = "${merge(
|
||||
var.traefik-labels, map(
|
||||
"traefik.port", 8686,
|
||||
"traefik.frontend.rule","Host:lidarr.${var.domain}"
|
||||
))}"
|
||||
|
||||
memory = 512
|
||||
restart = "unless-stopped"
|
||||
|
@ -53,6 +43,5 @@ resource "docker_container" "lidarr" {
|
|||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
|
||||
networks = [docker_network.media.id, var.traefik-network-id]
|
||||
networks = ["${docker_network.media.id}", "${var.traefik-network-id}"]
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
module "mylar" {
|
||||
name = "mylar"
|
||||
source = "../modules/container"
|
||||
image = "linuxserver/mylar:latest"
|
||||
|
||||
web {
|
||||
expose = true
|
||||
port = 8090
|
||||
host = "mylar.${var.domain}"
|
||||
auth = true
|
||||
}
|
||||
|
||||
volumes = [
|
||||
{
|
||||
host_path = "/mnt/xwing/media/EBooks/Comics"
|
||||
container_path = "/comics"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/config/mylar"
|
||||
container_path = "/config"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/media/DL"
|
||||
container_path = "/downloads"
|
||||
},
|
||||
]
|
||||
|
||||
env = [
|
||||
"PUID=1004",
|
||||
"PGID=1003",
|
||||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
|
||||
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
module "navidrome" {
|
||||
source = "../modules/container"
|
||||
image = "deluan/navidrome"
|
||||
name = "navidrome"
|
||||
|
||||
user = 1004
|
||||
|
||||
resource = {
|
||||
memory = "1024"
|
||||
memory_swap = "1024"
|
||||
}
|
||||
|
||||
web = {
|
||||
port = 4533
|
||||
host = "music.bb8.fun"
|
||||
expose = true
|
||||
}
|
||||
|
||||
env = [
|
||||
"ND_SCANINTERVAL=6h",
|
||||
"ND_LOGLEVEL=info",
|
||||
"ND_SESSIONTIMEOUT=300h",
|
||||
"ND_BASEURL=",
|
||||
"ND_AUTOIMPORTPLAYLISTS=false",
|
||||
"ND_LASTFM_APIKEY=${var.lastfm_api_key}",
|
||||
"ND_LASTFM_SECRET=${var.lastfm_secret}",
|
||||
"ND_SPOTIFY_ID=${var.spotify_id}",
|
||||
"ND_SPOTIFY_SECRET=${var.spotify_secret}",
|
||||
]
|
||||
|
||||
# TODO FIXME
|
||||
# networks = [docker_network.media.id, data.docker_network.bridge.id]
|
||||
|
||||
# Keep cache and data config so we can do easier backups
|
||||
volumes = [
|
||||
{
|
||||
host_path = "/mnt/zwing/config/navidrome"
|
||||
container_path = "/data"
|
||||
},{
|
||||
host_path = "/mnt/zwing/cache/navidrome"
|
||||
container_path = "/data/cache"
|
||||
},
|
||||
{
|
||||
host_path = "/mnt/xwing/media/Music"
|
||||
container_path = "/music"
|
||||
read_only = true
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ resource "docker_network" "media" {
|
|||
driver = "bridge"
|
||||
|
||||
ipam_config {
|
||||
subnet = "172.18.0.0/24"
|
||||
subnet = "172.18.0.0/16"
|
||||
gateway = "172.18.0.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
output "names-transmission" {
|
||||
value = docker_container.transmission.name
|
||||
value = "${docker_container.transmission.name}"
|
||||
}
|
||||
|
||||
output "names-emby" {
|
||||
value = docker_container.emby.name
|
||||
value = "${docker_container.emby.name}"
|
||||
}
|
||||
|
||||
|
|
|
@ -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,29 +3,24 @@ module "radarr" {
|
|||
source = "../modules/container"
|
||||
image = "linuxserver/radarr:latest"
|
||||
|
||||
networks = [docker_network.media.id, data.docker_network.bridge.id]
|
||||
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
|
||||
|
||||
web = {
|
||||
web {
|
||||
expose = true
|
||||
port = 7878
|
||||
host = "radarr.${var.domain}"
|
||||
}
|
||||
|
||||
resource = {
|
||||
resource {
|
||||
memory = 512
|
||||
memory_swap = 1024
|
||||
}
|
||||
|
||||
volumes = [
|
||||
{
|
||||
host_path = "/mnt/zwing/config/radarr"
|
||||
host_path = "/mnt/xwing/config/radarr"
|
||||
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"
|
||||
container_path = "/downloads"
|
||||
|
@ -42,4 +37,3 @@ module "radarr" {
|
|||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
module "requestrr" {
|
||||
name = "requestrr"
|
||||
source = "../modules/container"
|
||||
image = "darkalfx/requestrr:latest"
|
||||
|
||||
web = {
|
||||
expose = true
|
||||
port = 4545
|
||||
host = "requestrr.${var.domain}"
|
||||
}
|
||||
|
||||
resource = {
|
||||
memory = 256
|
||||
memory_swap = 256
|
||||
}
|
||||
|
||||
volumes = [
|
||||
{
|
||||
host_path = "/mnt/xwing/config/requestrr"
|
||||
container_path = "/root/config"
|
||||
},
|
||||
]
|
||||
|
||||
networks = [docker_network.media.id, data.docker_network.bridge.id]
|
||||
}
|
||||
|
|
@ -3,27 +3,22 @@ module "sonarr-container" {
|
|||
source = "../modules/container"
|
||||
image = "linuxserver/sonarr:latest"
|
||||
|
||||
web = {
|
||||
web {
|
||||
expose = true
|
||||
port = 8989
|
||||
host = "sonarr.${var.domain}"
|
||||
}
|
||||
|
||||
resource = {
|
||||
resource {
|
||||
memory = 512
|
||||
memory_swap = 1024
|
||||
}
|
||||
|
||||
volumes = [
|
||||
{
|
||||
host_path = "/mnt/zwing/config/sonarr"
|
||||
host_path = "/mnt/xwing/config/sonarr"
|
||||
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"
|
||||
container_path = "/downloads"
|
||||
|
@ -40,6 +35,5 @@ module "sonarr-container" {
|
|||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
|
||||
networks = [docker_network.media.id, data.docker_network.bridge.id]
|
||||
networks = "${list(docker_network.media.id, data.docker_network.bridge.id)}"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,18 @@
|
|||
locals {
|
||||
transmission_labels = merge(var.traefik-labels, {
|
||||
"traefik.frontend.auth.basic" = var.basic_auth
|
||||
"traefik.port" = 9091
|
||||
})
|
||||
}
|
||||
|
||||
resource "docker_container" "transmission" {
|
||||
name = "transmission"
|
||||
image = docker_image.transmission.image_id
|
||||
image = "${docker_image.transmission.latest}"
|
||||
|
||||
dynamic "labels" {
|
||||
for_each = local.transmission_labels
|
||||
content {
|
||||
label = labels.key
|
||||
value = labels.value
|
||||
}
|
||||
}
|
||||
labels = "${merge(
|
||||
var.traefik-labels,
|
||||
map(
|
||||
"traefik.frontend.auth.basic", "${var.basic_auth}",
|
||||
"traefik.port", 9091,
|
||||
))}"
|
||||
|
||||
ports {
|
||||
internal = 51413
|
||||
external = 51413
|
||||
ip = var.ips["eth0"]
|
||||
ip = "${var.ips["eth0"]}"
|
||||
protocol = "udp"
|
||||
}
|
||||
|
||||
|
@ -34,18 +26,13 @@ resource "docker_container" "transmission" {
|
|||
container_path = "/downloads"
|
||||
}
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/media/Music/Audiobooks"
|
||||
container_path = "/audiobooks"
|
||||
}
|
||||
|
||||
volumes {
|
||||
host_path = "/mnt/xwing/data/watch/transmission"
|
||||
container_path = "/watch"
|
||||
}
|
||||
|
||||
upload {
|
||||
content = file("${path.module}/conf/transmission.json")
|
||||
content = "${file("${path.module}/conf/transmission.json")}"
|
||||
file = "/config/settings.json"
|
||||
}
|
||||
|
||||
|
@ -55,7 +42,7 @@ resource "docker_container" "transmission" {
|
|||
"TZ=Asia/Kolkata",
|
||||
]
|
||||
|
||||
networks = [docker_network.media.id, var.traefik-network-id]
|
||||
networks = ["${docker_network.media.id}", "${var.traefik-network-id}"]
|
||||
|
||||
memory = 1024
|
||||
restart = "unless-stopped"
|
||||
|
@ -64,11 +51,10 @@ resource "docker_container" "transmission" {
|
|||
}
|
||||
|
||||
resource "docker_image" "transmission" {
|
||||
name = data.docker_registry_image.transmission.name
|
||||
pull_triggers = [data.docker_registry_image.transmission.sha256_digest]
|
||||
name = "${data.docker_registry_image.transmission.name}"
|
||||
pull_triggers = ["${data.docker_registry_image.transmission.sha256_digest}"]
|
||||
}
|
||||
|
||||
data "docker_registry_image" "transmission" {
|
||||
name = "linuxserver/transmission:latest"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
variable "domain" {
|
||||
type = string
|
||||
type = "string"
|
||||
}
|
||||
|
||||
# variable "airsonic-smtp-password" {}
|
||||
|
||||
variable "traefik-labels" {
|
||||
type = map(string)
|
||||
type = "map"
|
||||
}
|
||||
|
||||
// TODO: Remove duplication
|
||||
|
@ -14,29 +14,7 @@ variable "basic_auth" {
|
|||
}
|
||||
|
||||
variable "ips" {
|
||||
type = map(string)
|
||||
}
|
||||
|
||||
variable "traefik-network-id" {
|
||||
}
|
||||
|
||||
variable "lastfm_api_key" {
|
||||
description = "Navidrome Configuration for lastfm_api_key"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "lastfm_secret" {
|
||||
description = "Navidrome Configuration for lastfm_secret"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "spotify_id" {
|
||||
description = "Navidrome Configuration for spotify_id"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "spotify_secret" {
|
||||
description = "Navidrome Configuration for spotify_secret"
|
||||
type = string
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "traefik-network-id" {}
|
||||
|
|
22
miniflux.tf
22
miniflux.tf
|
@ -1,30 +1,28 @@
|
|||
module "miniflux-container" {
|
||||
name = "miniflux"
|
||||
source = "./modules/container"
|
||||
image = "miniflux/miniflux:2.0.50"
|
||||
source = "modules/container"
|
||||
image = "miniflux/miniflux:2.0.17"
|
||||
|
||||
web = {
|
||||
web {
|
||||
expose = true
|
||||
port = 8080
|
||||
host = "rss.captnemo.in"
|
||||
}
|
||||
|
||||
networks = ["bridge", "postgres"]
|
||||
networks = "${list(
|
||||
data.docker_network.bridge.id,
|
||||
module.docker.traefik-network-id,
|
||||
module.db.postgres-network-id
|
||||
)}"
|
||||
|
||||
env = [
|
||||
"DATABASE_URL=postgres://miniflux:${data.pass_password.miniflux-db-password.password}@postgres/miniflux?sslmode=disable",
|
||||
"RUN_MIGRATIONS=1",
|
||||
]
|
||||
|
||||
resource = {
|
||||
memory = 512
|
||||
memory_swap = 1024
|
||||
}
|
||||
}
|
||||
|
||||
module "miniflux-db" {
|
||||
source = "./modules/postgres"
|
||||
source = "modules/postgres"
|
||||
name = "miniflux"
|
||||
password = data.pass_password.miniflux-db-password.password
|
||||
password = "${data.pass_password.miniflux-db-password.password}"
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue