Compare commits

..

1 Commits

Author SHA1 Message Date
Nemo 7a6ad3cb44 Test branch for showcasing a docker-bug 2018-03-19 00:15:36 +05:30
257 changed files with 1950 additions and 3964 deletions

5
.gitignore vendored
View File

@ -3,11 +3,6 @@
.terraform
*.tfstate
*.tfstate.backup
*.terraform.lock.hcl
*.out
*.backup
secrets
k8s/
k8s2/
docker/conf/wiki.yml
plan

View File

@ -1 +0,0 @@
1.3.6

View File

@ -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
````

147
README.md
View File

@ -2,106 +2,109 @@
![Nebula header image](https://cdn.spacetelescope.org/archives/images/thumb700x/heic0707a.jpg)
> Where stars are born.
>Where stars are born.
Manages the local infrastructure of my home server. I'm also doing blog posts around the same:
1. [Part 1, Hardware](https://captnemo.in/blog/2017/09/17/home-server-build/)
2. [Part 2, Terraform/Docker](https://captnemo.in/blog/2017/11/09/home-server-update/)
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/)
1. [Part 1, Hardware](https://captnemo.in/blog/2017/09/17/home-server-build/)
2. [Part 2, Terraform/Docker](https://captnemo.in/blog/2017/11/09/home-server-update/)
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/)
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>
The canonical URL for this repo is https://git.captnemo.in/nemo/nebula/. A mirror is maintained on GitHub.
# modules
1. docker: to actually run the services. Catch-all for miscellaneous containers
2. cloudflare: to manage the DNS.
3. mysql: to create mysql users and databases.
4. media: Media related containers (Jackett, Lidarr, Radarr, Sonarr)
5. Monitoring: Monitoring related resources (Cadvisor, Grafana, NodeExporter, Prometheus, Transmission-Exporter)
6. Gitea: Just git.captnemo.in
7. miniflux: RSS Web reader
8. Radicale: CardDav/CalDav webserver
1. docker: to actually run the services. Catch-all for miscellaneous containers
2. cloudflare: to manage the DNS.
3. mysql: to create mysql users and databases.
4. media: Media related containers (Jackett, Lidarr, Radarr, Sonarr, Daapd)
5. Monitoring: Monitoring related resources (Cadvisor, Grafana, NodeExporter, Prometheus, Transmission-Exporter)
6. Gitea: Just git.captnemo.in
7. tt-rss: Tiny-Tiny RSS Web reader
8. Radicale: CardDav/CalDav webserver
Self-learning project for terraform/docker.
# Planned
1. ~Setup DigitalOcean~
2. Add DO infrastructure via ansible
3. ~Add traefik for proper proxying~
4. Maybe add docker swarm (or k8s?) across both the servers. Might setup the k8s API on the Raspberry Pi.
1. ~Setup DigitalOcean~
2. Add DO infrastructure via ansible
3. ~Add traefik for proper proxying~
4. Maybe add docker swarm (or k8s?) across both the servers. Might setup the k8s API on the Raspberry Pi.
# Service List
Currently running the following (all links are to the `store.docker.com` links for the docker images that I'm using:
| image | tag | module/link |
| -------------------------------- | ---------- | ---------------------------------------------------- |
| captn3m0/opml-gen | latest | https://opml.bb8.fun |
| 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 |
| gitea/gitea | 1.5.0-rc1 | services |
| google/cadvisor | latest | monitoring |
| grafana/grafana | latest | monitoring |
| jankysolutions/requestbin | latest | tools |
| linuxserver/airsonic | latest | media |
| linuxserver/jackett | latest | media |
| linuxserver/lidarr | latest | media |
| linuxserver/lychee | latest | media |
| linuxserver/radarr | latest | media |
| linuxserver/sonarr | latest | media |
| linuxserver/transmission | latest | media |
| linuxserver/ubooquity | latest | media |
| miniflux/miniflux | 2.0.9 | tools |
| postgres | 10-alpine | database |
| prom/node-exporter | v0.15.2 | monitoring |
| prom/prometheus | latest | monitoring |
| requarks/wiki | latest | services |
| serjs/go-socks5-proxy | latest | tools |
| tocttou/gotviz | latest | na |
| tomsquest/docker-radicale | latest | services |
| traefik | 1.6-alpine | plumbing |
## Databases
## Docker Notes
- [MariaDB](https://store.docker.com/images/mariadb) for a simple database backend
- [MongoRocks](https://store.docker.com/community/images/jadsonlourenco/mongo-rocks) as a mongoDB server. Uses RocksDB as the backend
- Lots of the above images are from the excellent [LinuxServer.io](https://www.linuxserver.io), and they're doing great work :+1:
- Most images are running the latest beta (if available) or stable versions.
- Traefik is running with wildcard certificates.
## Media
- [Emby](https://store.docker.com/community/images/emby/embyserver) Media Server
- ~[CouchPotato](https://store.docker.com/community/images/linuxserver/couchpotato), auto-download movies~
- [Radarr](https://store.docker.com/community/images/linuxserver/radarr), auto-download movies
- [Sonarr](https://store.docker.com/community/images/linuxserver/sonarr), auto-download TV Shows
- [Transmission](https://store.docker.com/community/images/linuxserver/transmission), to download torrents
- [AirSonic](https://store.docker.com/community/images/airsonic/airsonic), for a music server
- [Ubooquity](https://store.docker.com/community/images/linuxserver/ubooquity), EBooks server with OPDS support
- [Lychee](https://store.docker.com/community/images/linuxserver/lychee), as a simple image-sharing/hosting service
## Plumbing
- [Traefik](https://store.docker.com/images/traefik) as a reverse-proxy server, and TLS termination
- [CAdvisor](https://store.docker.com/community/images/google/cadvisor), for basic monitoring
## Misc
- [Wiki.JS](https://store.docker.com/community/images/requarks/wiki) as a simple home-wiki
- [Radicale](https://store.docker.com/community/images/tomsquest/docker-radicale), for a CalDav/Carddav server
- [Gitea](https://store.docker.com/community/images/gitea/gitea), git server
Lots of the above images are from the excellent [LinuxServer.io](https://www.linuxserver.io), and they're doing great work :+1:
## Security Headers Note
The following security headers are applied using traefik on all traefik frontend docker backends:
- HSTS
- Redirect HTTP->HTTPS
- contentTypeNosniff: true
- browserXSSFilter: true
- XFO: Allow-From home.bb8.fun
- referrerPolicy: no-referrer
- X-Powered-By: Allomancy
- X-Server: BlackBox
- X-Clacks-Overhead "GNU Terry Pratchett" (On some domains)
~~Currently waiting on traefik 1.5.0-rc2 to fix security specific headers issue (marked as TODO above).~~ (Now resolved with new traefik release)
## Upstream
I've been using this as a contributing opportunity and reporting/fixing issues upstream:
Issues I've faced/reported as a result of this project:
1. Airsonic HTTPS proxying is broken. Reported: https://github.com/airsonic/airsonic/issues/641. Turned out to be a known issue: https://github.com/airsonic/airsonic/issues/594. Now fixed.
2. Traefik docker backend security headers were broken with dashes. I [reported it here](https://github.com/containous/traefik/issues/2493), and fixed by https://github.com/containous/traefik/pull/2496 :white_check_mark:
3. Headphones dies repeatedly with no error logs. Yet-to-report. (Already reported, fails due to classical artists)
4. Terraform doesn't parse mariadb version numbers. Report: https://github.com/terraform-providers/terraform-provider-mysql/issues/6. Filed a [PR to fix](https://github.com/hashicorp/go-version/pull/34) and [to bump the go-version dependency](https://github.com/terraform-providers/terraform-provider-mysql/pull/27) :white_check_mark:
5. `elibsrv` didn't support ebook-convert, only mobigen. PR is at https://github.com/captn3m0/elibsrv/pull/1. Merged to `elibsrv` trunk, will be part of next release.
6. `ubooquity` docker container doesn't let you set admin password: https://github.com/linuxserver/docker-ubooquity/issues/17. (Couldn't reproduce, closed) :white_check_mark:
7. Traefik customresponseheaders can't contain colons on the docker backend: https://github.com/containous/traefik/issues/2517. Fixed with https://github.com/containous/traefik/pull/2509 :white_check_mark:
8. Traefik Security headers don't overwrite upstream headers: https://github.com/containous/traefik/issues/2618 :white_check_mark:
9. Transmission exporter broke with different data types while unmarshalling JSON in go. I filed a PR https://github.com/metalmatze/transmission-exporter/pull/2 :white_check_mark:
10. Radarr official docker container was [running a very old `mediainfo`](https://github.com/Radarr/Radarr/issues/2668#issuecomment-376310514). [Filed a fix to upgrade `mediainfo` on the official radarr image](https://github.com/linuxserver/docker-baseimage-mono/pull/3) :white_check_mark:
11. Patched the [speedtest-exporter](https://github.com/stefanwalther/speedtest-exporter/pull/7) to use Alpine and upgraded Node.JS for a smaller updated build.
12. Faced (4) above again because mariadb decided to add `:` in the version response. [Workaround was to force set `--version=10.3-mariadb`](https://git.captnemo.in/nemo/nebula/commit/5f47a08bb55eea2c708c41668657ac1efa84c72a)
13. Reported [2 critical security issues in Abstruse CI](https://github.com/bleenco/abstruse/issues/363). :white_check_mark:
14. Faced (13) above again with postgres, thankfully [someone already fixed version parsing](https://github.com/terraform-providers/terraform-provider-postgresql/pull/31) :white_check_mark:
15. RSS Bridge was missing an official Docker Image. [I Filed a PR](https://github.com/RSS-Bridge/rss-bridge/pull/720) :white_check_mark:
1. Airsonic HTTPS proxying is broken. Reported: https://github.com/airsonic/airsonic/issues/641. Turned out to be a known issue: https://github.com/airsonic/airsonic/issues/594.
2. Traefik docker backend security headers were broken with dashes. Reported at https://github.com/containous/traefik/issues/2493, and fixed by https://github.com/containous/traefik/pull/2496 :white_check_mark:
3. Headphones dies repeatedly with no error logs. Yet-to-report. (Already reported, fails due to classical artists)
4. Terraform doesn't parse mariadb version numbers. Report: https://github.com/terraform-providers/terraform-provider-mysql/issues/6. Got this fixed myself by filing a PR: https://github.com/hashicorp/go-version/pull/34. Another PR pending in the [provider](https://github.com/terraform-providers/terraform-provider-mysql/pull/27) to bump the go-version dependency. :white_check_mark:
5. `elibsrv` didn't support ebook-convert, only mobigen. PR is at https://github.com/captn3m0/elibsrv/pull/1. I've to get this merged upstream for the next release.
6. `ubooquity` docker container doesn't let you set admin password: https://github.com/linuxserver/docker-ubooquity/issues/17. (Couldn't reproduce, closed) :white_check_mark:
7. Traefik customresponseheaders can't contain colons on the docker backend: https://github.com/containous/traefik/issues/2517. Fixed with https://github.com/containous/traefik/pull/2509 :white_check_mark:
8. Traefik Security headers don't overwrite upstream headers: https://github.com/containous/traefik/issues/2618
9. Transmission exporter broke with different data types while unmarshalling JSON in go. I filed a PR https://github.com/metalmatze/transmission-exporter/pull/2
# Plumbing
Their is a lot of additional infrastructure that is _not-yet_ part of this repo. This includes:
1. The Digital Ocean droplet running DNSCrypt and simpleproxy to proxy over a openvpn connection to this box.
2. openbox, kodi configuration to run on boot along with the Steam Controller for the HTPC setup
3. Docker main configuration with half-baked CA setup
4. btrfs-backed subvolumes and snapshotting for most things in /mnt/xwing/ (in-progress)
5. User-creation on the main server. (I'm using a common user for media applications and specific users for other applications)
1. The Digital Ocean droplet running DNSCrypt and simpleproxy to proxy over a openvpn connection to this box.
2. openbox, kodi configuration to run on boot along with the Steam Controller for the HTPC setup
3. Docker main configuration with half-baked CA setup
4. btrfs-backed subvolumes and snapshotting for most things in /mnt/xwing/ (in-progress)
5. User-creation on the main server. (I'm using a common user for media applications and specific users for other applications)
# License

View File

@ -1,5 +0,0 @@
<?php
// Generates the Ubooquity preferences.json file
$template = "ubooquity.tpl.json";

View File

@ -4,18 +4,18 @@
*/
resource "cloudflare_record" "home" {
zone_id = var.zone_id
name = "in"
value = var.ips["eth0"]
type = "A"
domain = "${var.domain}"
name = "in"
value = "${var.ips["eth0"]}"
type = "A"
}
resource "cloudflare_record" "home-wildcard" {
zone_id = var.zone_id
name = "*.in"
value = cloudflare_record.home.hostname
type = "CNAME"
ttl = 3600
domain = "${var.domain}"
name = "*.in"
value = "${cloudflare_record.home.hostname}"
type = "CNAME"
ttl = 3600
}
/**
@ -23,42 +23,18 @@ resource "cloudflare_record" "home-wildcard" {
* *.bb8.fun -> bb8.fun
*/
resource "cloudflare_record" "internet" {
zone_id = var.zone_id
name = "@"
value = var.droplet_ip
type = "A"
domain = "${var.domain}"
name = "@"
value = "${var.ips["static"]}"
type = "A"
}
resource "cloudflare_record" "internet-wildcard" {
zone_id = var.zone_id
name = var.domain
value = cloudflare_record.internet.hostname
type = "CNAME"
ttl = 3600
}
resource "cloudflare_record" "dns" {
zone_id = var.zone_id
name = "dns"
value = var.ips["static"]
type = "A"
}
resource "cloudflare_record" "doh" {
zone_id = var.zone_id
name = "doh"
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
name = "_acme-challenge.${var.domain}"
type = "A"
value = "127.0.0.1"
ttl = "300"
domain = "${var.domain}"
name = "*.${var.domain}"
value = "${cloudflare_record.internet.hostname}"
type = "CNAME"
ttl = 3600
}
/**
@ -66,44 +42,18 @@ resource "cloudflare_record" "acme-no-cname-1" {
* *.vpn.bb8.fun
*/
resource "cloudflare_record" "vpn" {
zone_id = var.zone_id
name = "vpn"
value = var.ips["tun0"]
type = "A"
domain = "${var.domain}"
name = "vpn"
value = "${var.ips["tun0"]}"
type = "A"
}
resource "cloudflare_record" "vpn_wildcard" {
zone_id = var.zone_id
name = "*.vpn.${var.domain}"
value = cloudflare_record.vpn.hostname
type = "CNAME"
ttl = 3600
}
/**
* vpn.bb8.fun
* *.vpn.bb8.fun
*/
resource "cloudflare_record" "dovpn" {
zone_id = var.zone_id
name = "dovpn"
value = var.ips["dovpn"]
type = "A"
}
resource "cloudflare_record" "dovpn_wildcard" {
zone_id = var.zone_id
name = "*.dovpn.${var.domain}"
value = cloudflare_record.dovpn.hostname
type = "CNAME"
ttl = 3600
}
resource "cloudflare_record" "etcd" {
zone_id = var.zone_id
name = "etcd"
value = var.ips["dovpn"]
type = "A"
domain = "${var.domain}"
name = "*.vpn.${var.domain}"
value = "${cloudflare_record.vpn.hostname}"
type = "CNAME"
ttl = 3600
}
########################
@ -111,21 +61,21 @@ resource "cloudflare_record" "etcd" {
########################
resource "cloudflare_record" "mailgun-spf" {
zone_id = var.zone_id
name = "l"
value = "v=spf1 include:mailgun.org ~all"
type = "TXT"
domain = "${var.domain}"
name = "l"
value = "v=spf1 include:mailgun.org ~all"
type = "TXT"
}
resource "cloudflare_record" "mailgun-dkim" {
zone_id = var.zone_id
name = "k1._domainkey.l"
value = "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnbP+IQkuPkgmUhpqCKzIdDSZ0HazaMp+cdBH++LBed8oY8/jmV8BhxMp5JwyePzRTxneT8ASsRtcp7CQ3z4nMC7aFX0kH6Bnu2v+u2JWudxs8x0I02OrPbSaQ5QVQdbAaCUCEfCQ06LJsn8aqPNrRIOWEMnxln+ebFJ0wKGscFQIDAQAB"
type = "TXT"
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,17 +83,9 @@ 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"
priority = 20
}
resource "cloudflare_record" "k8s" {
zone_id = var.zone_id
name = "k8s"
value = "10.8.0.1"
type = "A"
ttl = 3600
}

View File

@ -1,7 +0,0 @@
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
}
}
}

View File

@ -1,10 +1,7 @@
variable "domain" {
type = string
type = "string"
}
variable "ips" {
type = map
type = "map"
}
variable "droplet_ip" {}
variable "zone_id" {}

11
data.tf
View File

@ -1,11 +0,0 @@
data "docker_network" "bridge" {
name = "bridge"
}
data "cloudflare_zones" "bb8" {
filter {
name = "bb8"
lookup_type = "exact"
match = "bb8.fun"
}
}

View File

@ -1,10 +0,0 @@
resource "docker_network" "postgres" {
name = "postgres"
driver = "bridge"
internal = true
ipam_config {
subnet = "172.20.0.8/27"
gateway = "172.20.0.9"
}
}

View File

@ -1,4 +0,0 @@
output "postgres-network-id" {
value = docker_network.postgres.name
}

View File

@ -1,58 +0,0 @@
resource "docker_container" "postgres" {
name = "postgres"
image = docker_image.postgres.image_id
command = [
"postgres",
"-c",
"max_connections=250",
"-c",
"shared_buffers=500MB",
]
volumes {
volume_name = docker_volume.pg_data.name
container_path = "/var/lib/postgresql/data"
read_only = false
}
// This is so that other host-only services can share this
ports {
internal = 5432
external = 5432
ip = var.ips["eth0"]
}
// This is a not-so-great idea
// TODO: Figure out a better way to make terraform SSH and then connect to localhost
ports {
internal = 5432
external = 5432
ip = var.ips["tun0"]
}
memory = 2048
memory_swap = 2048
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
env = [
"POSTGRES_PASSWORD=${var.postgres-root-password}",
]
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]
}
data "docker_registry_image" "postgres" {
name = "postgres:${var.postgres-version}"
}
data "docker_network" "bridge" {
name = "bridge"
}

View File

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

View File

@ -1,11 +0,0 @@
variable "postgres-version" {
description = "postgres version to use for fetching the docker image"
default = "14-alpine"
}
variable "ips" {
type = map(string)
}
variable "postgres-root-password" {
}

View File

@ -1,3 +0,0 @@
resource "docker_volume" "pg_data" {
name = "pg_data"
}

View File

@ -1,14 +1,12 @@
resource "digitalocean_droplet" "sydney" {
image = "??"
image = ""
name = "sydney.captnemo.in"
region = "blr1"
size = "s-1vcpu-2gb"
size = "1gb"
ipv6 = true
private_networking = true
resize_disk = true
volume_ids = ["eae03502-9279-11e8-ab31-0242ac11470b"]
tags = [
"bangalore",
"proxy",
@ -16,8 +14,3 @@ resource "digitalocean_droplet" "sydney" {
"vpn",
]
}
output "droplet_ipv4" {
value = digitalocean_droplet.sydney.ipv4_address
}

View File

@ -1,35 +1,38 @@
resource "digitalocean_firewall" "web" {
name = "web-inbound"
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"]
}
inbound_rule = [
{
protocol = "tcp"
port_range = "80"
source_addresses = ["0.0.0.0/0", "::/0"]
},
{
protocol = "tcp"
port_range = "443"
source_addresses = ["0.0.0.0/0", "::/0"]
},
]
}
resource "digitalocean_firewall" "ssh" {
name = "ssh-inbound"
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"]
}
inbound_rule = [
{
protocol = "tcp"
port_range = "22"
source_addresses = ["0.0.0.0/0", "::/0"]
},
{
protocol = "tcp"
port_range = "222"
source_addresses = ["0.0.0.0/0", "::/0"]
},
{
protocol = "tcp"
port_range = "24"
source_addresses = ["0.0.0.0/0", "::/0"]
},
]
}

View File

@ -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}"
}

View File

@ -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"
}
}
}

View File

@ -0,0 +1 @@
<EFBFBD>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
Åù<>9<EFBFBD><39> ¦{CNŠ¶J™”¸þsÝ%”´-Ïz£ªú©|·°cå-X°¤ÐóŽ<C3B3>²)<05>Žñ¼†äæ>¨E¹$À†qªRöF(<28>7É÷Z‰>V-Ú"öƒA$<24>â
Õü÷U!9ÚË룹ÓVüu
ü.9ü
ù¹6ÇÒï¼lÛT‡3J¨œPѨ¡vÃ\ Eàî:LQÐÆ™Æ<E284A2>êÑbݹ¢»»À“-kðŒ Tc½f³!‡$÷)J¨=—%Œ>ß±

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,3 @@
╞В^·╥chЭНoЕ}gL_н└В1~═"⌡вяжа╕Y ч3..Э/е ╥CШ4╪&ЦI┴╫√┴hб\·{Ы ОТ╧)ЯуrщC╚∙▐▐ТП(ё'╧~Jиm╫Gт╕ъ$."э═HН©m≤г~a╕~
7N≤фТ╘⌡шКoо╚ъ=EКc▓m^А└M╢сЕ╦┌>5║вH]иь⌠и≤{ФB{З3$N─┐╘sjB}Е'аЭ╨}щ╠─║╔]9ТX├m@Tlь┌PДёБся65╙IПD °≈▄Fh²Бх:@РE| k&e²ю341F╨┴0╟Ц≥hР╞6╝ ю╤8.▓ks~╪vfV┘┼dwМVzВ`а┘G┼╜z█дннъ%1▌h▌Тt "█≈Эщгю└rы√╕хVfOУЫ▒ёи╗Ф|W еИя╡Z ∙┌д⌡i▌Z6*О.Q ХSс|В~~w┘ъ/╕Ч©тЫ ╢≥╚-у▀vеlбИО├8[YHтI;≥╛3в W|╒l\═│ЕеО╦│dр█ьЁLЦXи hЕA!ё/╢&eKкс╞$yJIля(U╞(k[ 9?+h┴jЩвцИ╪|K@I=╨N╝╓н╦°с├©рЯ╨╫╡,▄╙т©┤М,ы╥ц╨╔╘FБ╕ЖюнгБЪшZt{РрИЫ┼аlХбХyl├xBR÷╔²<БQЬъЛ\`▄▀╢4ОйЬSч~T-P▓┼R2EUhЕ┤P
?*Г?mVq9²Ол■cП▀f_ВH╙lW│≈3p│Д╒╪pH╧.ЮыР)²ёа╥Ы еГР╕M└╔ъ╣г(╙°╩VГ▄╡╕KmмZмNyдВA│оoёlЫдЁЫZщ^u╒'*hд⌠яНD Ж╥[гm≥RЛAh·@/ьv╓д}Q√▄≥·еD╜} эг╬3еdи▓к╢и&M┼s<░√Q─▄Dф©=┬qqIл|@В│≥}г·kОёf╝я▓∙ъ╠зУ∙eч▐ 1╪÷-TИ,≈TДP■╚x:~Б╨жY▐m╩`DЦa'

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More