Compare commits

...

250 Commits

Author SHA1 Message Date
Nemo bd95967113 upgrade miniflux and gitea 2023-11-28 10:35:39 +05:30
Nemo 3f3f0fd55c re-enable GPU on Emby 2023-10-26 13:10:47 +05:30
Nemo 1b1bbcabbc drop act-exporter
I archived the repo, and no longer maintain it. ACT changed
their portal too much for this to keep working. Further,
the ACT app/portal now provide detailed stats on internet
usage, so this is not that helpful any more.
2023-10-26 13:09:32 +05:30
Nemo dfd0f94662 fix resource limits for grafana,cadvisor 2023-10-26 13:08:14 +05:30
Nemo 09c1094fc5 upgrade mastodon 2023-10-26 13:07:56 +05:30
Nemo 29368acfed upgrade miniflux 2023-10-26 13:07:45 +05:30
Nemo e18d8b11b1 Adds home-assistant
Trying to run https://hackaday.com/2021/07/24/esp8266-adds-wifi-logging-to-ikeas-air-quality-sensor/
2023-08-03 17:00:18 +05:30
Nemo 1feaf2e4f6 Migrate Emby to the SSD, and configure backups
Note that creating the directory alone doesn't do much.
You still have to configure backups and schedule them in the UI.
2023-07-27 13:36:00 +05:30
Nemo 2c52cd0cb7 gitea/miniflux upgrades 2023-07-26 09:40:02 +05:30
Nemo b83dd37365 [radicale] switch to ssd 2023-07-10 19:59:55 +05:30
Nemo af2be53caa [navidrome] Move to ssd 2023-07-10 17:12:03 +05:30
Nemo 9e8c5710f2 upgrade mastodon and use persistent redis 2023-07-10 17:01:50 +05:30
Nemo e4858d5d05 move sonarr/radarr to ssd 2023-07-10 17:01:30 +05:30
Nemo d59512c625 HSTS Preload on tatooine.club 2023-06-22 14:24:26 +05:30
Nemo 4a4504447f upgrade miniflux 2023-06-22 13:15:17 +05:30
Nemo 9b316b036b upgrade mastodon 2023-06-22 13:15:10 +05:30
Nemo f9b52957a8 fix resolver for dns/acme 2023-06-01 14:01:12 +05:30
Nemo 9b79cab3af gitea upgrade and fixes
fixes the svg favicons, but these are not nice
2023-06-01 14:01:06 +05:30
Nemo 5bd44d411f mastodon image conflict fixes 2023-06-01 14:00:08 +05:30
Nemo 406f4557fe fix+upgrade miniflux resource limits 2023-06-01 13:59:55 +05:30
Nemo 938ed017c9 Upgrade mastodon 2023-03-11 17:19:01 +05:30
Nemo 4f2a5b2cb4 Additional Mastodon secrets 2022-12-26 13:19:00 +05:30
Nemo ecaacaf3a5 [transmission] Upgrade configuration 2022-12-26 12:51:44 +05:30
Nemo af20a4efb9 [traefik] Upgrade 1.17 conf for tatooine.club 2022-12-26 12:51:30 +05:30
Nemo 18f32691f6 [media] Upgrade subnet size 2022-12-26 12:50:54 +05:30
Nemo eb1c40df6e [kaarana] Unused, but upgraded 2022-12-26 12:50:43 +05:30
Nemo 4b6b07c09a [db] Increase connections for mastodon 2022-12-26 12:50:31 +05:30
Nemo 48b93bf25d GPU and provider upgrades.
Applied to jupyter container
2022-12-26 12:49:52 +05:30
Nemo 8a894175a9 [miniflux] Upgrade to 2.0.39 2022-12-26 12:49:23 +05:30
Nemo 30fd75ae52 [main] Mastodon added 2022-12-26 12:49:13 +05:30
Nemo 9f6048a971 [gitea] Upgrades to 1.17 2022-12-26 12:48:59 +05:30
Nemo 442ec2d5d3 [traefik] New tatooine.club keys
Had to disable redirect
2022-12-26 12:48:34 +05:30
Nemo 9f04ebe4c4 [rss-bridge] Switch to upstream
Most of my changes are merged: captnemo.in/rss/
So I can switch to tracking upstream instead
2022-12-26 12:48:03 +05:30
Nemo 587b6258bb Mastodon: Initial Configuration
This is missing some secrets, will commit those later
2022-12-26 12:47:48 +05:30
Nemo da4fc888ef [WIP] Traefik v2 migration 2022-12-26 12:46:31 +05:30
Nemo 10ba57590b Switch from latest -> image_id
former is deprecated
2022-12-26 12:46:09 +05:30
Nemo 8a0ead5bb0 [postgres] Increase memory for mastodon 2022-12-26 12:44:55 +05:30
Nemo 36996a0ace Increase network size for pg to add mastodon containers 2022-12-26 12:44:03 +05:30
Nemo 24079f41a2 Upgrade Terraform version 2022-12-26 12:43:47 +05:30
Nemo 51dd19cdc8 add prowlarr 2022-02-02 19:06:13 +05:30
Nemo 1235775ed0 upgrade gitea to 1.16 2022-02-02 19:03:28 +05:30
Nemo ffa2517903 addded kavita then removed it 2022-01-08 22:19:47 +05:30
Nemo ba763d585c minor fixes and upgrades 2022-01-08 22:19:38 +05:30
Nemo f6b1954e8f no more firefox sync, Mozilla makes this too hard 2021-10-16 11:41:30 +05:30
Nemo 137eb3469f
Terraform Upgrade to 1.x (#3)
Co-authored-by: Hashfyre <joy.bhattacherjee@gmail.com>
2021-10-15 12:54:13 +00:00
Nemo 8d7875d174 Fix radicale 2021-04-14 12:30:35 +05:30
Nemo 9273447567 increase memory for radicale 2021-04-14 12:08:31 +05:30
Nemo eae805e596 Update gitea, improve config 2021-04-14 12:08:21 +05:30
Nemo c6ebee47d7 Replace gonic with navidrome 2021-02-16 19:58:53 +05:30
Nemo 1a0021fb31 update miniflux 2021-02-16 19:58:41 +05:30
Nemo 42a264c7bd Disable SSH, upgrade gitea 2021-02-02 18:31:56 +05:30
Nemo 09baca2819 remove unused code 2021-02-02 15:14:48 +05:30
Nemo d25573f4b0 upgrade miniflux 2021-02-02 15:14:37 +05:30
Nemo 6cb2ffa736 Security note about docker socket mount 2021-02-02 14:07:15 +05:30
Nemo d90a67539f Remove heimdall 2021-02-02 13:58:10 +05:30
Nemo a532831de9 remove abstruse 2021-02-02 13:52:51 +05:30
Nemo 2d2348f34f [ubooquity] Enable autoscan 2021-01-27 13:17:53 +05:30
Nemo 114bb27349 Adds requestrr 2021-01-27 13:01:44 +05:30
Nemo add21ccdac Adds klaxon 2021-01-27 12:58:32 +05:30
Nemo c3584a8f56 Removes unused code 2021-01-27 12:55:08 +05:30
Nemo 20cd656e04 Removes mongodb, upgrades wiki 2021-01-08 00:23:33 +05:30
Nemo 373793fcb5 Setup one for audiobooks 2020-10-11 18:29:56 +05:30
Nemo 4922bd098f got gonic working 2020-10-10 19:02:50 +05:30
Nemo 735279b0c1 Cleanup and comment unused stuff 2020-07-29 22:49:35 +05:30
Nemo 86db1b2da9 upgrades+gonic 2019-12-31 21:53:39 +05:30
Nemo 1a234f5025 only run webserver for elibsrv 2019-11-04 01:51:56 +05:30
Nemo f02ee532ad mount books as read-only 2019-11-04 01:40:18 +05:30
Nemo 557a0af80d Merge branch 'master' into kaarana-wordpress 2019-10-09 04:58:13 +05:30
Nemo 2b617967a3 upgrade elibsrv 2019-10-09 04:50:09 +05:30
Nemo cce99c0b6a WIP ingress configuration
- Traefik is advertising http/2 along with TLS
  it then forwards the unencrypted h2 to the php server
  which is then giving up.

(╯°□°)╯︵ ┻━┻
2019-09-21 07:55:55 +05:30
Nemo 42ab949caf Fix wordpress port 2019-09-21 06:02:16 +05:30
Nemo d4370f2b56 kaarana.org wordpress website 2019-09-21 04:59:39 +05:30
Nemo 0633f6113f The SSH and Web servers are on different IP addresses now 2019-09-14 18:32:09 +05:30
Nemo 4336814bac Fix audioserve 2019-09-14 17:32:17 +05:30
Nemo 975c48094f Upgrade redis 2019-08-12 00:27:44 +05:30
Nemo 8900b2d2be remove lychee and stringer 2019-08-12 00:21:47 +05:30
Nemo 2b2b68f722 General Updates 2019-08-11 21:40:29 +05:30
Nemo da53ac8f1a Increase memory for radicale 2019-06-28 23:52:44 +05:30
Nemo 125f4cecaf Adds stringer
- Doesn't work yet, have create an issue
2019-06-23 22:37:56 +05:30
Nemo 273b75841c Increase resources for rssbridge 2019-06-21 01:44:11 +05:30
Nemo c890430913 adds a subject prefix for gitea mails 2019-06-02 15:43:50 +05:30
Nemo 1617061f51 [gitea] New release forces oauth2 on everyone 2019-06-02 15:41:06 +05:30
Nemo 63facbde70 Remove custom dns support 2019-06-02 14:51:33 +05:30
Nemo c5677d0fa4 docker improvements got merged 2019-06-01 22:43:00 +05:30
Nemo 77afa90a64 Fix whitelist path 2019-05-28 17:08:50 +05:30
Nemo bd27db6aa6 Switch to official PHP base image 2019-05-28 16:05:16 +05:30
Nemo ae073752a1 Fix ACT Exporter 2019-05-19 12:52:02 +05:30
Nemo b862c78ec9 General Updates 2019-05-19 12:51:53 +05:30
Nemo c066e62ee0 Fix radicale 2019-05-16 16:07:01 +05:30
Nemo c152ec65df Adds elibsrv Docker Container 2019-05-12 09:01:46 +05:30
Nemo 4c55f5dd0f Updates gitea config for 1.8 2019-05-12 09:01:35 +05:30
Nemo d748e65a37 Block robots from scraping git.captnemo.in
- Too many requests
2019-04-27 16:33:52 +05:30
Nemo 3bc9e40b61 Get opml back 2019-04-27 16:24:48 +05:30
Nemo 1bc37d72a6 Force run stuff 2019-04-27 00:28:11 +05:30
Nemo 37bb59eda3 Run a jupyter notebook 2019-04-26 03:16:37 +05:30
Nemo 07d44ca39a Comment out unused kubernetes stuff 2019-04-26 03:16:25 +05:30
Nemo c9b9205496 Switch to stable release of nextcloud 2019-04-21 17:45:28 +05:30
Nemo 071a16dc94 Improve NextCloud Networking 2019-04-16 00:38:40 +05:30
Nemo d9ef272286 Fix Firefox Sync 2019-04-14 00:11:55 +05:30
Nemo 114487fc1e Fix pass provider issues 2019-04-13 03:01:36 +05:30
Nemo c2e029fb4f Adds audioserve 2019-04-02 02:55:26 +05:30
Nemo 0ce0753d5f turn off dnscrypt-proxy, client now runs on the Router 2019-03-31 17:09:43 +05:30
Nemo ff3b56231b fix rss-bridge 2019-03-26 12:48:43 +05:30
Nemo ace703fc1f Switch to pass-provider for secrets 2019-03-25 21:04:47 +05:30
Nemo d7a6d06ec2 switch to master for rss-bridge 2019-03-18 03:30:32 +05:30
Nemo 6362702c51 Fix Emby DNS to dnscrypt 2019-03-17 02:15:02 +05:30
Nemo 4fe34b183a Pihole and Dnscrypt Proxy Setup is done 2019-03-13 22:55:06 +05:30
Nemo 16a5a26123 Switch to aliases for container<>networking 2019-03-09 13:58:57 +05:30
Nemo 2b53a6a512 Add default bridge network 2019-03-09 13:54:01 +05:30
Nemo 6ec37264dc nextcloud and other minor changes 2019-03-09 13:22:54 +05:30
Nemo 995fb96611 Fixes Airsonic (mostly) 2019-02-20 00:52:09 +05:30
Nemo 435e166cd9 Adds jellyfin 🐟 2019-02-16 20:32:16 +05:30
Nemo ae985e01a7 Adds dnscrypt-proxy and pihole
pihole commented for now
2019-02-16 15:42:07 +05:30
Nemo e4b3620de5 Merge branch 'kubernetes' 2019-02-16 13:52:48 +05:30
Nemo 83eb97c8db Create etcd dns entry 2019-02-13 20:37:38 +05:30
Nemo 40b967edce Migrate to kayak 2019-02-10 23:14:21 +05:30
Nemo f85692da9e Switch to a remote state 2019-02-10 23:14:10 +05:30
Nemo 97300459fd General Updates 2019-02-03 18:39:10 +05:30
Nemo 80ce34d52f Bring up a sample pod 2019-02-02 23:21:49 +05:30
Nemo 86f2edc112 Get cluster up and running 2019-02-02 22:55:55 +05:30
Nemo 53f3c87600 some media updates 2019-01-29 00:50:00 +05:30
Nemo 23cf15b8a9 minor fixes 2019-01-28 02:01:46 +05:30
Nemo ff8efd3139 fix etcd, c-m, and node label/taints for kubelet 2019-01-27 20:07:52 +05:30
Nemo 6586244fa8 Adds etcd secrets to bootkube-start 2019-01-27 18:56:12 +05:30
Nemo 0956877ac7 asset copy fixes 2019-01-27 04:16:32 +05:30
Nemo a3dec142ad [k8s] Upload all assets using upload{} inside docker_container 2019-01-27 04:02:59 +05:30
Nemo 94f9a23b4f Remove unused variables 2019-01-27 02:49:55 +05:30
Nemo 5949a9448a [k8s] Use terraform-render-bootkube to bring up etcd
- Stop running render on the server
2019-01-27 02:49:55 +05:30
Nemo 6f6c4f974e [k8s] Run kubelet using --containerized (or maybe not) 2019-01-27 02:49:55 +05:30
Nemo 2a12c17948 Switch to official images 2019-01-27 02:49:55 +05:30
Nemo 6deddebe48 Resolve DNS issues by bypassing DNS for now 2019-01-27 02:49:55 +05:30
Nemo 524949c8e5 [k8s] Run etcd with bootkube generated certs 2019-01-27 02:49:55 +05:30
Nemo 7214355a89 [k8s] Adds kubelet, start stitching things together
Challenges:

1. etcd booting before bootkube meant I missed certs
2. etcd can run without certs, but managing docker network
   over static pod manifests might be tricky :fingers_crossed:
2019-01-27 02:49:55 +05:30
Nemo 97ef9179e4 [k8s] Make bootkube start depend on bootkube render 2019-01-27 02:49:55 +05:30
Nemo 789c9c5d3f [k8s] S01E03 Control Plane: bootkube-start 2019-01-27 02:49:55 +05:30
Nemo 86c0613d28 [k8s] S01E02 Control Plane: bootkube-render 2019-01-27 02:49:55 +05:30
Nemo 9b40bfd341 [k8s] S01E01 Control Plane: etcd
This brings up etcd using the terraform docker provider
to my Digital Ocean VPN Server. The listen address is set to the
VPN Address (10.8.0.1 = openvpn master server, also running on the
same server).

/mnt/disk is a Digital Ocean Volume attached to the instance.
2019-01-27 02:49:55 +05:30
Nemo 6eceb1d6c9 Fix memory_swap for radarr 2019-01-27 02:49:09 +05:30
Nemo 0792c36f64 Adds Firefox Sync Server 2019-01-26 18:06:18 +05:30
Nemo 4b5747abd3 Jump to 1.7 release 2019-01-25 02:08:00 +05:30
Nemo fa99d0de64 Switch to gitea master 2019-01-22 00:44:25 +05:30
Nemo 96545fe564 Upgrade miniflux and fix rss-bridge 2019-01-21 21:41:08 +05:30
Nemo 66a7e8cc46 Adds outline s3 module 2019-01-21 12:22:29 +05:30
Nemo 9aadf62b5d Try bringing up minio server 2019-01-20 04:20:43 +05:30
Nemo 54bcb8b8a9 Adds outline wiki 2019-01-20 03:46:53 +05:30
Nemo 93af050523 [docker] Dealing from the aftermath of docker provider release
- It stops adding the bridge network by default so it causes issues
2019-01-20 03:46:18 +05:30
Nemo d1d3506e7b Some minor updates for Docker provider upgrade 2019-01-18 17:15:22 +05:30
Nemo 1b61a07c55 Updates RSS Bridge 2019-01-18 00:51:36 +05:30
Nemo 245806ca8d gitea: bump to latest master to avoid a bug in 1.7rc 2019-01-14 15:31:11 +05:30
Nemo 18164d175e Disable LFS server because 1.7 breaks:
https://github.com/go-gitea/gitea/issues/5704
2019-01-12 15:16:50 +05:30
Nemo 87ce9743b3 Update gitea 2018-12-14 17:13:36 +05:30
Nemo 3b1a7a52e8 WIP: Get build working for now 2018-11-01 22:30:35 +05:30
Nemo 7d7ea22b31 Revert "lychee moved to container module"
This reverts commit 2fb18878ca.
2018-11-01 22:30:24 +05:30
Nemo c57b4b2c72 WIP: Image refactor
- docker_container cannot take upload as a parameter, leaving
  no choice but to use docker_container like a savage.
- This will take some backward refactors.
2018-10-13 20:55:20 +05:30
Nemo 809755e10d Migrate sonarr 2018-10-13 20:45:10 +05:30
Nemo 7a3f456feb Adds users 2018-10-13 20:43:25 +05:30
Nemo b1ddd5e562 Pin terraform 2018-10-13 20:08:17 +05:30
Nemo a7c9a3fe3c Upgrade gitea 2018-10-13 12:19:31 +05:30
Nemo 167e58f8de Attempt at modularizing airsonic 2018-09-16 12:23:11 +05:30
Nemo 2fb18878ca lychee moved to container module 2018-09-15 17:43:44 +05:30
Nemo aff21bf142 Fix jackett resources 2018-09-12 21:47:14 +05:30
Nemo 47a34095c6 Adds support for docker_network data source 2018-08-24 01:06:27 +05:30
Nemo 6646320d74 Adds ZNC 2018-08-23 12:02:32 +05:30
Nemo 840ce49e98 radicale: Migrate to container module 2018-08-21 08:58:10 +05:30
Nemo 2f08ef00a4 opml: Migrate to container module 2018-08-21 08:54:06 +05:30
Nemo ebe3ecbd9e rss-bridge: Migrate to container module 2018-08-21 08:46:25 +05:30
Nemo 9a5bf0a8b9 Migrate radarr to volumes 2018-08-21 08:39:00 +05:30
Nemo cbd36ca1e7 Adds support for single volumes 2018-08-21 08:30:17 +05:30
Nemo ef26f51613 Temp fix since networks aren't editable 2018-08-21 08:22:12 +05:30
Nemo e8dcd00e87 Minor fixes in container zipmapping 2018-08-07 02:55:46 +05:30
Nemo 6ef8783ba3 Really complicated terraform labelling 2018-08-07 02:12:55 +05:30
Nemo dea37a5319 Cleaner module for web configuration 2018-07-31 14:07:08 +05:30
Nemo 30853ee5aa Refactor traefik expose labels via variables
- no need to pass explicit traefik labels now
2018-07-30 12:12:58 +05:30
Nemo 1c75fe486b Moves around monicahq to new format 2018-07-28 20:26:29 +05:30
Nemo 8356ebd672 Create a new postgres module 2018-07-28 20:19:20 +05:30
Nemo 3322870a53 Creates a generic docker-container module 2018-07-28 20:03:43 +05:30
Nemo 1f545f3117 Switch to official docker image now that PR is merged 2018-07-28 10:33:48 +05:30
Nemo 40efbf6504 switches to jmalloc/echo-server for websocket support 2018-07-27 14:27:13 +05:30
Nemo 5eecce56a3 Drops tt-rss entirely 2018-07-26 01:25:11 +05:30
Nemo aa7c9047e9 Migrates monicahq to postgres 2018-07-21 13:01:20 +05:30
Nemo 97ff4a28a5 monicaHQ 2018-07-21 11:43:32 +05:30
Nemo 3ab14e79e5 Upgrades and kill mysql everywhere 2018-07-18 18:17:57 +05:30
Nemo 1353fd2c61 Switch prometheus port 2018-07-09 01:11:18 +05:30
Nemo 7e76f319a7 Starting to drop mariadb 2018-07-08 18:31:38 +05:30
Nemo 25d5a86d22 Gitea, miniflux upgrades
- Use VPN for postgres (doesn't work yet)
2018-07-04 20:05:43 +05:30
Nemo 53bfd99ad5 Adds miniflux, improves tt-rss 2018-07-01 04:17:59 +05:30
Nemo c44c8f0249 Adds postgres server and switches ttrss 2018-06-27 10:12:28 +05:30
Nemo cd33034826 Adds more RSS bridges 2018-06-27 10:12:12 +05:30
Nemo 757c52622a Adds pranav 2018-06-20 21:30:16 +05:30
Nemo 393a956fbf Disable git connectivity for wiki 2018-06-20 21:20:06 +05:30
Nemo 0dd428e4dc Tag ubooquity with the correct network for traefik 2018-06-20 21:03:23 +05:30
Nemo 453e976d85 Switches to a single traefik network
- See https://github.com/containous/traefik/issues/3429
- traefik labels are added everywhere now
2018-06-20 21:01:03 +05:30
Nemo 259aa69f8f Adds RSS-Bridge 2018-06-18 22:14:44 +05:30
Nemo 04281c5702 Changes home Domain 2018-06-18 20:32:12 +05:30
Nemo 2198faf77b gitea upgrade 2018-06-13 08:21:48 +05:30
Nemo 1487d1e129 Switch airsonic back to SQLite 2018-06-13 08:21:31 +05:30
Nemo b4447c7b8d Attach traefik to monitoring network 2018-06-04 21:54:05 +05:30
Nemo 022f8f7ce6 Improve scrape intervals 2018-06-04 21:20:47 +05:30
Nemo 3f9d4b6e9d Fix cadvisor 2018-06-04 20:15:05 +05:30
Nemo c7e2cc043f Deprecate links in monitoring module 2018-06-04 19:40:58 +05:30
Nemo d91ae4d87d Sets up ACT exporter 2018-06-04 15:30:17 +05:30
Nemo 21df4ceea6 Create and use a single traefik network everywhere 2018-06-04 13:39:55 +05:30
Nemo fb6688a3b4 Removes tinyproxy 2018-06-04 13:39:44 +05:30
Nemo 22245839ce Tinyproxy 2018-06-03 01:20:15 +05:30
Nemo ee54248ae0 Re-enable headerdebug 2018-06-03 00:32:31 +05:30
Nemo 76343d991d ACL is inbound, not outbound 2018-06-02 19:56:56 +05:30
Nemo b9965f2092 Changes for OPML-gen deployment 2018-06-01 02:25:49 +05:30
Nemo c3c5c7d0bc Move gitea.redis to its own network 2018-05-29 19:53:30 +05:30
Nemo bde455f0c3 Drop more links 2018-05-29 19:43:25 +05:30
Nemo d9a6c5fdf1 More work on networks instead of links 2018-05-29 19:36:55 +05:30
Nemo 1a714d87b2 re-arch into media directory 2018-05-29 18:56:00 +05:30
Nemo 8efb575290 Upgrades and stuff 2018-05-29 18:06:21 +05:30
Nemo 66ae57a3c5 Adds got visualizations
- https://twitter.com/tocttou/status/994942857214603265
- https://ashishchaudhary.in/game-of-thrones-visualization
2018-05-11 19:45:26 +05:30
Nemo 4c8486f6b9 switch to 10.2 series 2018-05-10 03:22:40 +05:30
Nemo 39d8d5f966 Remove mylar 2018-05-10 02:48:08 +05:30
Nemo 3a111b6c32 Switch to stable mariadb 2018-05-10 02:47:10 +05:30
Nemo abe774561e Adds accounts 2018-05-10 02:00:53 +05:30
Nemo 92083c7e8a adds people 2018-05-06 18:33:55 +05:30
Nemo b52875d3fb Adds note about requestbin 2018-05-06 03:25:41 +05:30
Nemo 0c7a43b646 Adds requestbin 2018-05-06 03:16:25 +05:30
Nemo 99beeb57e3 README update 2018-05-06 02:48:23 +05:30
Nemo 161f1991f6 force bump gitea 2018-05-06 02:41:10 +05:30
Nemo ec5ee3debc Use variable for mariadb version 2018-05-06 01:45:12 +05:30
Nemo 5f47a08bb5 Force the mysql version reported
- This is a workaround for https://github.com/terraform-providers/terraform-provider-mysql/issues/6#issuecomment-386830792
- MariaDB version responses are terrible 😠
2018-05-06 01:33:19 +05:30
Nemo 47e27ee658 fixes harman's access 2018-05-01 23:38:06 +05:30
Nemo 05c0a9e6e5 delete empty file 2018-04-23 11:09:01 +05:30
Nemo 8fe2d16fb7 standardize quotes on resource type 2018-04-22 18:09:44 +05:30
Nemo 636f3c534e lidarr on its own domain 2018-04-22 15:52:07 +05:30
Nemo 47073f4f7b Adds a new domain and KIB 2018-04-22 15:27:37 +05:30
Nemo a74efc6fba Adds gazee 2018-04-19 23:37:00 +05:30
Nemo b05bd3bd8b cleanup, downgrade traefik 2018-04-19 20:40:52 +05:30
Nemo 452c7d5b79 new user 2018-04-19 01:45:19 +05:30
Nemo c1dc9c86c7 Fix abstruse single image
- By default terraform pull all images otherwise!
2018-04-17 23:10:57 +05:30
Nemo 19dc775c5c Adds abstruse CI 2018-04-17 00:45:43 +05:30
Nemo bfe493c794 Removes daapd 2018-04-14 15:11:28 +05:30
Nemo 67620b75c1 Adds table of services 2018-04-14 15:09:54 +05:30
Nemo aa70016612 Adds note about speedtest fixes 2018-04-14 14:58:44 +05:30
Nemo 479faf6863 Switch to Percona official image for mongo rocks 2018-04-14 14:54:15 +05:30
Nemo 9b1c4d9055 Switch to speedtest:alpine
- Forked: https://github.com/stefanwalther/speedtest-exporter/pull/7
2018-04-14 14:53:58 +05:30
Nemo fd1c7f1dcc Keep gitea-redis always up 2018-04-14 13:04:14 +05:30
Nemo 1be61eadae Adds people to immutable config 2018-04-09 01:53:23 +05:30
Nemo 36c04c5ad3 Server ubooquity over multiple domains 2018-04-09 01:53:23 +05:30
Nemo ac8aa32ef3 Revert back to sqlite 2018-04-09 01:24:44 +05:30
Nemo 1f515b36f0 Revert back to sqlite 2018-04-07 17:39:23 +05:30
Nemo 5cbc438ff6 Gitea configuration update.
- Enables redis
- LFS JWT secret is now rotated
- Mail config is proper
2018-04-07 13:35:20 +05:30
Nemo 3fef15503e Expose prometheus over VPN 2018-04-05 14:46:40 +05:30
Nemo 3dae8f3a27 README update 2018-03-31 00:24:03 +05:30
Nemo a08132ca8c terraform file uploads can't be executed
- Uses a custom entrypoint instead
2018-03-30 23:48:26 +05:30
Nemo 57d175d794 Attempt at migrating to a second entrypoint 2018-03-30 10:29:26 +05:30
Nemo 8e90029a84 wildcard certs are here!!! 2018-03-28 15:45:44 +05:30
156 changed files with 3966 additions and 1921 deletions

5
.gitignore vendored
View File

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

1
.terraform-version Normal file
View File

@ -0,0 +1 @@
1.3.6

18
HACKING.md Normal file
View File

@ -0,0 +1,18 @@
# 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,109 +2,106 @@
![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/)
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/)
The canonical URL for this repo is https://git.captnemo.in/nemo/nebula/. A mirror is maintained on GitHub.
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>
# 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, 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
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
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:
## Databases
| 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 |
- [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
## Docker Notes
## 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)
- 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.
## Upstream
Issues I've faced/reported as a result of this project:
I've been using this as a contributing opportunity and reporting/fixing issues upstream:
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
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:
# 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

5
_scripts/ubooquity.php Normal file
View File

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

View File

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

7
cloudflare/providers.tf Normal file
View File

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

View File

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

11
data.tf Normal file
View File

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

10
db/network.tf Normal file
View File

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

4
db/outputs.tf Normal file
View File

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

58
db/postgres.tf Normal file
View File

@ -0,0 +1,58 @@
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"
}

10
db/providers.tf Normal file
View File

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

11
db/variables.tf Normal file
View File

@ -0,0 +1,11 @@
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" {
}

