ConfigLMM 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/CNAME +1 -0
  4. data/Examples/.lmm.state.yaml +159 -0
  5. data/Examples/ConfigLMM.mm.yaml +32 -0
  6. data/Examples/Implemented.mm.yaml +252 -4
  7. data/Examples/SmallBusiness.mm.yaml +492 -0
  8. data/Plugins/Apps/Answer/answer.lmm.rb +165 -0
  9. data/Plugins/Apps/Answer/answer@.service +40 -0
  10. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb +0 -3
  11. data/Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb +0 -1
  12. data/Plugins/Apps/Authentik/Authentik-ProxyOutpost.container +7 -1
  13. data/Plugins/Apps/Authentik/Authentik-Server.container +6 -1
  14. data/Plugins/Apps/Authentik/Authentik-Worker.container +6 -1
  15. data/Plugins/Apps/Authentik/Authentik.conf.erb +12 -7
  16. data/Plugins/Apps/Authentik/Authentik.lmm.rb +226 -61
  17. data/Plugins/Apps/BookStack/BookStack.conf.erb +0 -3
  18. data/Plugins/Apps/BookStack/BookStack.container +5 -0
  19. data/Plugins/Apps/BookStack/BookStack.lmm.rb +14 -3
  20. data/Plugins/Apps/Cassandra/Cassandra.lmm.rb +9 -19
  21. data/Plugins/Apps/ClickHouse/ClickHouse.container +28 -0
  22. data/Plugins/Apps/ClickHouse/ClickHouse.lmm.rb +113 -0
  23. data/Plugins/Apps/ClickHouse/Config/listen.yaml +2 -0
  24. data/Plugins/Apps/ClickHouse/Config/logger.yaml +8 -0
  25. data/Plugins/Apps/ClickHouse/Config/zookeepers.yaml +5 -0
  26. data/Plugins/Apps/ClickHouse/Connection.rb +96 -0
  27. data/Plugins/Apps/Discourse/Discourse-Sidekiq.container +5 -0
  28. data/Plugins/Apps/Discourse/Discourse.conf.erb +1 -4
  29. data/Plugins/Apps/Discourse/Discourse.container +4 -0
  30. data/Plugins/Apps/Discourse/Discourse.lmm.rb +116 -55
  31. data/Plugins/Apps/Dovecot/Dovecot.lmm.rb +74 -62
  32. data/Plugins/Apps/ERPNext/ERPNext-Frontend.container +6 -1
  33. data/Plugins/Apps/ERPNext/ERPNext-Queue.container +5 -0
  34. data/Plugins/Apps/ERPNext/ERPNext-Scheduler.container +5 -0
  35. data/Plugins/Apps/ERPNext/ERPNext-Websocket.container +6 -1
  36. data/Plugins/Apps/ERPNext/ERPNext.container +6 -1
  37. data/Plugins/Apps/ERPNext/ERPNext.lmm.rb +138 -127
  38. data/Plugins/Apps/GitLab/GitLab.container +6 -0
  39. data/Plugins/Apps/GitLab/GitLab.lmm.rb +43 -49
  40. data/Plugins/Apps/Homepage/Homepage.conf.erb +86 -0
  41. data/Plugins/Apps/Homepage/Homepage.container +19 -0
  42. data/Plugins/Apps/Homepage/Homepage.lmm.rb +54 -0
  43. data/Plugins/Apps/IPFS/IPFS.conf.erb +0 -3
  44. data/Plugins/Apps/IPFS/IPFS.lmm.rb +0 -1
  45. data/Plugins/Apps/InfluxDB/InfluxDB.conf.erb +0 -3
  46. data/Plugins/Apps/InfluxDB/InfluxDB.lmm.rb +0 -1
  47. data/Plugins/Apps/Jackett/Jackett.conf.erb +0 -3
  48. data/Plugins/Apps/Jackett/Jackett.lmm.rb +0 -1
  49. data/Plugins/Apps/Jellyfin/Jellyfin.conf.erb +0 -3
  50. data/Plugins/Apps/Jellyfin/Jellyfin.lmm.rb +0 -1
  51. data/Plugins/Apps/LetsEncrypt/LetsEncrypt.lmm.rb +49 -28
  52. data/Plugins/Apps/LibreTranslate/LibreTranslate.container +21 -0
  53. data/Plugins/Apps/LibreTranslate/LibreTranslate.lmm.rb +34 -0
  54. data/Plugins/Apps/Lobsters/Containerfile +81 -0
  55. data/Plugins/Apps/Lobsters/Lobsters-Tasks.container +26 -0
  56. data/Plugins/Apps/Lobsters/Lobsters.conf.erb +99 -0
  57. data/Plugins/Apps/Lobsters/Lobsters.container +27 -0
  58. data/Plugins/Apps/Lobsters/Lobsters.lmm.rb +196 -0
  59. data/Plugins/Apps/Lobsters/crontab +3 -0
  60. data/Plugins/Apps/Lobsters/database.yml +26 -0
  61. data/Plugins/Apps/Lobsters/entrypoint.sh +30 -0
  62. data/Plugins/Apps/Lobsters/generateCredentials.rb +19 -0
  63. data/Plugins/Apps/Lobsters/lobsters-cron.sh +25 -0
  64. data/Plugins/Apps/Lobsters/lobsters-daily.sh +23 -0
  65. data/Plugins/Apps/Lobsters/puma.rb +49 -0
  66. data/Plugins/Apps/MariaDB/Connection.rb +55 -0
  67. data/Plugins/Apps/MariaDB/MariaDB.lmm.rb +60 -53
  68. data/Plugins/Apps/Mastodon/Mastodon-Sidekiq.container +22 -0
  69. data/Plugins/Apps/Mastodon/Mastodon-Streaming.container +20 -0
  70. data/Plugins/Apps/Mastodon/Mastodon.conf.erb +34 -45
  71. data/Plugins/Apps/Mastodon/Mastodon.container +28 -0
  72. data/Plugins/Apps/Mastodon/Mastodon.lmm.rb +240 -5
  73. data/Plugins/Apps/Mastodon/configlmm.rake +30 -0
  74. data/Plugins/Apps/Mastodon/entrypoint.sh +16 -0
  75. data/Plugins/Apps/Matrix/Element.container +5 -0
  76. data/Plugins/Apps/Matrix/Matrix.conf.erb +2 -8
  77. data/Plugins/Apps/Matrix/Matrix.lmm.rb +100 -71
  78. data/Plugins/Apps/Matrix/Synapse.container +5 -0
  79. data/Plugins/Apps/Netdata/Netdata.conf.erb +0 -3
  80. data/Plugins/Apps/Netdata/Netdata.lmm.rb +0 -1
  81. data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +3 -4
  82. data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +150 -68
  83. data/Plugins/Apps/Nextcloud/autoconfig.php +13 -0
  84. data/Plugins/Apps/Nextcloud/config.php +10 -1
  85. data/Plugins/Apps/Nextcloud/nextcloudcron.service +8 -0
  86. data/Plugins/Apps/Nextcloud/nextcloudcron.timer +10 -0
  87. data/Plugins/Apps/Nginx/Connection.rb +93 -0
  88. data/Plugins/Apps/Nginx/conf.d/configlmm.conf +50 -9
  89. data/Plugins/Apps/Nginx/conf.d/languages.conf +21 -0
  90. data/Plugins/Apps/Nginx/config-lmm/errors.conf +25 -20
  91. data/Plugins/Apps/Nginx/config-lmm/gateway-errors.conf +20 -0
  92. data/Plugins/Apps/Nginx/config-lmm/proxy.conf +1 -1
  93. data/Plugins/Apps/Nginx/main.conf.erb +7 -3
  94. data/Plugins/Apps/Nginx/nginx.conf +2 -2
  95. data/Plugins/Apps/Nginx/nginx.lmm.rb +99 -81
  96. data/Plugins/Apps/Nginx/proxy.conf.erb +11 -3
  97. data/Plugins/Apps/Odoo/Odoo.conf.erb +0 -3
  98. data/Plugins/Apps/Odoo/Odoo.container +5 -0
  99. data/Plugins/Apps/Odoo/Odoo.lmm.rb +4 -5
  100. data/Plugins/Apps/Ollama/Ollama.container +26 -0
  101. data/Plugins/Apps/Ollama/Ollama.lmm.rb +73 -0
  102. data/Plugins/Apps/OpenTelemetry/Config/config.yaml +704 -0
  103. data/Plugins/Apps/OpenTelemetry/OpenTelemetry.lmm.rb +154 -0
  104. data/Plugins/Apps/OpenVidu/Ingress.container +5 -0
  105. data/Plugins/Apps/OpenVidu/OpenVidu.conf.erb +0 -3
  106. data/Plugins/Apps/OpenVidu/OpenVidu.container +5 -0
  107. data/Plugins/Apps/OpenVidu/OpenVidu.lmm.rb +7 -3
  108. data/Plugins/Apps/OpenVidu/OpenViduCall.conf.erb +0 -3
  109. data/Plugins/Apps/OpenVidu/OpenViduCall.container +5 -0
  110. data/Plugins/Apps/PHP-FPM/Connection.rb +91 -0
  111. data/Plugins/Apps/PHP-FPM/PHP-FPM.lmm.rb +31 -4
  112. data/Plugins/Apps/Peppermint/Peppermint.conf.erb +2 -5
  113. data/Plugins/Apps/Peppermint/Peppermint.container +5 -0
  114. data/Plugins/Apps/Peppermint/Peppermint.lmm.rb +29 -33
  115. data/Plugins/Apps/Perplexica/Perplexica.container +25 -0
  116. data/Plugins/Apps/Perplexica/Perplexica.lmm.rb +92 -0
  117. data/Plugins/Apps/Perplexica/config.toml +26 -0
  118. data/Plugins/Apps/Podman/Connection.rb +24 -0
  119. data/Plugins/Apps/Podman/Podman.lmm.rb +80 -0
  120. data/Plugins/Apps/Podman/storage.conf +6 -0
  121. data/Plugins/Apps/Postfix/Postfix.lmm.rb +242 -164
  122. data/Plugins/Apps/PostgreSQL/Connection.rb +97 -0
  123. data/Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb +184 -148
  124. data/Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb +0 -3
  125. data/Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb +0 -2
  126. data/Plugins/Apps/Pterodactyl/Wings.conf.erb +0 -3
  127. data/Plugins/Apps/RVM/RVM.lmm.rb +57 -0
  128. data/Plugins/Apps/Roundcube/Roundcube.conf.erb +0 -3
  129. data/Plugins/Apps/Roundcube/Roundcube.lmm.rb +15 -19
  130. data/Plugins/Apps/SSH/SSH.lmm.rb +9 -15
  131. data/Plugins/Apps/SearXNG/SearXNG.container +22 -0
  132. data/Plugins/Apps/SearXNG/SearXNG.lmm.rb +79 -0
  133. data/Plugins/Apps/SearXNG/limiter.toml +40 -0
  134. data/Plugins/Apps/SearXNG/settings.yml +2 -0
  135. data/Plugins/Apps/SigNoz/Config/alerts.yml +11 -0
  136. data/Plugins/Apps/SigNoz/Config/otel-collector-config.yaml +110 -0
  137. data/Plugins/Apps/SigNoz/Config/otel-collector-opamp-config.yaml +1 -0
  138. data/Plugins/Apps/SigNoz/Config/prometheus.yml +18 -0
  139. data/Plugins/Apps/SigNoz/SigNoz-Collector.container +23 -0
  140. data/Plugins/Apps/SigNoz/SigNoz-Migrator.container +17 -0
  141. data/Plugins/Apps/SigNoz/SigNoz.conf.erb +61 -0
  142. data/Plugins/Apps/SigNoz/SigNoz.container +26 -0
  143. data/Plugins/Apps/SigNoz/SigNoz.lmm.rb +319 -0
  144. data/Plugins/Apps/Solr/log4j2.xml +89 -0
  145. data/Plugins/Apps/Solr/solr.lmm.rb +82 -0
  146. data/Plugins/Apps/Sunshine/Sunshine.conf.erb +0 -3
  147. data/Plugins/Apps/Sunshine/Sunshine.lmm.rb +0 -1
  148. data/Plugins/Apps/Tunnel/tunnel.lmm.rb +33 -37
  149. data/Plugins/Apps/UVdesk/UVdesk.conf.erb +0 -3
  150. data/Plugins/Apps/Umami/Umami.container +19 -0
  151. data/Plugins/Apps/Umami/Umami.lmm.rb +108 -0
  152. data/Plugins/Apps/Valkey/Valkey.lmm.rb +54 -42
  153. data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +9 -6
  154. data/Plugins/Apps/Vaultwarden/Vaultwarden.container +7 -1
  155. data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +64 -29
  156. data/Plugins/Apps/Wiki.js/Wiki.js.conf.erb +1 -4
  157. data/Plugins/Apps/Wiki.js/Wiki.js.container +5 -0
  158. data/Plugins/Apps/Wiki.js/Wiki.js.lmm.rb +31 -37
  159. data/Plugins/Apps/YaCy/YaCy.conf.erb +93 -0
  160. data/Plugins/Apps/YaCy/YaCy.container +21 -0
  161. data/Plugins/Apps/YaCy/YaCy.lmm.rb +160 -0
  162. data/Plugins/Apps/ZooKeeper/ZooKeeper.container +24 -0
  163. data/Plugins/Apps/ZooKeeper/ZooKeeper.lmm.rb +68 -0
  164. data/Plugins/Apps/bitmagnet/bitmagnet.conf.erb +0 -3
  165. data/Plugins/Apps/bitmagnet/bitmagnet.lmm.rb +0 -1
  166. data/Plugins/Apps/gollum/gollum.conf.erb +2 -4
  167. data/Plugins/Apps/gollum/gollum.container +6 -0
  168. data/Plugins/Apps/gollum/gollum.lmm.rb +51 -50
  169. data/Plugins/Apps/llama.cpp/llama.cpp.container +28 -0
  170. data/Plugins/Apps/llama.cpp/llama.cpp.lmm.rb +90 -0
  171. data/Plugins/Apps/vLLM/vLLM.container +32 -0
  172. data/Plugins/Apps/vLLM/vLLM.lmm.rb +89 -0
  173. data/Plugins/OS/General/Utils.lmm.rb +26 -0
  174. data/Plugins/OS/Linux/Connection.rb +472 -0
  175. data/Plugins/OS/Linux/Debian/preseed.cfg.erb +25 -6
  176. data/Plugins/OS/Linux/Flavours.yaml +13 -0
  177. data/Plugins/OS/Linux/Grub/grub.cfg +10 -0
  178. data/Plugins/OS/Linux/HTTP.rb +32 -0
  179. data/Plugins/OS/Linux/Linux.lmm.rb +533 -187
  180. data/Plugins/OS/Linux/Packages.yaml +20 -1
  181. data/Plugins/OS/Linux/Services.yaml +8 -0
  182. data/Plugins/OS/Linux/Shell.rb +70 -0
  183. data/Plugins/OS/Linux/Syslinux/default +8 -0
  184. data/Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb +83 -59
  185. data/Plugins/OS/Linux/WireGuard/wg0.conf.erb +3 -0
  186. data/Plugins/OS/Linux/openSUSE/autoinst.xml.erb +29 -3
  187. data/Plugins/OS/Linux/systemd/systemd.lmm.rb +13 -11
  188. data/Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb +6 -5
  189. data/Plugins/Platforms/GitHub.lmm.rb +73 -28
  190. data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +9 -6
  191. data/Plugins/Platforms/Proxmox/Proxmox.lmm.rb +402 -0
  192. data/Plugins/Platforms/Proxmox/XTerm.rb +321 -0
  193. data/Plugins/Platforms/libvirt/libvirt.lmm.rb +38 -13
  194. data/Plugins/Platforms/porkbun.lmm.rb +12 -2
  195. data/Plugins/Platforms/porkbun_spec.rb +2 -2
  196. data/Plugins/Services/DNS/AmberBit.lmm.rb +1 -1
  197. data/Plugins/Services/DNS/ArubaItDNS.lmm.rb +1 -1
  198. data/Plugins/Services/DNS/NICLV.lmm.rb +1 -1
  199. data/Plugins/Services/DNS/PowerDNS.lmm.rb +70 -68
  200. data/Plugins/Services/DNS/tonic.lmm.rb +22 -12
  201. data/lib/ConfigLMM/Framework/plugins/dns.rb +4 -3
  202. data/lib/ConfigLMM/Framework/plugins/linuxApp.rb +145 -184
  203. data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +34 -17
  204. data/lib/ConfigLMM/Framework/plugins/plugin.rb +53 -181
  205. data/lib/ConfigLMM/Framework/plugins/store.rb +4 -4
  206. data/lib/ConfigLMM/Framework/variables.rb +75 -0
  207. data/lib/ConfigLMM/Framework.rb +1 -0
  208. data/lib/ConfigLMM/cli.rb +12 -6
  209. data/lib/ConfigLMM/commands/configsCommand.rb +37 -6
  210. data/lib/ConfigLMM/commands/diff.rb +33 -9
  211. data/lib/ConfigLMM/context.rb +22 -3
  212. data/lib/ConfigLMM/io/configList.rb +82 -6
  213. data/lib/ConfigLMM/io/connection.rb +143 -0
  214. data/lib/ConfigLMM/io/dhcp.rb +330 -0
  215. data/lib/ConfigLMM/io/http.rb +78 -0
  216. data/lib/ConfigLMM/io/local.rb +207 -0
  217. data/lib/ConfigLMM/io/pxe.rb +92 -0
  218. data/lib/ConfigLMM/io/ssh.rb +156 -0
  219. data/lib/ConfigLMM/io/tftp.rb +105 -0
  220. data/lib/ConfigLMM/io.rb +2 -0
  221. data/lib/ConfigLMM/secrets/envStore.rb +39 -0
  222. data/lib/ConfigLMM/secrets/fileStore.rb +43 -0
  223. data/lib/ConfigLMM/state.rb +2 -1
  224. data/lib/ConfigLMM/version.rb +2 -1
  225. data/lib/ConfigLMM.rb +1 -0
  226. data/{Examples → scripts}/configlmmAuth.sh +7 -5
  227. metadata +205 -8