3
db/volumes.tf Normal file
View File

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

View File

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

View File

@ -1,38 +1,35 @@
resource "digitalocean_firewall" "web" {
name = "web-inbound"
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"]
},
]
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 = [
{
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"]
},
]
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"]
}
}

View File

@ -1,4 +1,5 @@
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
}

19
digitalocean/providers.tf Normal file
View File

@ -0,0 +1,19 @@
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

@ -1 +0,0 @@

View File

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

View File

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

View File

@ -1,15 +1,11 @@
defaultEntryPoints = ["http", "https"]
# Have to enable this because of heimdall
InsecureSkipVerify = true
sendAnonymousUsage = true
checkNewVersion = false
[traefikLog]
[accessLog]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
# This is required for ACME support
@ -20,13 +16,15 @@ sendAnonymousUsage = true
[[entryPoints.https.tls.certificates]]
certFile = "/etc/traefik/rss.captnemo.in.crt"
keyFile = "/etc/traefik/rss.captnemo.in.key"
# This contains 2 domains: {emby|airsonic}.bb8.fun
[[entryPoints.https.tls.certificates]]
certFile = "/etc/traefik/emby.in.bb8.fun.crt"
keyFile = "/etc/traefik/emby.in.bb8.fun.key"
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
@ -39,33 +37,6 @@ sendAnonymousUsage = true
# 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
@ -74,7 +45,6 @@ sendAnonymousUsage = true
[web.metrics.prometheus]
[acme]
email = "acme@captnemo.in"
storage = "/acme/acme.json"
entryPoint = "https"
@ -85,44 +55,14 @@ acmelogging = true
[acme.httpChallenge]
entryPoint = "http"
# Keep DNS challenge disabled
# for now
# [acme.dnsChallenge]
# provider = "cloudflare"
# delayBeforeCheck = 5
# Get wildcard once possible
[acme.dnsChallenge]
provider = "cloudflare"
delayBeforeCheck = 120
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
# Primary 2 wildcard certs
[[acme.domains]]
main = "bb8.fun"
sans = [
"ads.bb8.fun",
"airsonic.bb8.fun",
"apps.bb8.fun",
"cadvisor.bb8.fun",
"dns.bb8.fun",
"emby.bb8.fun",
"falcon.bb8.fun", # Temporarily used for lidarr
"ghost.bb8.fun",
"grafana.bb8.fun", # Unused
"headphones.bb8.fun",
"home.bb8.fun",
"info.bb8.fun",
"jackett.bb8.fun",
"library.bb8.fun",
"luke.bb8.fun",
"monitoring.bb8.fun",
# "lidarr.bb8.fun", (TBA)
"ombi.bb8.fun", # Unused
"pics.bb8.fun",
"radarr.bb8.fun",
"read.bb8.fun",
"rey.bb8.fun",
"scan.bb8.fun",
"sonarr.bb8.fun",
"tatooine.bb8.fun",
"tie.bb8.fun",
"traefik.bb8.fun",
"transmission.bb8.fun",
"wifi.bb8.fun",
"wiki.bb8.fun"
]
main = "*.bb8.fun"
# Internal services are also protected!
[[acme.domains]]
main = "*.in.bb8.fun"

View File

@ -3,8 +3,22 @@
{
"pathString": "/files",
"userName": [
"arvind",
"diya",
"gappan",
"himanshu",
"konarak",
"pratyush",
"reddit",
"tatooine"
"riccu",
"sankalp",
"shreyas",
"tatooine",
"vignesh",
"harman",
"pranav",
"swapnil",
"noopur"
]
}
],
@ -12,8 +26,22 @@
{
"pathString": "/comics",
"userName": [
"arvind",
"diya",
"gappan",
"himanshu",
"konarak",
"pratyush",
"reddit",
"tatooine"
"riccu",
"sankalp",
"shreyas",
"tatooine",
"vignesh",
"harman",
"pranav",
"swapnil",
"noopur"
]
}
],
@ -21,51 +49,139 @@
{
"pathString": "/books",
"userName": [
"arvind",
"diya",
"gappan",
"himanshu",
"konarak",
"pratyush",
"reddit",
"tatooine"
"riccu",
"sankalp",
"shreyas",
"tatooine",
"vignesh",
"harman",
"pranav",
"swapnil",
"noopur"
]
}
],
"users": [
{
"name": "reddit",
"passwordHash": "396731fff7f1931aeba6e69d3443d5ef7971569e3b9d64a3a4deca655789917a"
"passwordHash":
"396731fff7f1931aeba6e69d3443d5ef7971569e3b9d64a3a4deca655789917a"
},
{
"name": "tatooine",
"passwordHash": "ca0c540641a9e34c47cbd1866443ca181202aaa422fcc5ad4cbf75095aab7da0"
"passwordHash":
"ca0c540641a9e34c47cbd1866443ca181202aaa422fcc5ad4cbf75095aab7da0"
},
{
"name": "riccu",
"passwordHash":
"ff66d15e21624763cb2d65a21a7aa275ae65219d6f5ed0e5c5583c9be2fc3b12"
},
{
"name": "sankalp",
"passwordHash":
"b3c219dffa8a379c4daaed75c63141ebefa2a6f0a872e9cd7f328ad6511fb863"
},
{
"name": "pratyush",
"passwordHash":
"e63af1a184949abfd3666ef2c60c462191619fdcefadf9021a5d24f236d302fe"
},
{
"name": "arvind",
"passwordHash":
"126f31712138ea8e5f77c0e2565be848ec87a4057dfe1c4070a6c9d1f3de8ded"
},
{
"name": "harman",
"passwordHash":
"f9bd71d0a8cee05a724efae4f5636123f18d8c9c531c470892f8681375726bd2"
},
{
"name": "shreyas",
"passwordHash":
"ee4501f0aa63453f4360e974c3220c2c7a4c58d2125d989b80ef855e1471535d"
},
{
"name": "himanshu",
"passwordHash":
"c8da693b24c20921b16a55b8bd21b9e0c76e3bdfba81df20f1a0e6b010e0c3a5"
},
{
"name": "diya",
"passwordHash":
"96d39fafe6c1cfb8504ba8f438ab3e11a972f7a3bb3908287b9e3fa5bd28e19a"
},
{
"name": "vignesh",
"passwordHash":
"a1589cab7d5123af4fb19ccaea31e586348756944b1dca759a16a4a0b8e1243d"
},
{
"name": "konarak",
"passwordHash":
"49afa1013d2be0498107e12fc755f27edb90787161f00a2ef579bb6ad8c59b63"
},
{
"name": "gappan",
"passwordHash":
"681825c273d75dce4151f6c61358038e099fec2c3540369267f1fa28d607ce1d"
},
{
"name": "swapnil",
"passwordHash":
"f916f120f09ec561ff1d76e19e2749d1a6078e92051f1f5fcca884489fd43745"
},
{
"name": "noopur",
"passwordHash":
"f49e49db9893a187773fb08e8671ff2f9cd83b8d43b657fbf0abe67b3dfc0e9d"
},
{
"name": "pranav",
"passwordHash":
"9df97ced8b4de090c469244230ca64f5164ff37e9fde2314cf8c2e87db6d033b"
}
],
"isFilesProviderEnabled": true,
"isComicsProviderEnabled": true,
"isBooksProviderEnabled": true,
"isUserManagementEnabled": true,
"libraryPortNumber": 2202,
"adminPortNumber": 2203,
"comicWidth": 160,
"comicHeight": 230,
"comicsPaginationNumber": 30,
"bookWidth": 160,
"bookHeight": 230,
"booksPaginationNumber": 30,
"minimizeToTray": false,
"minimizeOnStartup": false,
"autoscanPeriod": 0,
"isRemoteAdminEnabled": true,
"theme": "default",
"isShrinkingCacheEnabled": false,
"shrunkPageWidth": 1536,
"shrunkPageHeight": 2500,
"shrinkingCachePath": "",
"autoScanAtLaunch": false,
"reverseProxyPrefix": "",
"keystorePath": "",
"keystorePassword": "",
"isOpdsProviderEnabled": true,
"folderExclusionPattern": "",
"bypassSingleRootFolder": false,
"enableFolderMetadataDisplay": true,
"bookmarkUsingCookies": false,
"displayTitleInsteadOfFileName": true,
"keepUnreachableSharedFolders": false
"isFilesProviderEnabled" : true,
"isComicsProviderEnabled" : true,
"isBooksProviderEnabled" : true,
"isUserManagementEnabled" : true,
"libraryPortNumber" : 2202,
"adminPortNumber" : 2203,
"comicWidth" : 160,
"comicHeight" : 230,
"comicsPaginationNumber" : 30,
"bookWidth" : 160,
"bookHeight" : 230,
"booksPaginationNumber" : 30,
"minimizeToTray" : false,
"minimizeOnStartup" : false,
"autoscanPeriod" : 1440,
"isRemoteAdminEnabled" : true,
"theme" : "default",
"isShrinkingCacheEnabled" : false,
"shrunkPageWidth" : 1536,
"shrunkPageHeight" : 2500,
"shrinkingCachePath" : "",
"autoScanAtLaunch" : false,
"reverseProxyPrefix" : "",
"keystorePath" : "",
"keystorePassword" : "",
"isOpdsProviderEnabled" : true,
"folderExclusionPattern" : "",
"bypassSingleRootFolder" : false,
"enableFolderMetadataDisplay" : true,
"bookmarkUsingCookies" : false,
"displayTitleInsteadOfFileName" : true,
"keepUnreachableSharedFolders" : false,
"isCalibreLibrary" : false,
"instanceId" : "3a0e4425a8e14c719ca2eb382f85292e"
}