@@ -0,0 +1,196 @@
1
+
2
+
3
+ module ConfigLMM
4
+ module LMM
5
+ class Lobsters < Framework::Plugin
6
+
7
+ USER = 'lobsters'
8
+ HOME_DIR = '/var/lib/lobsters'
9
+ GIT_REPO = 'https://github.com/lobsters/lobsters.git'
10
+ IMAGE_ID = 'ConfigLM.moe/lobsters:master'
11
+
12
+ def actionLobstersBuild(id, target, activeState, context, options)
13
+ buildContainer(id, target, options)
14
+ end
15
+
16
+ def buildContainer(id, target, options)
17
+ raise Framework::PluginProcessError.new('Domain field must be set!') unless target['Domain']
18
+ Linux.withConnection(local) do |localLinux|
19
+ begin
20
+ localLinux.ensurePackages(['git', 'Podman'], options) unless localLinux.hasBinaries?(['git', 'podman'], options)
21
+ rescue RuntimeError => error
22
+ prompt.say(error, :color => :red)
23
+ end
24
+ lobstersDir = File.expand_path(REPOS_CACHE + '/lobsters')
25
+ if !File.exist?(lobstersDir)
26
+ localLinux.createDirs(options, File.expand_path(REPOS_CACHE))
27
+ gitRepo = GIT_REPO
28
+ gitRepo = target['Repository'] if target['Repository']
29
+ localLinux.exec("cd #{REPOS_CACHE} && git clone --quiet #{gitRepo} lobsters", false, options)
30
+ else
31
+ localLinux.exec("cd #{lobstersDir} && git checkout . --quiet && git pull --quiet", false, options)
32
+ end
33
+ localLinux.exec("cd #{lobstersDir} && git checkout . --quiet", false, options)
34
+
35
+ if !IO::Connection.cmdSuccess?("podman image exists #{IMAGE_ID}")
36
+ # if you see error like "newuidmap 5227 0 1000 1 1 100000 65536: newuidmap: write to uid_map failed: Operation not permitted"
37
+ # then for LXC you need to set idmap like:
38
+ # LXC:
39
+ # - idmap: u 0 100000 165536
40
+ # - idmap: g 0 100000 165536
41
+ localLinux.upload(__dir__ + '/entrypoint.sh', lobstersDir, options)
42
+ localLinux.upload(__dir__ + '/Containerfile', lobstersDir, options)
43
+ localLinux.upload(__dir__ + '/crontab', lobstersDir, options)
44
+ localLinux.upload(__dir__ + '/puma.rb', lobstersDir + '/config/', options)
45
+ localLinux.upload(__dir__ + '/database.yml', lobstersDir + '/config/', options)
46
+ localLinux.upload(__dir__ + '/lobsters-cron.sh', lobstersDir + '/script/', options)
47
+ localLinux.upload(__dir__ + '/lobsters-daily.sh', lobstersDir + '/script/', options)
48
+ localLinux.upload(__dir__ + '/generateCredentials.rb', lobstersDir + '/script/', options)
49
+
50
+ localLinux.exec("cd #{lobstersDir} && git rev-parse HEAD > id.txt", false, options)
51
+
52
+ localLinux.exec("sed -i 's|lobste\\.rs|#{target['Domain']}|' #{lobstersDir}/config/application.rb #{lobstersDir}/config/sitemap.rb #{lobstersDir}/public/opensearch.xml", false, options)
53
+ localLinux.exec("sed -i 's|lobste\\.rs|#{target['Domain']}|' #{lobstersDir}/app/models/comment.rb #{lobstersDir}/app/controllers/keybase_proofs_controller.rb", false, options)
54
+
55
+ localLinux.exec("sed -i 's|email: \"inactive-user@example.com\"|email: \"inactive-user@#{target['Domain']}\"|' #{lobstersDir}/db/seeds.rb", false, options)
56
+
57
+ if target['Admin'].to_h['Username']
58
+ localLinux.exec("sed -i 's|username: \"test\"|username: \"#{target['Admin']['Username']}\"|' #{lobstersDir}/db/seeds.rb", false, options)
59
+ end
60
+
61
+ if target['Admin'].to_h['EMail']
62
+ localLinux.exec("sed -i 's|email: \"test@example.com\"|email: \"#{target['Admin']['EMail']}\"|' #{lobstersDir}/db/seeds.rb", false, options)
63
+ end
64
+
65
+ adminPassword = SecureRandom.alphanumeric(20)
66
+ localLinux.exec(" sed -i 's|password: \"test\"|password: \"#{adminPassword}\"|' #{lobstersDir}/db/seeds.rb", false, { **options, hide: true })
67
+ localLinux.exec(" sed -i 's|password_confirmation: \"test\"|password_confirmation: \"#{adminPassword}\"|' #{lobstersDir}/db/seeds.rb", false, { **options, hide: true })
68
+
69
+ #localLinux.fileReplace("#{REPOS_CACHE}/lobsters/Dockerfile.dev", 'COPY Gemfile.*', 'COPY . ./', options)
70
+ rubyVersion = localLinux.fileRead("#{REPOS_CACHE}/lobsters/.ruby-version", options).strip
71
+ localLinux.exec("cd #{REPOS_CACHE}/lobsters && podman build --tag=#{IMAGE_ID} --build-arg RUBY_VERSION=#{rubyVersion} --file Containerfile .", false, options)
72
+ end
73
+ end
74
+ end
75
+
76
+ def actionLobstersDeploy(id, target, activeState, context, options)
77
+ raise Framework::PluginProcessError.new('Domain field must be set!') unless target['Domain']
78
+
79
+ target['Database'] ||= {}
80
+ self.withConnection(target['Location'], target) do |connection|
81
+ Linux.withConnection(connection) do |linuxConnection|
82
+
83
+ dbPassword = self.configureMariaDB(target['Database'], activeState, linuxConnection, options)
84
+
85
+ Podman.ensurePresent(linuxConnection, options)
86
+ Podman.createUser(USER, HOME_DIR, 'Lobsters', linuxConnection, options)
87
+
88
+ cmd = IO::SSH.cmd(target['Location'])
89
+ local.exec("podman image save #{IMAGE_ID} | #{cmd} 'cat > #{HOME_DIR}/lobsters.tar'", false, options)
90
+
91
+ linuxConnection.withUserShell(USER) do |shell|
92
+ shell.createDirs(options, '~/config', '~/logs', '~/cache', '~/storage', '~/queue', '~/tmp')
93
+ Podman.loadImage(shell, 'lobsters.tar', options)
94
+ end
95
+
96
+ linuxConnection.exec("rm -f #{HOME_DIR}/lobsters.tar", false, options)
97
+
98
+ linuxConnection.createDirs(options, '/srv/lobsters')
99
+ linuxConnection.setUserGroup('/srv/lobsters', USER, USER, options)
100
+
101
+ path = Podman.containersPath(HOME_DIR)
102
+
103
+ linuxConnection.fileWrite(path + '/Lobsters.env', 'RAILS_ENV=production', options)
104
+ if target['SMTP'] && target['SMTP']['Host']
105
+ linuxConnection.fileAppend(path + '/Lobsters.env', 'SMTP_HOST=' + target['SMTP']['Host'], options)
106
+ if target['SMTP']['Port']
107
+ linuxConnection.fileAppend(path + '/Lobsters.env', 'SMTP_PORT=' + target['SMTP']['Port'].to_s, options)
108
+ end
109
+ if target['SMTP']['Username']
110
+ linuxConnection.fileAppend(path + '/Lobsters.env', 'SMTP_USERNAME=' + target['SMTP']['Username'], options)
111
+ end
112
+ if target['SMTP']['SecretId']
113
+ smtpPassword = context.secrets.load(target['SMTP']['SecretId'], target['SMTP']['Username'].upcase + '_PASSWORD')
114
+ linuxConnection.fileAppend(path + '/Lobsters.env', 'SMTP_PASSWORD=' + smtpPassword.to_s, { **options, hide: true })
115
+ end
116
+ if target['SMTP']['TLS'] || target['SMTP']['Port'].to_s == '465'
117
+ linuxConnection.fileAppend(path + '/Lobsters.env', 'SMTP_TLS=true', options)
118
+ end
119
+ else
120
+ linuxConnection.fileAppend(path + '/Lobsters.env', 'SMTP_HOST=10.0.2.2', options)
121
+ end
122
+ linuxConnection.fileAppend(path + '/Lobsters.env', 'SMTP_STARTTLS_AUTO=true', options)
123
+
124
+ linuxConnection.exec("chown #{USER}:#{USER} #{path}/Lobsters.env", false, options)
125
+ linuxConnection.exec("chmod 600 #{path}/Lobsters.env", false, options)
126
+
127
+ linuxConnection.upload(__dir__ + '/database.yml', HOME_DIR + '/config/', options)
128
+
129
+ if target['Database'] && target['Database']['HostName'] && target['Database']['HostName'] != 'localhost'
130
+ linuxConnection.fileReplace(HOME_DIR + '/config/database.yml', '10.0.2.2', target['Database']['HostName'], options)
131
+ end
132
+ linuxConnection.exec("sed -i 's|password:.*|password: #{dbPassword}|' #{HOME_DIR}/config/database.yml", false, options)
133
+
134
+ linuxConnection.upload(__dir__ + '/Lobsters.container', path, options)
135
+ linuxConnection.upload(__dir__ + '/Lobsters-Tasks.container', path, options)
136
+
137
+ linuxConnection.reloadUserServices(USER, options)
138
+ linuxConnection.restartUserService(USER, 'Lobsters', options)
139
+ linuxConnection.restartUserService(USER, 'Lobsters-Tasks', options)
140
+
141
+ Nginx.withConnection(linuxConnection) do |nginxConnection|
142
+ nginxConnection.writeConfig(__dir__, 'Lobsters', target, state, context, options)
143
+ nginxConnection.deployAllConfigs(target, activeState, context, options)
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ def configureMariaDB(settings, activeState, linuxConnection, options)
150
+ password = SecureRandom.alphanumeric(20)
151
+ MariaDB.withConnection(settings, linuxConnection) do |mariaConnection|
152
+ mariaConnection.createUserAndDB(USER, password, nil, options)
153
+ end
154
+ password
155
+ end
156
+
157
+ def cleanup(configs, state, context, options)
158
+ cleanupType(:Lobsters, configs, state, context, options) do |item, id, state, context, options, connection|
159
+ Linux.withConnection(connection) do |linuxConnection|
160
+
161
+ Nginx.withConnection(linuxConnection) do |nginxConnection|
162
+ nginxConnection.cleanupConfig('Lobsters', context, options)
163
+ nginxConnection.reload(options)
164
+ end
165
+
166
+ linuxConnection.stopUserService(USER, 'Lobsters-Tasks', options)
167
+ linuxConnection.stopUserService(USER, 'Lobsters', options)
168
+
169
+ path = Podman.containersPath(HOME_DIR)
170
+ linuxConnection.rm(path + 'Lobsters.container', options[:dry])
171
+ linuxConnection.rm(path + 'Lobsters-Tasks.container', options[:dry])
172
+ linuxConnection.rm('/srv/lobsters', options[:dry])
173
+
174
+ linuxConnection.withUserShell(USER) do |shell|
175
+ Podman.removeImage(shell, IMAGE_ID, options)
176
+ end
177
+
178
+ state.item(id)['Status'] = State::STATUS_DELETED unless options[:dry]
179
+
180
+ if options[:destroy]
181
+ item['Config']['Database'] ||= {}
182
+ MariaDB.withConnection(item['Config']['Database'], linuxConnection) do |connectionDB|
183
+ connectionDB.dropDB(USER, options)
184
+ end
185
+ linuxConnection.deleteUserAndGroup(USER, options)
186
+ linuxConnection.rm(HOME_DIR, options[:dry])
187
+
188
+ state.item(id)['Status'] = State::STATUS_DESTROYED unless options[:dry]
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,3 @@
1
+ */5 * * * * /srv/lobste.rs/http/script/lobsters-cron.sh
2
+ 0 0 * * * /srv/lobste.rs/http/script/lobsters-daily.sh
3
+ * * * * * /srv/lobste.rs/http/script/expire_page_cache
@@ -0,0 +1,26 @@
1
+ ---
2
+ trilogy: &trilogy
3
+ adapter: trilogy
4
+ encoding: utf8mb4
5
+ host: 10.0.2.2
6
+ port: 3306
7
+ pool: 5
8
+
9
+ sqlite3: &sqlite3
10
+ adapter: sqlite3
11
+ timeout: 5000
12
+
13
+ production:
14
+ primary:
15
+ <<: *trilogy
16
+ database: lobsters
17
+ username: lobsters
18
+ password:
19
+ cache:
20
+ <<: *sqlite3
21
+ database: /srv/lobste.rs/cache/cache.sqlite3
22
+ migrations_paths: db/cache_migrate
23
+ queue:
24
+ <<: *sqlite3
25
+ database: /srv/lobste.rs/queue/queue.sqlite3
26
+ migrations_paths: db/queue_migrate
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/sh
2
+
3
+ set -o errexit
4
+ set -o nounset
5
+
6
+ cmd="/lobsters/bin/rails"
7
+
8
+ if [ $# -gt 0 ]; then
9
+ if [ "$1" = "cron" ]; then
10
+ shift
11
+ cmd="/usr/local/bin/supercronic /etc/crontab"
12
+ elif [ "$1" = "server" ]; then
13
+ status=0
14
+ cmp --quiet "/lobsters/id.txt" "/srv/lobsters/id.txt" || status=$?
15
+ if [ $status -ne 0 ]; then
16
+ rm -rf /srv/lobsters/*
17
+ mkdir -p /srv/lobsters/public
18
+ cp -R /lobsters/public_source/* /srv/lobsters/public/
19
+ cp -R /lobsters/public_source/.* /srv/lobsters/public/
20
+ cp "/lobsters/id.txt" "/srv/lobsters/"
21
+ fi
22
+
23
+ if [ ! -f "/config/credentials.yml.enc" ]; then
24
+ bundle exec /lobsters/script/generateCredentials.rb
25
+ fi
26
+ /lobsters/bin/rails db:prepare
27
+ fi
28
+ fi
29
+
30
+ exec $cmd "$@"
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/rails/encryption_key_file/encryption_key_file_generator'
5
+ require 'rails/generators/rails/credentials/credentials_generator'
6
+
7
+ content_path = '/config/credentials.yml.enc'
8
+ key_path = '/config/master.key'
9
+
10
+ Rails::Generators::EncryptionKeyFileGenerator.new([], quiet: true).add_key_file(key_path)
11
+
12
+ Rails::Generators::CredentialsGenerator.new(
13
+ [content_path, key_path],
14
+ skip_secret_key_base: false,
15
+ quiet: true
16
+ ).invoke_all
17
+
18
+ # TODO
19
+ # should apply config/credentials.yml.enc.sample to config
@@ -0,0 +1,25 @@
1
+ #!/bin/bash
2
+
3
+ err=0
4
+ report() {
5
+ err=1
6
+ echo -n "error at line ${BASH_LINENO[0]}, in call to "
7
+ sed -n ${BASH_LINENO[0]}p $0
8
+ } >&2
9
+ trap report ERR
10
+
11
+ cd /srv/lobste.rs/http
12
+
13
+ if [ -f public/maintenance.html ];
14
+ then
15
+ exit 0
16
+ fi
17
+
18
+ bundle exec ruby script/fill_flagged_cache.rb &
19
+ bundle exec ruby script/mail_new_activity.rb &
20
+ #bundle exec ruby script/mastodon_post.rb &
21
+ #bundle exec ruby script/mastodon_sync_users.rb &
22
+ #bundle exec ruby script/send_new_webmentions &
23
+ bundle exec ruby script/traffic_range &
24
+
25
+ exit $err
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+
3
+ err=0
4
+ report() {
5
+ err=1
6
+ echo -n "error at line ${BASH_LINENO[0]}, in call to "
7
+ sed -n ${BASH_LINENO[0]}p $0
8
+ } >&2
9
+ trap report ERR
10
+
11
+ cd /srv/lobste.rs/http
12
+
13
+ if [ -f public/maintenance.html ];
14
+ then
15
+ exit 0
16
+ fi
17
+
18
+ bundle exec rails daily_maintenance
19
+ bundle exec rails sitemap:refresh -s
20
+
21
+ find /srv/lobste.rs/http/tmp -type f -name 'rack%3A%3Aattack*' -mtime +2 -delete
22
+
23
+ exit $err
@@ -0,0 +1,49 @@
1
+ # typed: false
2
+
3
+ require "etc"
4
+
5
+ # Puma can serve each request in a thread from an internal thread pool.
6
+ # The `threads` method setting takes two numbers: a minimum and maximum.
7
+ # Any libraries that use thread pools should be configured to match
8
+ # the maximum value specified for Puma. Default is set to 5 threads for minimum
9
+ # and maximum; this matches the default thread size of Active Record.
10
+ #
11
+ threads_count = ENV.fetch("RAILS_MAX_THREADS") { 4 }
12
+ threads threads_count, threads_count
13
+
14
+ # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
15
+ # port ENV.fetch("PORT") { 3000 }
16
+ # bind 'tcp://127.0.0.1:3000'
17
+
18
+ # Specifies the `environment` that Puma will run in.
19
+ environment ENV.fetch("RAILS_ENV") { "development" }
20
+
21
+ # Specifies the `pidfile` that Puma will use.
22
+ #pidfile ENV.fetch("PIDFILE") {
23
+ # "tmp/puma.pid"
24
+ #}
25
+
26
+ # Specifies the number of `workers` to boot in clustered mode.
27
+ # Workers are forked webserver processes. If using threads and workers together
28
+ # the concurrency of the application would be max `threads` * `workers`.
29
+ # Workers do not work on JRuby or Windows (both of which do not support
30
+ # processes).
31
+ workers ENV.fetch("PUMA_WORKERS") { 3 }
32
+
33
+ # Use the `preload_app!` method when specifying a `workers` number.
34
+ # This directive tells Puma to first boot the application and load code
35
+ # before forking the application. This takes advantage of Copy On Write
36
+ # process behavior so workers use less memory.
37
+ if ENV.fetch("RAILS_ENV") == "production"
38
+
39
+ # phased restarts
40
+ # https://github.com/puma/puma/blob/master/docs/restart.md
41
+ prune_bundler
42
+
43
+ # old hot restart config; will need ansible change to tell systemctl to restart instead of reload
44
+ # preload_app!
45
+ end
46
+
47
+ # Allow puma to be restarted by `rails restart` command.
48
+ plugin :tmp_restart
49
+
@@ -0,0 +1,55 @@
1
+
2
+ module ConfigLMM
3
+ module LMM
4
+ class MariaDBConnection
5
+
6
+ attr_reader :connection
7
+
8
+ def initialize(connection, settings)
9
+ @connection = connection
10
+ @settings = settings
11
+ end
12
+
13
+ def exec(sql, db = nil, allowFailure = false, options = {})
14
+ cmd = "mariadb #{db ? db.shellescape : ''} --execute=#{sql.shellescape}"
15
+ @connection.exec(cmd, allowFailure, options)
16
+ end
17
+
18
+ def createUserAndDB(user, password, host = nil, options = {})
19
+ if host.nil?
20
+ if @settings['HostName'] == 'localhost'
21
+ host = 'localhost'
22
+ else
23
+ host = '%'
24
+ end
25
+ end
26
+ self.exec("CREATE USER '#{user}'@'#{host}'", nil, true, options)
27
+ self.exec("ALTER USER '#{user}'@'#{host}' IDENTIFIED BY '#{password}'", nil, false, { **options, hide: true })
28
+ self.exec("CREATE DATABASE #{user}", nil, true, options)
29
+ self.exec("GRANT ALL PRIVILEGES ON #{user}.* TO '#{user}'@'#{host}'", nil, false, options)
30
+ end
31
+
32
+ def dropDB(db, options = {})
33
+ self.exec("DROP DATABASE #{db}", nil, true, options)
34
+ end
35
+
36
+ def createAdmin(options = {})
37
+ self.exec("CREATE USER 'admin'@'%'", nil, true, options)
38
+ password = SecureRandom.alphanumeric(20)
39
+ self.exec("ALTER USER 'admin'@'%' IDENTIFIED BY '#{password}'", nil, false, { **options, hide: true })
40
+ self.exec("GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION", nil, false, options)
41
+ password
42
+ end
43
+
44
+ def dropAdmin(options = {})
45
+ self.exec("DROP USER 'admin'@'%'", nil, true, options)
46
+ end
47
+
48
+ def tableExist?(db, table, options = {})
49
+ table = self.exec("SHOW TABLES LIKE '#{table}'", db, false, options).strip
50
+ !table.empty?
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -1,49 +1,46 @@
1
1
  require_relative '../../OS/Linux/Linux.lmm.rb'
2
+ require_relative 'Connection'
2
3
 
3
4
  module ConfigLMM
4
5
  module LMM
5
6
  class MariaDB < Framework::LinuxApp
6
7
  PACKAGE_NAME = 'MariaDB'
7
- SERVICE_NAME = 'mariadb'
8
+ SERVICE_NAME = :mariadb
8
9
  USER_NAME = 'mariadb'
9
10
 
10
11
  def actionMariaDBDeploy(id, target, activeState, context, options)
11
- self.ensurePackage(PACKAGE_NAME, target['Location'])
12
- self.ensureServiceAutoStart(SERVICE_NAME, target['Location'])
13
- self.startService(SERVICE_NAME, target['Location'])
14
-
15
- if target['Location'] && target['Location'] != '@me'
16
- uri = Addressable::URI.parse(target['Location'])
17
- raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
18
-
19
- self.class.sshStart(uri) do |ssh|
20
- self.class.secureInstallation(ssh)
12
+ self.withConnection(target['Location'], target) do |connection|
13
+ Linux.withConnection(connection) do |linuxConnection|
14
+ linuxConnection.ensurePackage(PACKAGE_NAME, options)
15
+ linuxConnection.ensureServiceAutoStart(SERVICE_NAME, options)
16
+ linuxConnection.startService(SERVICE_NAME, options)
17
+
18
+ self.class.secureInstallation(connection)
19
+ linuxConnection.exec("sed -i 's|^log-error |#log-error |' /etc/my.cnf", false, options)
21
20
  if target['Listen']
22
- self.class.exec("sed -i 's|bind-address .*|bind-address = #{target['Listen']}|' /etc/my.cnf", ssh)
23
- self.class.restartService(SERVICE_NAME, ssh)
21
+ linuxConnection.exec("sed -i 's|bind-address .*|bind-address = #{target['Listen']}|' /etc/my.cnf", false, options)
22
+ linuxConnection.restartService(SERVICE_NAME, options)
24
23
  end
25
24
  end
26
- else
27
- # TODO
28
25
  end
29
-
30
- activeState['Status'] = State::STATUS_DEPLOYED
31
26
  end
32
27
 
33
28
  def cleanup(configs, state, context, options)
34
- cleanupType(:MariaDB, configs, state, context, options) do |item, id, state, context, options, ssh|
35
- Framework::LinuxApp.stopService(SERVICE_NAME, ssh, options[:dry])
36
- Framework::LinuxApp.disableService(SERVICE_NAME, ssh, options[:dry])
37
- Framework::LinuxApp.removePackage(PACKAGE_NAME, ssh, options[:dry])
38
-
29
+ cleanupType(:MariaDB, configs, state, context, options) do |item, id, state, context, options, connection|
30
+ Linux.withConnection(connection) do |linuxConnection|
31
+ linuxConnection.stopService(SERVICE_NAME, options)
32
+ linuxConnection.disableService(SERVICE_NAME, options)
33
+ linuxConnection.removePackage(PACKAGE_NAME, options)
34
+ end
39
35
  state.item(id)['Status'] = State::STATUS_DELETED unless options[:dry]
40
36
  end
41
37
  end
42
38
 
43
- def self.secureInstallation(ssh)
39
+ def self.secureInstallation(connection)
44
40
  status = {}
45
41
  output = ''
46
- channel = ssh.exec("mariadb-secure-installation", status: status) do |channel, stream, data|
42
+ # TODO: FIXME to work with non-ssh connection aswell
43
+ channel = connection.tunnel.ssh.exec("mariadb-secure-installation", status: status) do |channel, stream, data|
47
44
  output += data
48
45
  channel.send_data("\n") # Empty root password
49
46
  channel.send_data("Y\n") # unix_socket authentication
@@ -60,53 +57,63 @@ module ConfigLMM
60
57
  end
61
58
  end
62
59
 
60
+ # DEPRECATED
63
61
  def self.createRemoteUserAndDB(settings, user, password, ssh = nil)
64
- self.executeRemotely(settings, ssh) do |ssh|
62
+ self.executeRemotely(settings, ssh) do |connection|
65
63
  host = 'localhost'
66
64
  host = '%' if settings['HostName'] != 'localhost'
67
- self.createUserAndDB(user, password, host, ssh)
65
+ self.createUserAndDB(user, password, host, connection)
66
+ end
67
+ end
68
+
69
+ def self.withConnection(settings, linuxConnection)
70
+ if settings['HostName'].nil? || settings['HostName'] == 'localhost'
71
+ settings['HostName'] = 'localhost'
72
+ yield(MariaDBConnection.new(linuxConnection, settings))
73
+ else
74
+ IO::Connection.tunnel("ssh://#{settings['HostName']}/", {}, {}, linuxConnection.prompt, linuxConnection.logger) do |connection|
75
+ yield(MariaDBConnection.new(connection, settings))
76
+ end
68
77
  end
69
78
  end
70
79
 
71
- def self.executeRemotely(settings, ssh = nil)
80
+ # DEPRECATED
81
+ def self.executeRemotely(settings, connectionOrSSH = nil)
82
+ prompt = TTY::Prompt.new
83
+ logger = TTY::Logger.new
72
84
  settings['HostName'] = 'localhost' unless settings['HostName']
73
85
  if settings['HostName'] == 'localhost'
74
- yield(ssh)
86
+ connection = connectionOrSSH
87
+ if connectionOrSSH.nil?
88
+ connection = IO::Connection.new(:Local, IO::Local.new(prompt, logger), prompt, logger)
89
+ elsif !connectionOrSSH.is_a?(IO::Connection)
90
+ connection = IO::Connection.new(:SSH, SSH.new(prompt, logger, connectionOrSSH), prompt, logger)
91
+ end
92
+ yield(connection)
75
93
  else
76
94
  self.sshStart("ssh://#{settings['HostName']}/") do |ssh|
77
- yield(ssh)
95
+ yield(IO::Connection.new(:SSH, SSH.new(prompt, logger, ssh), prompt, logger))
78
96
  end
79
97
  end
80
98
  end
81
99
 
82
- def self.createUserAndDB(user, password, host, ssh = nil)
83
- self.executeSQL("CREATE USER '#{user}'@'#{host}'", nil, ssh, true)
84
- self.executeSQL("ALTER USER '#{user}'@'#{host}' IDENTIFIED BY '#{password}'", nil, ssh)
85
- self.executeSQL("CREATE DATABASE #{user}", nil, ssh, true)
86
- self.executeSQL("GRANT ALL PRIVILEGES ON #{user}.* TO '#{user}'@'#{host}'", nil, ssh)
87
- end
88
-
89
- def self.createAdmin(ssh)
90
- self.executeSQL("CREATE USER 'admin'@'%'", nil, ssh, true)
91
- password = SecureRandom.alphanumeric(20)
92
- self.executeSQL("ALTER USER 'admin'@'%' IDENTIFIED BY '#{password}'", nil, ssh)
93
- self.executeSQL("GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION", nil, ssh)
94
- password
95
- end
96
-
97
- def self.dropAdmin(ssh)
98
- self.executeSQL("DROP USER 'admin'@'%'", nil, ssh, true)
99
- end
100
-
101
- def self.tableExist?(db, table, ssh)
102
- table = self.executeSQL("SHOW TABLES LIKE '#{table}'", db, ssh).strip
103
- !table.empty?
100
+ # DEPRECATED
101
+ def self.createUserAndDB(user, password, host, connectionOrSSH = nil)
102
+ self.executeSQL("CREATE USER '#{user}'@'#{host}'", nil, connectionOrSSH, true)
103
+ self.executeSQL("ALTER USER '#{user}'@'#{host}' IDENTIFIED BY '#{password}'", nil, connectionOrSSH)
104
+ self.executeSQL("CREATE DATABASE #{user}", nil, connectionOrSSH, true)
105
+ self.executeSQL("GRANT ALL PRIVILEGES ON #{user}.* TO '#{user}'@'#{host}'", nil, connectionOrSSH)
104
106
  end
105
107
 
106
- def self.executeSQL(sql, db = nil, ssh = nil, allowFailure = false, dry = false)
108
+ # DEPRECATED
109
+ def self.executeSQL(sql, db = nil, connectionOrSSH = nil, allowFailure = false, dry = false)
107
110
  db = '' unless db
108
111
  cmd = " mariadb #{db} --execute=\"#{sql.gsub('"', '\\"')};\""
109
- self.exec(cmd, ssh, allowFailure, dry)
112
+ if connectionOrSSH.is_a?(IO::Connection)
113
+ connectionOrSSH.exec(cmd, allowFailure, dry)
114
+ else
115
+ self.exec(cmd, connectionOrSSH, allowFailure, dry)
116
+ end
110
117
  end
111
118
 
112
119
  end
@@ -0,0 +1,22 @@
1
+
2
+ [Unit]
3
+ Description=Mastodon Sidekiq container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ ContainerName=Mastodon-Sidekiq
8
+ Image=ghcr.io/mastodon/mastodon:latest
9
+ Exec=bundle exec sidekiq
10
+ EnvironmentFile=/var/lib/mastodon/.config/containers/systemd/Mastodon.env
11
+ Network=slirp4netns:allow_host_loopback=true
12
+ UserNS=keep-id:uid=991,gid=991
13
+ Volume=/var/lib/mastodon/system:/mastodon/public/system
14
+ LogDriver=journald
15
+ AutoUpdate=registry
16
+
17
+ [Service]
18
+ TimeoutStartSec=6min
19
+ Restart=on-failure
20
+
21
+ [Install]
22
+ WantedBy=multi-user.target default.target
@@ -0,0 +1,20 @@
1
+
2
+ [Unit]
3
+ Description=Mastodon Streaming container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ ContainerName=Mastodon-Streaming
8
+ Image=ghcr.io/mastodon/mastodon-streaming:latest
9
+ EnvironmentFile=/var/lib/mastodon/.config/containers/systemd/Mastodon.env
10
+ Network=slirp4netns:allow_host_loopback=true
11
+ PublishPort=127.0.0.1:14000:4000
12
+ LogDriver=journald
13
+ AutoUpdate=registry
14
+
15
+ [Service]
16
+ TimeoutStartSec=6min
17
+ Restart=on-failure
18
+
19
+ [Install]
20
+ WantedBy=multi-user.target default.target