15
docker/conf/wiki.tpl Normal file
View File

@ -0,0 +1,15 @@
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

View File

@ -1,141 +0,0 @@
#######################################################################
# 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
# ---------------------------------------------------------------------
# git:
# url: https://github.com/Organization/Repo
# 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

View File

@ -1,37 +1,12 @@
# Database versions shouldn't be upgraded
data "docker_registry_image" "mariadb" {
name = "mariadb:10.3"
}
data "docker_registry_image" "mongorocks" {
name = "jadsonlourenco/mongo-rocks:latest"
}
data "docker_registry_image" "emby" {
name = "emby/embyserver:latest"
}
data "docker_registry_image" "transmission" {
name = "linuxserver/transmission:latest"
}
data "docker_registry_image" "traefik" {
name = "traefik:cancoillotte-alpine"
}
data "docker_registry_image" "wikijs" {
name = "requarks/wiki:latest"
name = "traefik:1.7"
}
data "docker_registry_image" "ubooquity" {
name = "linuxserver/ubooquity:latest"
}
data "docker_registry_image" "headerdebug" {
name = "brndnmtthws/nginx-echo-headers:latest"
}
data "docker_registry_image" "lychee" {
name = "linuxserver/lychee:latest"
}

View File

@ -1,56 +0,0 @@
resource "docker_container" "mongorocks" {
name = "mongorocks"
image = "${docker_image.mongorocks.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}"
}
env = [
"AUTH=no",
"DATABASE=wiki",
"OPLOG_SIZE=50",
]
}
resource "docker_container" "mariadb" {
name = "mariadb"
image = "${docker_image.mariadb.latest}"
volumes {
volume_name = "${docker_volume.mariadb_volume.name}"
container_path = "/var/lib/mysql"
host_path = "${docker_volume.mariadb_volume.mountpoint}"
}
// This is so that other host-only services can share this
ports {
internal = 3306
external = 3306
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 = 3306
external = 3306
ip = "${var.ips["tun0"]}"
}
memory = 512
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
env = [
"MYSQL_ROOT_PASSWORD=${var.mysql_root_password}",
]
}

View File

@ -1,16 +0,0 @@
# resource "docker_container" "headerdebug" {
# name = "headerdebug"
# image = "${docker_image.headerdebug.latest}"
# restart = "unless-stopped"
# destroy_grace_seconds = 30
# must_run = true
# memory = 16
# labels = "${merge(
# local.traefik_common_labels,
# map(
# "traefik.frontend.rule", "Host:debug.in.${var.domain},debug.${var.domain}",
# "traefik.port", 8080,
# "traefik.enable", "true",
# ))}"
# }

View File

@ -1,36 +0,0 @@
resource "docker_container" "emby" {
name = "emby"
image = "${docker_image.emby.latest}"
volumes {
host_path = "/mnt/xwing/config/emby"
container_path = "/config"
}
volumes {
host_path = "/mnt/xwing/media"
container_path = "/media"
}
labels = "${merge(
local.traefik_common_labels,
map(
"traefik.frontend.rule", "Host:emby.in.${var.domain},emby.${var.domain}",
"traefik.frontend.passHostHeader", "true",
"traefik.port", 8096,
))}"
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",
]
}

20
docker/got.tf Normal file
View File

@ -0,0 +1,20 @@
data "docker_registry_image" "gotviz" {
name = "tocttou/gotviz:latest"
}
# resource "docker_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}"
# 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
# }

View File

@ -1,49 +1,14 @@
resource "docker_image" "emby" {
name = "${data.docker_registry_image.emby.name}"
pull_triggers = ["${data.docker_registry_image.emby.sha256_digest}"]
}
resource "docker_image" "mariadb" {
name = "${data.docker_registry_image.mariadb.name}"
pull_triggers = ["${data.docker_registry_image.mariadb.sha256_digest}"]
}
resource "docker_image" "transmission" {
name = "${data.docker_registry_image.transmission.name}"
pull_triggers = ["${data.docker_registry_image.transmission.sha256_digest}"]
}
resource "docker_image" "traefik" {
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}"]
}
# Attempting to use mongorocks to work around reboot issue
# Hoping that this will not face reboot-recovery issues
# Wrote about this: https://captnemo.in/blog/2017/12/18/home-server-learnings/
resource "docker_image" "mongorocks" {
name = "${data.docker_registry_image.mongorocks.name}"
pull_triggers = ["${data.docker_registry_image.mongorocks.sha256_digest}"]
resource "docker_image" "traefik17" {
name = data.docker_registry_image.traefik.name
pull_triggers = [data.docker_registry_image.traefik.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]
}
# Helps debug traefik reverse proxy headers
# Highly recommended!
# resource "docker_image" "headerdebug" {
# name = "${data.docker_registry_image.headerdebug.name}"
# pull_triggers = ["${data.docker_registry_image.headerdebug.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}"]
}

View File

@ -1,18 +1,17 @@
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"
}
}

View File

@ -1,37 +1,30 @@
resource "docker_container" "lychee" {
name = "lychee"
image = "${docker_image.lychee.latest}"
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
volumes {
host_path = "/mnt/xwing/config/lychee"
container_path = "/config"
}
volumes {
host_path = "/mnt/xwing/data/lychee"
container_path = "/pictures"
}
upload {
content = "${file("${path.module}/conf/lychee.php.ini")}"
file = "/config/lychee/user.ini"
}
labels = "${merge(
local.traefik_common_labels,
map(
"traefik.port", 80,
"traefik.frontend.rule", "Host:pics.${var.domain}",
))}"
env = [
"PUID=986",
"PGID=984",
]
links = ["${docker_container.mariadb.name}"]
}
# resource "docker_container" "lychee" {
# name = "lychee"
# image = "${docker_image.lychee.image_id}"
# restart = "unless-stopped"
# destroy_grace_seconds = 10
# must_run = true
# volumes {
# host_path = "/mnt/xwing/config/lychee"
# container_path = "/config"
# }
# volumes {
# host_path = "/mnt/xwing/data/lychee"
# container_path = "/pictures"
# }
# upload {
# content = "${file("${path.module}/conf/lychee.php.ini")}"
# file = "/config/lychee/user.ini"
# }
# labels = "${merge(
# local.traefik_common_labels,
# map(
# "traefik.port", 80,
# "traefik.frontend.rule", "Host:pics.${var.domain}",
# ))}"
# env = [
# "PUID=986",
# "PGID=984",
# ]
# # links = ["${var.links-mariadb}"]
# }

View File

@ -1 +0,0 @@

6
docker/network.tf Normal file
View File

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

View File

@ -1,23 +1,16 @@
output "lychee-ip" {
value = "${docker_container.lychee.ip_address}"
}
output "names-transmission" {
value = "${docker_container.transmission.name}"
}
output "names-emby" {
value = "${docker_container.emby.name}"
}
output "names-mariadb" {
value = "${docker_container.mariadb.name}"
}
# output "lychee-ip" {
# value = "${docker_container.lychee.ip_address}"
# }
output "names-traefik" {
value = "${docker_container.traefik.name}"
value = docker_container.traefik.name
}
output "traefik-network-id" {
value = docker_network.traefik.id
}
output "auth-header" {
value = "${var.basic_auth}"
value = var.basic_auth
}

19
docker/providers.tf Normal file
View File

@ -0,0 +1,19 @@
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

@ -1,80 +1,95 @@
resource "docker_container" "traefik" {
name = "traefik"
image = "${docker_image.traefik.latest}"
image = docker_image.traefik17.image_id
# Admin Backend
ports {
internal = 1111
external = 1111
ip = "${var.ips["eth0"]}"
labels {
label = "traefik.enable"
value = "true"
}
ports {
internal = 1111
external = 1111
ip = "${var.ips["tun0"]}"
labels {
label = "traefik.http.routers.api.rule"
value = "Host('traefik.in.bb8.fun')"
}
labels {
label = "traefik.http.routers.api.service"
value = "api@internal"
}
# Local Web Server
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")}"
file = "/etc/traefik/git.captnemo.in.crt"
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")}"
file = "/etc/traefik/git.captnemo.in.key"
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/rss.captnemo.in/fullchain.pem")}"
file = "/etc/traefik/rss.captnemo.in.crt"
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/rss.captnemo.in/privkey.pem")}"
file = "/etc/traefik/rss.captnemo.in.key"
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/emby.in.bb8.fun/privkey.pem")}"
file = "/etc/traefik/emby.in.bb8.fun.key"
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/emby.in.bb8.fun/fullchain.pem")}"
file = "/etc/traefik/emby.in.bb8.fun.crt"
content = file(
"/home/nemo/projects/personal/certs/rss.captnemo.in/privkey.pem",
)
file = "/etc/traefik/rss.captnemo.in.key"
}
volumes {
@ -89,10 +104,20 @@ resource "docker_container" "traefik" {
}
memory = 256
restart = "unless-stopped"
restart = "always"
destroy_grace_seconds = 10
must_run = true
// `bridge` is auto-connected for now
// https://github.com/terraform-providers/terraform-provider-docker/issues/10
networks_advanced {
name = "traefik"
}
networks_advanced {
name = "bridge"
}
env = [
"CLOUDFLARE_EMAIL=${var.cloudflare_email}",
"CLOUDFLARE_API_KEY=${var.cloudflare_key}",

View File

@ -1,49 +0,0 @@
resource docker_container "transmission" {
name = "transmission"
image = "${docker_image.transmission.latest}"
labels = "${merge(
local.traefik_common_labels,
map(
"traefik.frontend.auth.basic", "${var.basic_auth}",
"traefik.port", 9091,
))}"
ports {
internal = 51413
external = 51413
ip = "${var.ips["eth0"]}"
protocol = "udp"
}
volumes {
host_path = "/mnt/xwing/config/transmission"
container_path = "/config"
}
volumes {
host_path = "/mnt/xwing/media/DL"
container_path = "/downloads"
}
volumes {
host_path = "/mnt/xwing/data/watch/transmission"
container_path = "/watch"
}
upload {
content = "${file("${path.module}/conf/transmission.json")}"
file = "/config/settings.json"
}
env = [
"PGID=1003",
"PUID=1000",
"TZ=Asia/Kolkata",
]
memory = 1024
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
}

View File

@ -1,6 +1,13 @@
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.latest}"
image = docker_image.ubooquity.image_id
restart = "unless-stopped"
destroy_grace_seconds = 30
@ -25,28 +32,37 @@ resource "docker_container" "ubooquity" {
host_path = "/mnt/xwing/media/EBooks/Comics"
container_path = "/comics"
}
labels {
"traefik.enable" = "true"
"traefik.admin.port" = 2203
"traefik.admin.frontend.rule" = "Host:library.${var.domain}"
"traefik.admin.frontend.auth.basic" = "${var.basic_auth}"
"traefik.read.port" = 2202
"traefik.read.frontend.rule" = "Host:read.${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}"
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"
}
upload {
content = "${file("${path.module}/conf/ubooquity.json")}"
content = file("${path.module}/conf/ubooquity.json")
file = "/config/preferences.json"
}
@ -57,3 +73,4 @@ resource "docker_container" "ubooquity" {
"MAXMEM=800",
]
}

View File

@ -1,22 +1,18 @@
variable "web_username" {
type = "string"
type = string
}
variable "web_password" {
type = "string"
}
variable "mysql_root_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"
}
@ -43,13 +39,15 @@ variable "refpolicy" {
}
variable "wiki_session_secret" {
type = "string"
type = string
}
variable "domain" {
type = "string"
type = string
}
variable "ips" {
type = "map"
type = map(string)
}
# variable "links-mariadb" {}

View File

@ -1,7 +0,0 @@
resource "docker_volume" "mariadb_volume" {
name = "mariadb_volume"
}
resource "docker_volume" "mongorocks_data_volume" {
name = "mongorocks_data_volume"
}

View File

@ -1,51 +0,0 @@
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}",
))}"
links = ["${docker_container.mongorocks.name}"]
env = [
"WIKI_ADMIN_EMAIL=me@captnemo.in",
"SESSION_SECRET=${var.wiki_session_secret}",
]
}

12
echoserver.tf Normal file
View File

@ -0,0 +1,12 @@
module "echo-server" {
source = "./modules/container"
name = "echo-server"
image = "jmalloc/echo-server:latest"
web = {
expose = "true"
port = 8080
host = "debug.${var.root-domain},debug.in.${var.root-domain}"
}
}

45
elibsrv.tf Normal file
View File

@ -0,0 +1,45 @@
module "elibsrv" {
name = "elibsrv"
source = "./modules/container"
image = "captn3m0/elibsrv"
resource = {
memory = 512
memory_swap = 512
}
web = {
expose = true
host = "ebooks.${var.root-domain}"
auth = true
}
volumes = [
{
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"
container_path = "/cache"
},
]
# 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"]
}

View File

@ -1,19 +1,27 @@
; This file lists the default values used by Gitea
; 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
; 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
[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
@ -33,6 +41,11 @@ 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
@ -47,11 +60,12 @@ KEYWORDS = git, captnemo, git.captnemo.in, piratecoders
ENABLE_HARD_LINE_BREAK = false
; List of custom URL-Schemes that are allowed as links when rendering Markdown
; for example git,magnet
CUSTOM_URL_SCHEMES = git,magnet,steam
; List of file extensions that should be rendered/edited as Markdown
; Separate extensions with a comma. To render files w/o extension as markdown, just put a comma
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
@ -59,49 +73,48 @@ ECDSA = 256
RSA = 2048
DSA = 1024
[lfs]
PATH=/data/gitea/lfs
[server]
APP_DATA_PATH = /data/gitea
SSH_DOMAIN = git.captnemo.in
HTTP_PORT = 3000
ROOT_URL = https://git.captnemo.in/
DISABLE_SSH = false
SSH_PORT = 22
DISABLE_SSH = true
DOMAIN = git.captnemo.in
LFS_START_SERVER = true
LFS_CONTENT_PATH = /data/gitea/lfs
LFS_JWT_SECRET = nsLco71Wn4iu_UzyDir0jzkCdJDya1L9N0KZfgew13E
LFS_JWT_SECRET = "${lfs-jwt-secret}"
OFFLINE_MODE = true
LANDING_PAGE = explore
MINIMUM_KEY_SIZE_CHECK = true
# Uses the Mozilla Modern SSH Config params
SSH_SERVER_CIPHERS = chacha20-poly1305@openssh.com, aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr
SSH_SERVER_KEY_EXCHANGES = curve25519-sha256@libssh.org, ecdh-sha2-nistp521, ecdh-sha2-nistp384, ecdh-sha2-nistp256, diffie-hellman-group-exchange-sha256
SSH_SERVER_MACS = hmac-sha2-512-etm@openssh.com, hmac-sha2-256-etm@openssh.com, umac-128-etm@openssh.com, hmac-sha2-512, hmac-sha2-256, umac-128@openssh.com
DISABLE_ROUTER_LOG = true
ENABLE_GZIP = true
[database]
; TODO
; ; Either "mysql", "postgres", "mssql" or "sqlite3", it's your choice
; DB_TYPE = mysql
; HOST = 127.0.0.1:3306
; NAME = gitea
; USER = root
; PASSWD =
DB_TYPE = sqlite3
HOST = mariadb:3306
NAME = gitea
USER = gitea
; PASSWD = "mysql-password"
; ; For "postgres" only, either "disable", "require" or "verify-full"
; SSL_MODE = disable
; ; For "sqlite3" and "tidb", use absolute path when you start as service
; PATH = data/gitea.db
PATH = /data/gitea/gitea.db
; ; For "sqlite3" only. Query timeout
; SQLITE_TIMEOUT = 500
SQLITE_TIMEOUT = 500
; ; For iterate buffer, default is 50
; ITERATE_BUFFER_SIZE = 50
PATH = /data/gitea/gitea.db
DB_TYPE = sqlite3
HOST = localhost:3306
NAME = gitea
USER = root
PASSWD =
SSL_MODE = disable
[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER = file
; Show the database generated SQL
LOG_SQL = false
SQLITE_JOURNAL_MODE = WAL
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
@ -111,33 +124,25 @@ ENABLE_FEDERATED_AVATAR = false
[indexer]
ISSUE_INDEXER_PATH = indexers/issues.bleve
; repo indexer by default disabled, since it uses a lot of disk space
REPO_INDEXER_ENABLED = false
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
[security]
; Whether the installer is disabled
INSTALL_LOCK = true
; Auto-login remember days
LOGIN_REMEMBER_DAYS = 30
; COOKIE_USERNAME = gitea_awesome
; COOKIE_REMEMBER_NAME = gitea_incredible
; Reverse proxy authentication header name of user name
; REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
; Sets the minimum password length for new Users
MIN_PASSWORD_LENGTH = 10
; True when users are allowed to import local server paths
IMPORT_LOCAL_PATHS = false
; Prevent all users (including admin) from creating custom git hooks
IMPORT_LOCAL_PATHS = true
DISABLE_GIT_HOOKS = true
SECRET_KEY = ${secret_key}
INTERNAL_TOKEN = ${internal_token}
SECRET_KEY = "${secret_key}"
INTERNAL_TOKEN = "${internal_token}"
[service]
; ; More detail: https://github.com/gogits/gogs/issues/165
@ -150,14 +155,16 @@ ACTIVE_CODE_LIVE_MINUTES = 15
RESET_PASSWD_CODE_LIVE_MINUTES = 30
REGISTER_EMAIL_CONFIRM = true
ENABLE_NOTIFY_MAIL = true
DISABLE_REGISTRATION = false
DISABLE_REGISTRATION = true
; ; 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 = false
DEFAULT_KEEP_EMAIL_PRIVATE = true
; ; Default value for AllowCreateOrganization
; ; New user will have rights set to create organizations depending on this setting
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
@ -170,174 +177,59 @@ NO_REPLY_ADDRESS = noreply.example.org
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
; [webhook]
; ; Hook task queue length, increase if webhook shooting starts hanging
; QUEUE_LENGTH = 1000
; ; Deliver timeout in seconds
; DELIVER_TIMEOUT = 5
; ; Allow insecure certification
; SKIP_TLS_VERIFY = false
; ; Number of history information in each page
; PAGING_NUM = 10
[mailer]
ENABLED = true
; ; Buffer length of channel, keep it as it is if you don't know what it is.
; SEND_BUFFER_LEN = 100
; ; Name displayed in mail title
; SUBJECT = %(APP_NAME)s
; ; Mail server
; ; Gmail: smtp.gmail.com:587
; ; QQ: smtp.qq.com:465
; ; Note, if the port ends with "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409. If the server supports STARTTLS it will always be used.
HOST = smtp.migadu.com:587
; ; Disable HELO operation when hostname are different.
; DISABLE_HELO =
; ; Custom hostname for HELO operation, default is from system.
; HELO_HOSTNAME =
; ; Do not verify the certificate of the server. Only use this for self-signed certificates
; SKIP_VERIFY =
; ; Use client certificate
; USE_CERTIFICATE = false
; CERT_FILE = custom/mailer/cert.pem
; KEY_FILE = custom/mailer/key.pem
; ; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
FROM = git@captnemo.in
; ; Mailer user name and password
USER = git@captnemo.in
PASSWD = ${smtp_password}
; ; Send mails as plain text
PROTOCOL = smtps
SMTP_ADDR = smtp.migadu.com
SMTP_PORT = 465
SEND_AS_PLAIN_TEXT = true
; ; Enable sendmail (override SMTP)
; USE_SENDMAIL = false
; ; Specify an alternative sendmail binary
; SENDMAIL_PATH = sendmail
; ; Specify any extra sendmail arguments
; SENDMAIL_ARGS =
SUBJECT_PREFIX = "[git.captnemo.in] "
; [cache]
; ; Either "memory", "redis", or "memcache", default is "memory"
; ADAPTER = memory
; ; For "memory" only, GC interval in seconds, default is 60
; INTERVAL = 60
; ; For "redis" and "memcache", connection host address
; ; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
; ; memcache: `127.0.0.1:11211`
; HOST =
; ; Time to keep items in cache if not used, default is 16 hours.
; ; Setting it to 0 disables caching
; ITEM_TTL = 16h
[cache]
ADAPTER = redis
HOST = "network=tcp,addr=gitea-redis:6379,db=0,pool_size=100,idle_timeout=180"
[session]
; ; Either "memory", "file", or "redis", default is "memory"
; PROVIDER = memory
; ; Provider config options
; ; memory: not have any config yet
; ; file: session file path, e.g. `data/sessions`
; ; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
; ; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
; PROVIDER_CONFIG = data/sessions
; ; Session cookie name
COOKIE_NAME = i_like_gitea
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"
; ; If you use session in https only, default is false
COOKIE_SECURE = true
; ; 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
; SameSite settings. Either "none", "lax", or "strict"
SAME_SITE = strict
[migrations]
ALLOWED_DOMAINS = github.com
ALLOW_LOCALNETWORKS = false
; [picture]
; AVATAR_UPLOAD_PATH = data/avatars
; ; Chinese users can choose "duoshuo"
; ; or a custom avatar source, like: http://cn.gravatar.com/avatar/
; GRAVATAR_SOURCE = gravatar
; ; This value will be forced to be true in offline mode.
; DISABLE_GRAVATAR = false
; ; Federated avatar lookup uses DNS to discover avatar associated
; ; with emails, see https://www.libravatar.org
; ; This value will be forced to be false in offline mode or Gravatar is disabled.
; ENABLE_FEDERATED_AVATAR = false
[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 = 4
MAX_SIZE = 200
; ; Max number of files per upload. Defaults to 10
; MAX_FILES = 5
MAX_FILES = 10
; [time]
; ; Specifies the format for fully outputted dates. Defaults to RFC1123
; ; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano
; ; For more information about the format see http://golang.org/pkg/time/#pkg-constants
; FORMAT =
; [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 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 = Info
; ; For "console" mode only
; [log.console]
; LEVEL =
; ; For "file" mode only
; [log.file]
; LEVEL =
; ; This enables automated log rotate(switch of following options), default is true
; LOG_ROTATE = true
; ; Max line number of single file, default is 1000000
; MAX_LINES = 1000000
; ; Max size shift of single file, default is 28 means 1 << 28, 256MB
; MAX_SIZE_SHIFT = 28
; ; Segment log daily, default is true
; DAILY_ROTATE = true
; ; Expired days of log file(delete after max days), default is 7
; MAX_DAYS = 7
; ; For "conn" mode only
; [log.conn]
; LEVEL =
; ; Reconnect host for every single message, default is false
; RECONNECT_ON_MSG = false
; ; Try to reconnect when connection is lost, default is false
; RECONNECT = false
; ; Either "tcp", "unix" or "udp", default is "tcp"
; PROTOCOL = tcp
; ; Host address
; ADDR =
; ; For "smtp" mode only
; [log.smtp]
; LEVEL =
; ; Name displayed in mail title, default is "Diagnostic message from server"
; SUBJECT = Diagnostic message from server
; ; Mail server
; HOST =
; ; Mailer user name and password
; USER =
; PASSWD =
; ; Receivers, can be one or more, e.g. 1@example.com,2@example.com
; RECEIVERS =
; ; For "database" mode only
; [log.database]
; LEVEL =
; ; Either "mysql" or "postgres"
; DRIVER =
; ; Based on xorm, e.g.: root:root@localhost/gitea?charset=utf8
; CONN =
[log]
; 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
REDIRECT_MACARON_LOG = true
ROUTER_LOG_LEVEL = Critical
logger.access.MODE=,
logger.xorm.MODE=,
[cron]
; Enable running cron tasks periodically.
@ -345,107 +237,34 @@ ENABLED = true
; ; Run cron tasks when Gitea starts.
RUN_AT_START = false
[cron.archive_cleanup]
RUN_AT_START = true
SCHEDULE = @midnight
; Archives created more than OLDER_THAN ago are subject to deletion
OLDER_THAN = 24h
; ; Update mirrors
[cron.update_mirrors]
SCHEDULE = @every 3h
; ; Repository health check
; [cron.repo_health_check]
; SCHEDULE = @every 24h
; TIMEOUT = 60s
; ; Arguments for command 'git fsck', e.g. "--unreachable --tags"
; ; see more on http://git-scm.com/docs/git-fsck/1.7.5
; ARGS =
; ; Check repository statistics
; [cron.check_repo_stats]
; RUN_AT_START = true
; SCHEDULE = @every 24h
; Repository health check
[cron.repo_health_check]
SCHEDULE = @midnight
TIMEOUT = 60s
; Arguments for command 'git fsck', e.g. "--unreachable --tags"
; see more on http://git-scm.com/docs/git-fsck
ARGS =
; ; Clean up old repository archives
; [cron.archive_cleanup]
; ; Whether to enable the job
; ENABLED = true
; ; Whether to always run at least once at start up time (if ENABLED)
; RUN_AT_START = true
; ; Time interval for job to run
; SCHEDULE = @every 24h
; ; Archives created more than OLDER_THAN ago are subject to deletion
; OLDER_THAN = 24h
; ; Synchronize external user data (only LDAP user synchronization is supported)
; [cron.sync_external_users]
; ; Synchronize external user data when starting server (default false)
; RUN_AT_START = false
; ; Interval as a duration between each synchronization (default every 24h)
; SCHEDULE = @every 24h
; ; Create new users, update existing user data and disable users that are not in external source anymore (default)
; ; or only create new users if UPDATE_EXISTING is set to false
; UPDATE_EXISTING = true
; [git]
; ; Disables highlight of added and removed changes
; DISABLE_DIFF_HIGHLIGHT = false
; ; Max number of lines allowed of a single file in diff view
; MAX_GIT_DIFF_LINES = 1000
; ; Max number of characters of a line allowed 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/1.7.5
; GC_ARGS =
; ; Operation timeout in seconds
[git.timeout]
MIGRATE = 600
MIRROR = 300
CLONE = 300
PULL = 300
GC = 60
; [mirror]
; ; Default interval as a duration between each check
; DEFAULT_INTERVAL = 8h
; ; Min interval as a duration must be > 1m
; MIN_INTERVAL = 10m
; Check repository statistics
[cron.check_repo_stats]
RUN_AT_START = true
SCHEDULE = @midnight
[api]
; Max number of items will response in a page
MAX_RESPONSE_ITEMS = 100
; [i18n]
; LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
; NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
; ; Used for datetimepicker
; [i18n.datelang]
; en-US = en
; zh-CN = zh
; zh-HK = zh-TW
; zh-TW = zh-TW
; de-DE = de
; fr-FR = fr
; nl-NL = nl
; lv-LV = lv
; ru-RU = ru
; ja-JP = ja
; es-ES = es
; pt-BR = pt-BR
; pl-PL = pl
; bg-BG = bg
; it-IT = it
; fi-FI = fi
; tr-TR = tr
; cs-CZ = cs-CZ
; sr-SP = sr
; sv-SE = sv
; ko-KR = ko
; ; Extension mapping to highlight class
; ; e.g. .toml=ini
; [highlight.mapping]
[other]
SHOW_FOOTER_BRANDING = false
; Show version information about Gitea and Go in the footer
@ -453,16 +272,42 @@ SHOW_FOOTER_VERSION = true
; Show time of template execution in the footer
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
; [markup.asciidoc]
; ENABLED = false
; ; List of file extensions that should be rendered by an external command
; FILE_EXTENSIONS = .adoc,.asciidoc
; ; External command to render all matching extensions
; RENDER_COMMAND = "asciidoc --out-file=- -"
; ; Input is not a standard input but a file
; IS_INPUT_FILE = false
[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = true
ENABLE_OPENID_SIGNUP = false
[metrics]
; Enables metrics endpoint. True or false; default is false.
ENABLED = true
[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

View File

@ -0,0 +1,56 @@
<?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>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1,22 @@
User-agent: MJ12bot
Disallow: /
User-agent: SemrushBot
Disallow: /
User-agent: SemrushBot-SA
Disallow: /
User-agent: rogerbot
Disallow:/
User-agent: dotbot
Disallow:/
User-agent: AhrefsBot
Disallow: /
User-agent: Alexibot
Disallow: /
User-agent: SurveyBot
Disallow: /
User-agent: Xenus
Disallow: /
User-agent: Xenus Link Sleuth 1.1c
Disallow: /
User-agent: AhrefsBot
Disallow: /

22
gitea/conf/robots.txt Normal file
View File

@ -0,0 +1,22 @@
User-agent: MJ12bot
Disallow: /
User-agent: SemrushBot
Disallow: /
User-agent: SemrushBot-SA
Disallow: /
User-agent: rogerbot
Disallow:/
User-agent: dotbot
Disallow:/
User-agent: AhrefsBot
Disallow: /
User-agent: Alexibot
Disallow: /
User-agent: SurveyBot
Disallow: /
User-agent: Xenus
Disallow: /
User-agent: Xenus Link Sleuth 1.1c
Disallow: /
User-agent: AhrefsBot
Disallow: /

View File

@ -1,14 +1,21 @@
# https://github.com/go-gitea/gitea/releases
data "docker_registry_image" "gitea" {
name = "gitea/gitea:1.4"
name = "gitea/gitea:1.21"
}
data "docker_registry_image" "redis" {
name = "redis:alpine"
}
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}"
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
}
}

View File

@ -1,67 +1,89 @@
resource docker_container "gitea" {
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.latest}"
image = docker_image.gitea.image_id
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"]}"
dynamic "labels" {
for_each = local.l
content {
label = labels.key
value = labels.value
}
}
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 = "${file("${path.module}/conf/public/img/gitea-lg.png")}"
file = "/data/gitea/public/img/gitea-lg.png"
content_base64 = filebase64("${path.module}/conf/public/img/gitea-lg.png")
file = "/data/gitea/public/img/logo.png"
}
upload {
content = "${file("${path.module}/conf/public/img/gitea-sm.png")}"
file = "/data/gitea/public/img/gitea-sm.png"
content_base64 = filebase64("${path.module}/conf/public/img/gitea-lg.png")
file = "/data/gitea/public/img/apple-touch-icon.png"
}
upload {
content = "${file("${path.module}/conf/public/img/gitea-sm.png")}"
file = "/data/gitea/public/img/favicon.png"
content_base64 = filebase64("${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"
}
upload {
content = "${file("${path.module}/../docker/conf/humans.txt")}"
file = "/data/gitea/public/humans.txt"
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"
}
upload {
content = file("${path.module}/conf/public/robots.txt")
file = "/data/gitea/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 = 256
restart = "unless-stopped"
memory = 800
restart = "always"
destroy_grace_seconds = 10
must_run = true
networks = ["gitea", "traefik"]
}
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]
}

5
gitea/network.tf Normal file
View File

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

19
gitea/providers.tf Normal file
View File

@ -0,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}

23
gitea/redis.tf Normal file
View File

@ -0,0 +1,23 @@
resource "docker_container" "redis" {
name = "gitea-redis"
image = docker_image.redis.image_id
volumes {
host_path = "/mnt/xwing/cache/gitea"
container_path = "/data"
}
memory = 64
restart = "always"
destroy_grace_seconds = 10
must_run = true
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]
keep_locally = true
}

View File

@ -1,13 +1,32 @@
variable "traefik-labels" {
type = "map"
type = map(string)
}
variable "domain" {}
variable "domain" {
}
variable "ips" {
type = "map"
type = map(string)
}
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" {}

View File

@ -1,3 +1,4 @@
resource "docker_volume" "gitea_volume" {
name = "gitea_volume"
}

View File

@ -1,34 +0,0 @@
data "docker_registry_image" "heimdall" {
name = "linuxserver/heimdall:latest"
}
resource "docker_image" "heimdall" {
name = "${data.docker_registry_image.heimdall.name}"
pull_triggers = ["${data.docker_registry_image.heimdall.sha256_digest}"]
}
resource docker_container "heimdall" {
name = "heimdall"
image = "${docker_image.heimdall.latest}"
labels = "${merge(
var.traefik-labels, map(
"traefik.port", "443",
"traefik.protocol", "https",
"traefik.frontend.rule","Host:${var.domain}",
"traefik.frontend.auth.basic", "${var.auth-header}",
))}"
volumes {
host_path = "/mnt/xwing/config/heimdall"
container_path = "/config"
}
env = [
"TZ=Asia/Kolkata",
]
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
}

View File

@ -1,11 +0,0 @@
variable "domain" {
type = "string"
}
variable "auth-header" {
type = "string"
}
variable "traefik-labels" {
type = "map"
}

24
home-assistant/main.tf Normal file
View File

@ -0,0 +1,24 @@
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"
},
]
}

16
jupyter.tf Normal file
View File

@ -0,0 +1,16 @@
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
}

21
kaarana.tf Normal file
View File

@ -0,0 +1,21 @@
# kaarana related stuff
# module "kaarana" {
# source = "./kaarana"
# root_db_password = data.pass_password.kaarana-root-db-password.password
# db_password = data.pass_password.kaarana-db-password.password
# providers = {
# docker = docker.sydney
# }
# }
data "pass_password" "kaarana-root-db-password" {
path = "KAARANA_DB_ROOT_PASSWORD"
}
data "pass_password" "kaarana-db-password" {
path = "KAARANA_DB_PASSWORD"
}

40
kaarana/database.tf Normal file
View File

@ -0,0 +1,40 @@
// Create a small database network
resource "docker_network" "kaarana-db" {
name = "kaarana-db"
labels = {
internal = "true"
role = "database"
}
internal = true
ipam_config {
subnet = "172.20.0.0/29"
gateway = "172.20.0.1"
}
}
// Run a small mySQL container in this subnet
resource "docker_container" "mysql" {
image = docker_image.db.image_id
name = "kaarana-mariadb"
restart = "always"
must_run = true
env = [
"MYSQL_ROOT_PASSWORD=${var.root_db_password}",
"MYSQL_USER=${local.username}",
"MYSQL_PASSWORD=${var.db_password}",
"MYSQL_DATABASE=${local.database}",
]
volumes {
host_path = "/mnt/disk/kaarana-db"
container_path = "/var/lib/mysql"
}
networks = ["kaarana-db"]
}

27
kaarana/images.tf Normal file
View File

@ -0,0 +1,27 @@
data "docker_registry_image" "wp" {
name = "wordpress:latest"
}
resource "docker_image" "wp" {
name = "wordpress"
pull_triggers = [data.docker_registry_image.wp.sha256_digest]
}
data "docker_registry_image" "db" {
name = "mariadb:10.4"
}
resource "docker_image" "db" {
name = "mariadb"
pull_triggers = [data.docker_registry_image.db.sha256_digest]
}
data "docker_registry_image" "traefik" {
name = "traefik:v2.0"
}
resource "docker_image" "traefik" {
name = "traefik"
pull_triggers = [data.docker_registry_image.db.sha256_digest]
}

64
kaarana/traefik.tf Normal file
View File

@ -0,0 +1,64 @@
// Create a small database network
resource "docker_network" "traefik" {
name = "traefik"
labels = {
internal = "true"
role = "ingress"
}
internal = true
}
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",
]
upload {
content = file("${path.module}/traefik.toml")
file = "/etc/traefik/traefik.toml"
}
volumes {
host_path = "/var/run/docker.sock"
container_path = "/var/run/docker.sock"
read_only = true
}
volumes {
host_path = "/mnt/disk/traefik"
container_path = "/acme"
}
ports {
internal = 443
external = 8443
ip = "139.59.22.234"
}
ports {
internal = 80
external = 80
ip = "139.59.22.234"
}
memory = 256
restart = "always"
destroy_grace_seconds = 10
must_run = true
networks_advanced {
name = "bridge"
}
networks_advanced {
name = "traefik"
}
}

45
kaarana/traefik.toml Normal file
View File

@ -0,0 +1,45 @@
# This configures docker service discovery
[providers.docker]
exposedByDefault = false
network = "traefik"
defaultRule = ""
[entryPoints]
[entryPoints.web]
address = ":80"
[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"
]

12
kaarana/vars.tf Normal file
View File

@ -0,0 +1,12 @@
variable "root_db_password" {
}
variable "db_password" {
}
locals {
username = "wordpress"
database = "wordpress"
db_hostname = "kaarana.db"
}

40
kaarana/wordpress.tf Normal file
View File

@ -0,0 +1,40 @@
resource "docker_container" "wp" {
image = docker_image.wp.image_id
name = "kaarana-wordpress"
restart = "always"
must_run = true
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"
}
env = [
"WORDPRESS_DB_HOST=${local.db_hostname}",
"WORDPRESS_DB_USER=${local.username}",
"WORDPRESS_DB_PASSWORD=${var.db_password}",
"WORDPRESS_DB_NAME=${local.database}",
"WORDPRESS_TABLE_PREFIX=",
]
volumes {
host_path = "/mnt/disk/kaarana-wp"
container_path = "/var/www/html"
}
ports {
internal = 80
external = 8213
ip = "10.8.0.1"
}
networks = ["bridge", "kaarana-db"]
}

33
kavita.tf Normal file
View File

@ -0,0 +1,33 @@
# 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",
# ]
# }

41
kayak.tf Normal file
View File

@ -0,0 +1,41 @@
# // Points to the local working directory instead of
# // the published version
# module "kayak" {
# source = "../terraform-digitalocean-kayak"
# cert_path = "${path.root}/secrets/kayak"
# domain = "kayak.${var.root-domain}"
# ssh_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD0Getey8585AqdgIl9mqQ3SH9w6z7NZUW4HXdOqZwC7sYEaDrLOBV014gtFS8h8ymm4dcw6xEGUkaavcHC8W9ChTLKBMK4N1/sUS/umLy+Wi/K//g13y0VHSdvcc+gMQ27b9n/DwDY4ZKkaf6t+4HWyFWNh6gp0cT1WCyLNlsER55KUdy+C1lCOpv1SMepOaYc7uyBlC9FfgewJho/OfxnoTztQV6QeSGfr2Xr94Ip1FUPoLoBLLilh4ZbCe6F6bqn0kNgVBTkrVwWJv5Z0jCJpUjER69cqjASRao9KCHkyPtybzKKhCLZIlB3QMggEv0xnlHMpeeuDWcGrBVPKI8V"
# asset_dir = "${path.root}/k8s"
# providers {
# docker = "docker.kayak"
# }
# }
# provider "docker" {
# host = "tcp://${cloudflare_record.kayak-docker.hostname}:2376"
# version = "~> 2.0.0"
# alias = "kayak"
# ca_material = "${module.kayak.docker_ca_cert}"
# cert_material = "${module.kayak.docker_client_cert}"
# key_material = "${module.kayak.docker_client_key}"
# }
# resource "cloudflare_record" "kayak-docker" {
# name = "docker.kayak"
# value = "${module.kayak.droplet_ipv4}"
# domain = "${var.root-domain}"
# type = "A"
# ttl = 120
# }
# resource "cloudflare_record" "kayak" {
# name = "kayak"
# value = "${module.kayak.droplet_ipv4}"
# domain = "${var.root-domain}"
# type = "A"
# ttl = 120
# }
# resource "cloudflare_record" "kayak-etcd" {
# name = "etcd.kayak"
# value = "${module.kayak.droplet_ipv4_private}"
# domain = "${var.root-domain}"
# type = "A"
# ttl = 120
# }

40
klaxon.tf Normal file
View File

@ -0,0 +1,40 @@
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"]
}

19
kube-test.tf Normal file
View File

@ -0,0 +1,19 @@
// Bring up a simple test container
// In the controller node
# resource "kubernetes_pod" "nginx" {
# metadata {
# name = "terraform-example"
# namespace = "default"
# }
# spec {
# toleration {
# key = "node-role.kubernetes.io/master"
# operator = "Exists"
# effect = "NoSchedule"
# }
# container {
# image = "nginx:latest"
# name = "nginx"
# }
# }
# }

152
main.tf
View File

@ -1,94 +1,112 @@
module "cloudflare" {
source = "cloudflare"
domain = "bb8.fun"
ips = "${var.ips}"
}
source = "./cloudflare"
domain = "bb8.fun"
zone_id = lookup(data.cloudflare_zones.bb8.zones[0], "id")
ips = var.ips
module "mysql" {
source = "mysql"
mysql_root_password = "${var.mysql_root_password}"
mysql_lychee_password = "${var.mysql_lychee_password}"
mysql_airsonic_password = "${var.mysql_airsonic_password}"
mysql_kodi_password = "${var.mysql_kodi_password}"
lychee_ip = "${module.docker.lychee-ip}"
droplet_ip = module.digitalocean.droplet_ipv4
}
module "docker" {
source = "docker"
web_username = "${var.web_username}"
web_password = "${var.web_password}"
mysql_root_password = "${var.mysql_root_password}"
cloudflare_key = "${var.cloudflare_key}"
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 = "${var.wiki_session_secret}"
ips = "${var.ips}"
wiki_session_secret = data.pass_password.wiki_session_secret.password
ips = var.ips
domain = "bb8.fun"
}
module "db" {
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
}
module "gitea" {
source = "gitea"
domain = "git.captnemo.in"
traefik-labels = "${var.traefik-common-labels}"
ips = "${var.ips}"
secret-key = "${var.gitea-secret-key}"
internal-token = "${var.gitea-internal-token}"
smtp-password = "${var.gitea-smtp-password}"
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
//passed, but not used
mysql-password = ""
traefik-network-id = module.docker.traefik-network-id
}
module "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
}
module "radicale" {
source = "radicale"
domain = "radicale.bb8.fun"
traefik-labels = "${var.traefik-common-labels}"
}
module "tt-rss" {
source = "tt-rss"
domain = "rss.captnemo.in"
mysql_password = "${var.mysql-ttrss-password}"
links-db = "${module.docker.names-mariadb}"
traefik-labels = "${var.traefik-common-labels}"
}
module "resilio" {
source = "resilio"
domain = "sync.bb8.fun"
traefik-labels = "${var.traefik-common-labels}"
ips = "${var.ips}"
}
module "heimdall" {
source = "heimdall"
domain = "bb8.fun"
traefik-labels = "${var.traefik-common-labels}"
auth-header = "${module.docker.auth-header}"
source = "./radicale"
domain = "radicale.bb8.fun"
}
module "media" {
source = "media"
domain = "bb8.fun"
links-emby = "${module.docker.names-emby}"
links-transmission = "${module.docker.names-transmission}"
links-mariadb = "${module.docker.names-mariadb}"
traefik-labels = "${var.traefik-common-labels}"
airsonic-smtp-password = "${var.airsonic-smtp-password}"
airsonic-db-password = "${var.mysql_airsonic_password}"
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
}
module "monitoring" {
source = "monitoring"
gf-security-admin-password = "${var.gf-security-admin-password}"
source = "./monitoring"
gf-security-admin-password = data.pass_password.gf-security-admin-password.password
domain = "bb8.fun"
transmission = "${module.docker.names-transmission}"
traefik-labels = "${var.traefik-common-labels}"
ips = "${var.ips}"
links-traefik = "${module.docker.names-traefik}"
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"
source = "./digitalocean"
}
module "home-assistant" {
source = "./home-assistant"
}
module "mastodon" {
source = "./mastodon"
db-password = data.pass_password.mastodon-db-password.password
secret-key-base = data.pass_password.mastodon-secret-key-base.password
otp-secret = data.pass_password.mastodon-otp-secret.password
vapid-private-key = data.pass_password.mastodon-vapid-private-key.password
vapid-public-key = data.pass_password.mastodon-vapid-public-key.password
smtp-password = data.pass_password.mastodon-smtp-password.password
}
// Used to force access to ISP related resources
# module "tinyproxy" {
# source = "./tinyproxy"
# ips = "${var.ips}"
# }

29
mastodon/db.tf Normal file
View File

@ -0,0 +1,29 @@
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
}

23
mastodon/locals.tf Normal file
View File

@ -0,0 +1,23 @@
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 Normal file
View File

@ -0,0 +1,103 @@
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
}
}

5
mastodon/network.tf Normal file
View File

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

10
mastodon/provider.tf Normal file
View File

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

18
mastodon/vars.tf Normal file
View File

@ -0,0 +1,18 @@
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
}

View File

@ -1,69 +1,62 @@
resource "docker_container" "airsonic" {
name = "airsonic"
image = "${docker_image.airsonic.latest}"
restart = "unless-stopped"
destroy_grace_seconds = 30
must_run = true
# Unfortunately, the --device flag is not yet supported
# in docker/terraform:
# https://github.com/terraform-providers/terraform-provider-docker/issues/30
upload {
content = "${data.template_file.airsonic-properties-file.rendered}"
file = "/usr/lib/jvm/java-1.8-openjdk/jre/lib/airsonic.properties"
}
# This lets the Jukebox use ALSA
upload {
content = "${file("${path.module}/conf/airsonic.sound.properties")}"
file = "/usr/lib/jvm/java-1.8-openjdk/jre/lib/sound.properties"
}
volumes {
host_path = "/mnt/xwing/config/airsonic/data"
container_path = "/config"
}
volumes {
host_path = "/mnt/xwing/media/Music"
container_path = "/music"
}
volumes {
host_path = "/mnt/xwing/config/airsonic/playlists"
container_path = "/playlists"
}
volumes {
host_path = "/mnt/xwing/config/airsonic/podcasts"
container_path = "/podcasts"
}
labels {
"traefik.enable" = "true"
"traefik.port" = "4040"
"traefik.frontend.rule" = "Host:airsonic.in.${var.domain},airsonic.${var.domain}"
"traefik.frontend.passHostHeader" = "true"
}
# lounge:tatooine
env = [
"PUID=1004",
"PGID=1003",
"TZ=Asia/Kolkata",
"JAVA_OPTS=-Xmx512m",
]
links = ["${var.links-mariadb}"]
}
resource "docker_image" "airsonic" {
name = "${data.docker_registry_image.airsonic.name}"
pull_triggers = ["${data.docker_registry_image.airsonic.sha256_digest}"]
}
data "docker_registry_image" "airsonic" {
name = "linuxserver/airsonic:latest"
}
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}"
}
}
# 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",
# # ]
# # 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}"
# }
# }

View File

@ -33,9 +33,3 @@ SmtpPort=465
SmtpUser=airsonic@captnemo.in
SmtpFrom=airsonic@captnemo.in
SmtpPassword=${smtp-password}
DatabaseConfigType=embed
DatabaseConfigEmbedDriver=org.hsqldb.jdbcDriver
DatabaseConfigEmbedUrl=jdbc:mysql://mariadb:3306/airsonic
DatabaseConfigEmbedUsername=airsonic
DatabaseConfigEmbedPassword=${db-password}

View File

@ -10,17 +10,17 @@
"bind-address-ipv6": "::",
"blocklist-enabled": true,
"blocklist-url": "http://john.bitsurge.net/public/biglist.p2p.gz",
"cache-size-mb": 16,
"cache-size-mb": 256,
"dht-enabled": true,
"download-dir": "/downloads",
"download-queue-enabled": true,
"download-queue-enabled": false,
"download-queue-size": 5,
"encryption": 1,
"idle-seeding-limit": 30,
"idle-seeding-limit-enabled": false,
"incomplete-dir": "/downloads",
"incomplete-dir-enabled": true,
"lpd-enabled": false,
"lpd-enabled": true,
"message-level": 2,
"peer-congestion-algorithm": "",
"peer-id-ttl-hours": 6,
@ -31,13 +31,13 @@
"peer-port-random-low": 49152,
"peer-port-random-on-start": false,
"peer-socket-tos": "default",
"pex-enabled": true,
"pex-enabled": false,
"port-forwarding-enabled": true,
"preallocation": 1,
"prefetch-enabled": true,
"queue-stalled-enabled": true,
"queue-stalled-enabled": false,
"queue-stalled-minutes": 30,
"ratio-limit": 0.2,
"ratio-limit": 1.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": true,
"scrape-paused-torrents-enabled": false,
"script-torrent-done-enabled": false,
"script-torrent-done-filename": "",
"seed-queue-enabled": false,
"seed-queue-size": 10,
"seed-queue-enabled": true,
"seed-queue-size": 50,
"speed-limit-down": 100,
"speed-limit-down-enabled": false,
"speed-limit-up": 50,
"speed-limit-up-enabled": true,
"speed-limit-up-enabled": false,
"start-added-torrents": true,
"trash-original-torrent-files": false,
"umask": 2,
"upload-slots-per-torrent": 14,
"upload-slots-per-torrent": 10,
"utp-enabled": true,
"watch-dir": "/watch",
"watch-dir-enabled": true

View File

@ -1,34 +0,0 @@
data "docker_registry_image" "daapd" {
name = "linuxserver/daapd:latest"
}
resource "docker_image" "daapd" {
name = "${data.docker_registry_image.daapd.name}"
pull_triggers = ["${data.docker_registry_image.daapd.sha256_digest}"]
}
resource "docker_container" "daapd" {
name = "daapd"
image = "${docker_image.daapd.latest}"
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
network_mode = "host"
volumes {
host_path = "/mnt/xwing/config/daapd"
container_path = "/config"
}
volumes {
host_path = "/mnt/xwing/media/Music"
container_path = "/music"
}
env = [
"PUID=1004",
"PGID=1003",
"TZ=Asia/Kolkata",
]
}

4
media/data.tf Normal file
View File

@ -0,0 +1,4 @@
data "docker_network" "bridge" {
name = "bridge"
}

74
media/emby.tf Normal file
View File

@ -0,0 +1,74 @@
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
# SSD holds both the cache and data
volumes {
host_path = "/mnt/zwing/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
}
}
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"
]
}
resource "docker_image" "emby" {
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"
}

View File

@ -1,29 +1,26 @@
data "docker_registry_image" "jackett" {
name = "linuxserver/jackett:latest"
}
module "jackett" {
name = "jackett"
source = "../modules/container"
image = "linuxserver/jackett:latest"
# TODO FIXME
# networks = [data.docker_network.bridge.id]
resource "docker_image" "jackett" {
name = "${data.docker_registry_image.jackett.name}"
pull_triggers = ["${data.docker_registry_image.jackett.sha256_digest}"]
}
web = {
expose = true
port = 9117
host = "jackett.${var.domain}"
}
resource docker_container "jackett" {
name = "jackett"
image = "${docker_image.jackett.latest}"
volumes = [
{
host_path = "/mnt/xwing/config/jackett"
container_path = "/config"
},
]
labels = "${merge(
var.traefik-labels, map(
"traefik.port", 9117,
"traefik.frontend.rule","Host:jackett.${var.domain}"
))}"
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
volumes {
host_path = "/mnt/xwing/config/jackett"
container_path = "/config"
resource = {
memory = "256"
memory_swap = "512"
}
env = [
@ -31,6 +28,5 @@ resource docker_container "jackett" {
"PGID=1003",
"TZ=Asia/Kolkata",
]
# links = ["${var.links-emby}"]
}

View File

@ -3,19 +3,29 @@ 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}"]
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.latest}"
locals {
lidarr_labels = merge(var.traefik-labels, {
"traefik.port" = 8686
"traefik.frontend.rule" = "Host:lidarr.${var.domain}"
})
}
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
}
}
labels = "${merge(
var.traefik-labels, map(
"traefik.port", 8686,
"traefik.frontend.rule","Host:falcon.${var.domain}"
))}"
memory = 512
restart = "unless-stopped"
@ -43,5 +53,6 @@ resource docker_container "lidarr" {
"TZ=Asia/Kolkata",
]
links = ["${var.links-emby}", "${var.links-transmission}"]
networks = [docker_network.media.id, var.traefik-network-id]
}

50
media/navidrome.tf Normal file
View File

@ -0,0 +1,50 @@
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
},
]
}

9
media/network.tf Normal file
View File

@ -0,0 +1,9 @@
resource "docker_network" "media" {
name = "media"
driver = "bridge"
ipam_config {
subnet = "172.18.0.0/24"
gateway = "172.18.0.1"
}
}

8
media/outputs.tf Normal file
View File

@ -0,0 +1,8 @@
output "names-transmission" {
value = docker_container.transmission.name
}
output "names-emby" {
value = docker_container.emby.name
}

19
media/providers.tf Normal file
View File

@ -0,0 +1,19 @@
terraform {
required_providers {
pass = {
source = "camptocamp/pass"
}
digitalocean = {
source = "digitalocean/digitalocean"
}
postgresql = {
source = "cyrilgdn/postgresql"
}
cloudflare = {
source = "cloudflare/cloudflare"
}
docker = {
source = "kreuzwerker/docker"
}
}
}

33
media/prowlarr.tf Normal file
View File

@ -0,0 +1,33 @@
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]
}

View File

@ -1,48 +1,45 @@
data "docker_registry_image" "radarr" {
name = "linuxserver/radarr:latest"
}
module "radarr" {
name = "radarr"
source = "../modules/container"
image = "linuxserver/radarr:latest"
resource "docker_image" "radarr" {
name = "${data.docker_registry_image.radarr.name}"
pull_triggers = ["${data.docker_registry_image.radarr.sha256_digest}"]
}
networks = [docker_network.media.id, data.docker_network.bridge.id]
resource docker_container "radarr" {
name = "radarr"
image = "${docker_image.radarr.latest}"
# TODO: wildcard certs needed!
labels = "${merge(
var.traefik-labels, map(
"traefik.port", 7878,
"traefik.frontend.rule","Host:radarr.${var.domain}"
))}"
memory = 512
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
volumes {
host_path = "/mnt/xwing/config/radarr"
container_path = "/config"
web = {
expose = true
port = 7878
host = "radarr.${var.domain}"
}
volumes {
host_path = "/mnt/xwing/media/DL"
container_path = "/downloads"
resource = {
memory = 512
memory_swap = 1024
}
volumes {
host_path = "/mnt/xwing/media/Movies"
container_path = "/movies"
}
volumes = [
{
host_path = "/mnt/zwing/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"
},
{
host_path = "/mnt/xwing/media/Movies"
container_path = "/movies"
},
]
env = [
"PUID=1004",
"PGID=1003",
"TZ=Asia/Kolkata",
]
links = ["${var.links-emby}", "${var.links-transmission}"]
}

26
media/requestrr.tf Normal file
View File

@ -0,0 +1,26 @@
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]
}

View File

@ -1,41 +1,38 @@
data "docker_registry_image" "sonarr" {
name = "linuxserver/sonarr:latest"
}
module "sonarr-container" {
name = "sonarr"
source = "../modules/container"
image = "linuxserver/sonarr:latest"
resource "docker_image" "sonarr" {
name = "${data.docker_registry_image.sonarr.name}"
pull_triggers = ["${data.docker_registry_image.sonarr.sha256_digest}"]
}
resource docker_container "sonarr" {
name = "sonarr"
image = "${docker_image.sonarr.latest}"
labels = "${merge(
var.traefik-labels, map(
"traefik.port", 8989,
"traefik.frontend.rule","Host:sonarr.${var.domain}"
))}"
memory = 512
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
volumes {
host_path = "/mnt/xwing/config/sonarr"
container_path = "/config"
web = {
expose = true
port = 8989
host = "sonarr.${var.domain}"
}
volumes {
host_path = "/mnt/xwing/media/DL"
container_path = "/downloads"
resource = {
memory = 512
memory_swap = 1024
}
volumes {
host_path = "/mnt/xwing/media/TV"
container_path = "/tv"
}
volumes = [
{
host_path = "/mnt/zwing/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"
},
{
host_path = "/mnt/xwing/media/TV"
container_path = "/tv"
},
]
env = [
"PUID=1004",
@ -43,5 +40,6 @@ resource docker_container "sonarr" {
"TZ=Asia/Kolkata",
]
links = ["${var.links-emby}", "${var.links-transmission}"]
networks = [docker_network.media.id, data.docker_network.bridge.id]
}

74
media/transmission.tf Normal file
View File

@ -0,0 +1,74 @@
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
dynamic "labels" {
for_each = local.transmission_labels
content {
label = labels.key
value = labels.value
}
}
ports {
internal = 51413
external = 51413
ip = var.ips["eth0"]
protocol = "udp"
}
volumes {
host_path = "/mnt/xwing/config/transmission"
container_path = "/config"
}
volumes {
host_path = "/mnt/xwing/media/DL"
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")
file = "/config/settings.json"
}
env = [
"PGID=1003",
"PUID=1000",
"TZ=Asia/Kolkata",
]
networks = [docker_network.media.id, var.traefik-network-id]
memory = 1024
restart = "unless-stopped"
destroy_grace_seconds = 10
must_run = true
}
resource "docker_image" "transmission" {
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"
}

View File

@ -1,13 +1,42 @@
variable "domain" {
type = "string"
type = string
}
variable "links-emby" {}
variable "links-transmission" {}
variable "links-mariadb" {}
variable "airsonic-smtp-password" {}
variable "airsonic-db-password" {}
# variable "airsonic-smtp-password" {}
variable "traefik-labels" {
type = "map"
type = map(string)
}
// TODO: Remove duplication
variable "basic_auth" {
default = "tatooine:$2y$05$iPbatint3Gulbs6kUtyALO9Yq5sBJ..aiF82bcIziH4ytz9nFoPr6,reddit:$2y$05$ghKxSydYCpAT8r2VVMDmWO/BBecghGfLsRJUkr3ii7XxPyxBqp8Oy"
}
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
}

30
miniflux.tf Normal file
View File

@ -0,0 +1,30 @@
module "miniflux-container" {
name = "miniflux"
source = "./modules/container"
image = "miniflux/miniflux:2.0.50"
web = {
expose = true
port = 8080
host = "rss.captnemo.in"
}
networks = ["bridge", "postgres"]
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"
name = "miniflux"
password = data.pass_password.miniflux-db-password.password
}

View File

@ -0,0 +1,9 @@
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
}

View File

@ -0,0 +1,49 @@
locals {
default_labels = {
"managed.by" = "nebula"
}
web = {
"traefik.port" = var.web.port != null ? var.web.port : 80
"traefik.frontend.rule" = var.web.host != null ? "Host:${var.web.host}" : "Host:example.invalid"
"traefik.protocol" = var.web.protocol != null ? var.web.protocol : "http"
}
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.contentTypeNosniff" = "true"
"traefik.frontend.headers.browserXSSFilter" = "true"
"traefik.docker.network" = "traefik"
}
# if var.web.auth == true
traefik_auth_labels = {
"traefik.frontend.auth.basic" = var.auth_header
}
resource = {
memory = lookup(var.resource, "memory", 64)
memory_swap = lookup(var.resource, "memory_swap", 128)
}
labels = merge(
# Default labels are applied to every container
local.default_labels,
# Add the common traefik labels
var.web.expose ? local.traefik_common_labels : null,
# Apply the overwritten web labels only if the container is exposed
var.web.expose ? local.web : null,
# And finally a label for Basic Authentication if the service wants it
var.web.auth != null ? (var.web.auth ? local.traefik_auth_labels : null) : null,
var.labels,
)
networks = concat(var.networks, var.web.expose ? ["traefik"] : [])
}

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