@muhammedaksam/easiarr 1.4.0 → 1.4.1

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 (109) hide show
  1. package/dist/index.js +29837 -0
  2. package/package.json +15 -15
  3. package/src/VersionInfo.ts +0 -12
  4. package/src/api/arr-api.ts +0 -521
  5. package/src/api/auto-setup-types.ts +0 -64
  6. package/src/api/base-api.ts +0 -216
  7. package/src/api/bazarr-api.ts +0 -297
  8. package/src/api/cloudflare-api.ts +0 -493
  9. package/src/api/custom-format-api.ts +0 -224
  10. package/src/api/grafana-api.ts +0 -230
  11. package/src/api/heimdall-api.ts +0 -141
  12. package/src/api/homarr-api.ts +0 -209
  13. package/src/api/huntarr-api.ts +0 -457
  14. package/src/api/index.ts +0 -9
  15. package/src/api/jellyfin-api.ts +0 -389
  16. package/src/api/jellyseerr-api.ts +0 -559
  17. package/src/api/maintainerr-api.ts +0 -461
  18. package/src/api/naming-config.ts +0 -101
  19. package/src/api/overseerr-api.ts +0 -392
  20. package/src/api/plex-api.ts +0 -308
  21. package/src/api/portainer-api.ts +0 -374
  22. package/src/api/profilarr-api.ts +0 -391
  23. package/src/api/prowlarr-api.ts +0 -488
  24. package/src/api/qbittorrent-api.ts +0 -300
  25. package/src/api/quality-profile-api.ts +0 -272
  26. package/src/api/tautulli-api.ts +0 -244
  27. package/src/api/uptime-kuma-api.ts +0 -343
  28. package/src/apps/categories.ts +0 -14
  29. package/src/apps/index.ts +0 -2
  30. package/src/apps/registry.ts +0 -1275
  31. package/src/compose/caddy-config.ts +0 -130
  32. package/src/compose/generator.ts +0 -287
  33. package/src/compose/index.ts +0 -7
  34. package/src/compose/templates.ts +0 -78
  35. package/src/compose/traefik-config.ts +0 -187
  36. package/src/config/bookmarks-generator.ts +0 -160
  37. package/src/config/defaults.ts +0 -37
  38. package/src/config/homepage-config.ts +0 -381
  39. package/src/config/index.ts +0 -6
  40. package/src/config/manager.ts +0 -150
  41. package/src/config/recyclarr-config.ts +0 -181
  42. package/src/config/schema.ts +0 -310
  43. package/src/config/slskd-config.ts +0 -86
  44. package/src/config/soularr-config.ts +0 -105
  45. package/src/config/trash-quality-definitions.ts +0 -213
  46. package/src/data/lidarr-custom-formats.ts +0 -127
  47. package/src/data/trash-profiles.ts +0 -333
  48. package/src/docker/client.ts +0 -312
  49. package/src/docker/index.ts +0 -18
  50. package/src/index.ts +0 -77
  51. package/src/setup/actions/arr-common.ts +0 -307
  52. package/src/setup/actions/dashboards.ts +0 -79
  53. package/src/setup/actions/download-clients.ts +0 -54
  54. package/src/setup/actions/jellyseerr.ts +0 -331
  55. package/src/setup/actions/media-servers.ts +0 -68
  56. package/src/setup/actions/monitoring.ts +0 -120
  57. package/src/setup/actions/prowlarr.ts +0 -137
  58. package/src/setup/actions/utilities.ts +0 -490
  59. package/src/setup/index.ts +0 -78
  60. package/src/setup/types.ts +0 -144
  61. package/src/structure/manager.ts +0 -129
  62. package/src/ui/App.ts +0 -111
  63. package/src/ui/components/ApplicationSelector.ts +0 -275
  64. package/src/ui/components/CredentialsForm.ts +0 -180
  65. package/src/ui/components/DownloadClientForm.ts +0 -114
  66. package/src/ui/components/FileEditor.ts +0 -91
  67. package/src/ui/components/FooterHint.ts +0 -119
  68. package/src/ui/components/PageLayout.ts +0 -160
  69. package/src/ui/components/UpdateNotification.ts +0 -102
  70. package/src/ui/index.ts +0 -7
  71. package/src/ui/screens/AdvancedSettings.ts +0 -188
  72. package/src/ui/screens/ApiKeyViewer.ts +0 -511
  73. package/src/ui/screens/AppConfigurator.ts +0 -543
  74. package/src/ui/screens/AppManager.ts +0 -284
  75. package/src/ui/screens/ContainerControl.ts +0 -581
  76. package/src/ui/screens/LogsViewer.ts +0 -478
  77. package/src/ui/screens/MainMenu.ts +0 -299
  78. package/src/ui/screens/MonitorDashboard.ts +0 -881
  79. package/src/ui/screens/SecretsEditor.ts +0 -216
  80. package/src/ui/screens/SettingsScreen.ts +0 -633
  81. package/src/ui/screens/index.ts +0 -22
  82. package/src/ui/screens/setup/BaseAppSetupScreen.ts +0 -375
  83. package/src/ui/screens/setup/CloudflaredSetup.ts +0 -460
  84. package/src/ui/screens/setup/FullAutoSetup.ts +0 -766
  85. package/src/ui/screens/setup/HomepageSetup.ts +0 -165
  86. package/src/ui/screens/setup/JellyfinSetup.ts +0 -328
  87. package/src/ui/screens/setup/JellyseerrSetup.ts +0 -242
  88. package/src/ui/screens/setup/ProwlarrSetup.ts +0 -500
  89. package/src/ui/screens/setup/QBittorrentSetup.ts +0 -221
  90. package/src/ui/screens/setup/QuickSetup.ts +0 -1169
  91. package/src/ui/screens/setup/RecyclarrSetup.ts +0 -270
  92. package/src/ui/screens/setup/TRaSHProfileSetup.ts +0 -381
  93. package/src/utils/arch.ts +0 -78
  94. package/src/utils/browser.ts +0 -27
  95. package/src/utils/categories.ts +0 -61
  96. package/src/utils/debug.ts +0 -84
  97. package/src/utils/env.ts +0 -138
  98. package/src/utils/index.ts +0 -8
  99. package/src/utils/logs.ts +0 -119
  100. package/src/utils/migrations/1765626338_rename_env_variables.ts +0 -102
  101. package/src/utils/migrations/1765707135_rename_easiarr_status.ts +0 -91
  102. package/src/utils/migrations/1765732722_remove_cloudflare_dns_api_token.ts +0 -45
  103. package/src/utils/migrations/1769515650_migrate_to_xdg.ts +0 -114
  104. package/src/utils/migrations.ts +0 -165
  105. package/src/utils/password.ts +0 -42
  106. package/src/utils/paths.ts +0 -33
  107. package/src/utils/unraid.ts +0 -103
  108. package/src/utils/update-checker.ts +0 -210
  109. package/src/utils/url-utils.ts +0 -38
@@ -1,1275 +0,0 @@
1
- /**
2
- * App Registry
3
- * Definitions for all supported *arr ecosystem applications
4
- * Based on mediastack and TRaSH Guides configurations
5
- */
6
-
7
- import type { AppDefinition, AppId } from "~/config/schema"
8
- import { getArchWarning, getSystemArch, isAppCompatible, isAppDeprecated } from "~/utils/arch"
9
-
10
- export const APPS: Record<AppId, AppDefinition> = {
11
- // === SERVARR (Media Management) ===
12
- radarr: {
13
- id: "radarr",
14
- name: "Radarr",
15
- description: "Movie collection manager",
16
- category: "servarr",
17
- defaultPort: 7878,
18
- image: "lscr.io/linuxserver/radarr:latest",
19
- puid: 13002,
20
- pgid: 13000,
21
- volumes: (root) => [`${root}/config/radarr:/config`, `${root}/data:/data`],
22
-
23
- trashGuide: "docs/Radarr/",
24
- apiKeyMeta: {
25
- configFile: "config.xml",
26
- parser: "regex",
27
- selector: "<ApiKey>(.*?)</ApiKey>",
28
- },
29
- rootFolder: {
30
- path: "/data/media/movies",
31
- apiVersion: "v3",
32
- },
33
- prowlarrCategoryIds: [2000, 2010, 2020, 2030, 2040, 2045, 2050, 2060, 2070, 2080, 2090], // Movies + all sub-categories
34
- homepage: { icon: "radarr.png", widget: "radarr" },
35
- logVolume: "/config/logs",
36
- },
37
-
38
- sonarr: {
39
- id: "sonarr",
40
- name: "Sonarr",
41
- description: "TV series collection manager",
42
- category: "servarr",
43
- defaultPort: 8989,
44
- image: "lscr.io/linuxserver/sonarr:latest",
45
- puid: 13001,
46
- pgid: 13000,
47
- volumes: (root) => [`${root}/config/sonarr:/config`, `${root}/data:/data`],
48
-
49
- trashGuide: "docs/Sonarr/",
50
- apiKeyMeta: {
51
- configFile: "config.xml",
52
- parser: "regex",
53
- selector: "<ApiKey>(.*?)</ApiKey>",
54
- },
55
- rootFolder: {
56
- path: "/data/media/tv",
57
- apiVersion: "v3",
58
- },
59
- prowlarrCategoryIds: [5000, 5010, 5020, 5030, 5040, 5045, 5050, 5060, 5070, 5080, 5090], // TV + all sub-categories
60
- homepage: { icon: "sonarr.png", widget: "sonarr" },
61
- logVolume: "/config/logs",
62
- },
63
-
64
- lidarr: {
65
- id: "lidarr",
66
- name: "Lidarr",
67
- description: "Music collection manager",
68
- category: "servarr",
69
- defaultPort: 8686,
70
- image: "lscr.io/linuxserver/lidarr:latest",
71
- puid: 13003,
72
- pgid: 13000,
73
- volumes: (root) => [`${root}/config/lidarr:/config`, `${root}/data:/data`],
74
- apiKeyMeta: {
75
- configFile: "config.xml",
76
- parser: "regex",
77
- selector: "<ApiKey>(.*?)</ApiKey>",
78
- },
79
- rootFolder: {
80
- path: "/data/media/music",
81
- apiVersion: "v1",
82
- },
83
- prowlarrCategoryIds: [3000, 3010, 3020, 3030, 3040, 3050, 3060], // Audio + all sub-categories
84
- homepage: { icon: "lidarr.png", widget: "lidarr" },
85
- logVolume: "/config/logs",
86
- },
87
-
88
- readarr: {
89
- id: "readarr",
90
- name: "Readarr",
91
- description: "Book collection manager",
92
- category: "servarr",
93
- defaultPort: 8787,
94
- image: "lscr.io/linuxserver/readarr:develop",
95
- puid: 13004,
96
- pgid: 13000,
97
- volumes: (root) => [`${root}/config/readarr:/config`, `${root}/data:/data`],
98
- apiKeyMeta: {
99
- configFile: "config.xml",
100
- parser: "regex",
101
- selector: "<ApiKey>(.*?)</ApiKey>",
102
- },
103
- rootFolder: {
104
- path: "/data/media/books",
105
- apiVersion: "v1",
106
- },
107
- prowlarrCategoryIds: [7000, 7010, 7020, 7030, 7040, 7050, 7060], // Books + all sub-categories
108
- arch: {
109
- deprecated: ["arm64", "arm32"],
110
- warning: "Readarr is deprecated - no ARM64 support (project abandoned by upstream)",
111
- },
112
- homepage: { icon: "readarr.png", widget: "readarr" },
113
- logVolume: "/config/logs",
114
- },
115
-
116
- bazarr: {
117
- id: "bazarr",
118
- name: "Bazarr",
119
- description: "Subtitle manager for Sonarr/Radarr",
120
- category: "servarr",
121
- defaultPort: 6767,
122
- image: "lscr.io/linuxserver/bazarr:latest",
123
- puid: 13013,
124
- pgid: 13000,
125
- // TRaSH: Bazarr only needs media access, use /data/media for consistent paths
126
- volumes: (root) => [`${root}/config/bazarr:/config`, `${root}/data/media:/data/media`],
127
- dependsOn: ["sonarr", "radarr"],
128
- trashGuide: "docs/Bazarr/",
129
- apiKeyMeta: {
130
- configFile: "config/config.yaml",
131
- parser: "yaml",
132
- selector: "auth.apikey",
133
- },
134
- homepage: { icon: "bazarr.png", widget: "bazarr" },
135
- logVolume: "/config/log",
136
- },
137
-
138
- mylar3: {
139
- id: "mylar3",
140
- name: "Mylar3",
141
- description: "Comic book collection manager",
142
- category: "servarr",
143
- defaultPort: 8090,
144
- image: "lscr.io/linuxserver/mylar3:latest",
145
- puid: 13005,
146
- pgid: 13000,
147
- volumes: (root) => [`${root}/config/mylar3:/config`, `${root}/data:/data`],
148
- apiKeyMeta: {
149
- configFile: "mylar/config.ini",
150
- parser: "ini",
151
- section: "API",
152
- selector: "api_key",
153
- enabledKey: "api_enabled",
154
- generateIfMissing: true,
155
- },
156
- prowlarrCategoryIds: [7030], // Comics
157
- homepage: { icon: "mylar.png", widget: "mylar" },
158
- logVolume: "/app/mylar/logs",
159
- // Note: Mylar3 is NOT an *arr app - has different API format (?cmd=<endpoint>)
160
- // Root folder is configured via Web UI settings, not API
161
- },
162
-
163
- whisparr: {
164
- id: "whisparr",
165
- name: "Whisparr",
166
- description: "Adult media collection manager",
167
- category: "servarr",
168
- defaultPort: 6969,
169
- image: "ghcr.io/hotio/whisparr:nightly",
170
- puid: 13015,
171
- pgid: 13000,
172
- volumes: (root) => [`${root}/config/whisparr:/config`, `${root}/data:/data`],
173
- apiKeyMeta: {
174
- configFile: "config.xml",
175
- parser: "regex",
176
- selector: "<ApiKey>(.*?)</ApiKey>",
177
- },
178
- rootFolder: {
179
- path: "/data/media/adult",
180
- apiVersion: "v3",
181
- },
182
- prowlarrCategoryIds: [6000, 6010, 6020, 6030, 6040, 6045, 6050, 6060, 6070, 6080, 6090], // XXX + all sub-categories
183
- homepage: { icon: "whisparr.png", widget: "sonarr" }, // Uses sonarr widget type
184
- logVolume: "/config/logs",
185
- },
186
-
187
- audiobookshelf: {
188
- id: "audiobookshelf",
189
- name: "Audiobookshelf",
190
- description: "Audiobook and podcast server",
191
- category: "servarr",
192
- defaultPort: 13378,
193
- image: "ghcr.io/advplyr/audiobookshelf:latest",
194
- puid: 13014,
195
- pgid: 13000,
196
- volumes: (root) => [
197
- `${root}/config/audiobookshelf:/config`,
198
- `${root}/data/media/audiobooks:/audiobooks`,
199
- `${root}/data/media/podcasts:/podcasts`,
200
- `${root}/data/media/audiobookshelf-metadata:/metadata`,
201
- ],
202
- homepage: { icon: "audiobookshelf.png", widget: "audiobookshelf" },
203
- logVolume: "/config/metadata/logs",
204
- },
205
-
206
- // === INDEXERS ===
207
- prowlarr: {
208
- id: "prowlarr",
209
- name: "Prowlarr",
210
- description: "Indexer manager for *arr apps",
211
- category: "indexer",
212
- defaultPort: 9696,
213
- image: "lscr.io/linuxserver/prowlarr:develop",
214
- puid: 13006,
215
- pgid: 13000,
216
- volumes: (root) => [`${root}/config/prowlarr:/config`],
217
-
218
- trashGuide: "docs/Prowlarr/",
219
- apiKeyMeta: {
220
- configFile: "config.xml",
221
- parser: "regex",
222
- selector: "<ApiKey>(.*?)</ApiKey>",
223
- },
224
- homepage: { icon: "prowlarr.png", widget: "prowlarr" },
225
- logVolume: "/config/logs",
226
- },
227
-
228
- jackett: {
229
- id: "jackett",
230
- name: "Jackett",
231
- description: "Alternative indexer manager",
232
- category: "indexer",
233
- defaultPort: 9117,
234
- image: "lscr.io/linuxserver/jackett:latest",
235
- puid: 13008,
236
- pgid: 13000,
237
- volumes: (root) => [`${root}/config/jackett:/config`],
238
- apiKeyMeta: {
239
- configFile: "Jackett/ServerConfig.json",
240
- parser: "json",
241
- selector: "APIKey",
242
- },
243
- homepage: { icon: "jackett.png", widget: "jackett" },
244
- logVolume: "/config/logs",
245
- },
246
-
247
- flaresolverr: {
248
- id: "flaresolverr",
249
- name: "FlareSolverr",
250
- description: "Cloudflare bypass proxy",
251
- category: "indexer",
252
- defaultPort: 8191,
253
- image: "ghcr.io/flaresolverr/flaresolverr:latest",
254
- puid: 0,
255
- pgid: 0,
256
- volumes: () => [],
257
- environment: {
258
- LOG_LEVEL: "info",
259
- LOG_HTML: "false",
260
- CAPTCHA_SOLVER: "none",
261
- },
262
- homepage: {
263
- icon: "flaresolverr.png",
264
- widget: "customapi",
265
- widgetFields: {
266
- url: "http://flaresolverr:8191",
267
- mappings: JSON.stringify([
268
- { field: "msg", label: "Status" },
269
- { field: "version", label: "Version" },
270
- ]),
271
- },
272
- },
273
- },
274
-
275
- // === DOWNLOAD CLIENTS ===
276
- qbittorrent: {
277
- id: "qbittorrent",
278
- name: "qBittorrent",
279
- description: "BitTorrent client",
280
- category: "downloader",
281
- defaultPort: 8080,
282
- image: "lscr.io/linuxserver/qbittorrent:latest",
283
- puid: 13007,
284
- pgid: 13000,
285
- // TRaSH: Mount full /data for consistent paths with *arr apps (enables hardlinks)
286
- volumes: (root) => [`${root}/config/qbittorrent:/config`, `${root}/data:/data`],
287
- environment: { WEBUI_PORT: "8080" },
288
- secrets: [
289
- {
290
- name: "USERNAME_QBITTORRENT",
291
- description: "Username for qBittorrent WebUI",
292
- required: false,
293
- default: "admin",
294
- },
295
- {
296
- name: "PASSWORD_QBITTORRENT",
297
- description: "Password for qBittorrent WebUI",
298
- required: false,
299
- mask: true,
300
- },
301
- ],
302
- trashGuide: "docs/Downloaders/qBittorrent/",
303
- homepage: { icon: "qbittorrent.png", widget: "qbittorrent" },
304
- logVolume: "/config/qBittorrent/logs",
305
- },
306
-
307
- sabnzbd: {
308
- id: "sabnzbd",
309
- name: "SABnzbd",
310
- description: "Usenet downloader",
311
- category: "downloader",
312
- defaultPort: 8081,
313
- image: "lscr.io/linuxserver/sabnzbd:latest",
314
- puid: 13011,
315
- pgid: 13000,
316
- // TRaSH: Mount full /data for consistent paths with *arr apps (enables hardlinks)
317
- volumes: (root) => [`${root}/config/sabnzbd:/config`, `${root}/data:/data`],
318
-
319
- trashGuide: "docs/Downloaders/SABnzbd/",
320
- apiKeyMeta: {
321
- configFile: "sabnzbd.ini",
322
- parser: "regex",
323
- selector: "api_key\\s*=\\s*(.+)",
324
- },
325
- homepage: { icon: "sabnzbd.png", widget: "sabnzbd" },
326
- logVolume: "/config/logs",
327
- },
328
-
329
- slskd: {
330
- id: "slskd",
331
- name: "Slskd",
332
- description: "Soulseek client for music downloads",
333
- category: "downloader",
334
- defaultPort: 5030,
335
- image: "slskd/slskd",
336
- puid: 0, // Uses Docker user: directive instead
337
- pgid: 0,
338
- useDockerUser: true, // Use Docker's user: directive for file permissions
339
- volumes: (root) => [`${root}/config/slskd:/app`, `${root}/data:/data`],
340
- secondaryPorts: ["5031:5031", "50300:50300"],
341
- environment: {
342
- SLSKD_REMOTE_CONFIGURATION: "true",
343
- // Web UI authentication (use global credentials)
344
- SLSKD_USERNAME: "${USERNAME_GLOBAL}",
345
- SLSKD_PASSWORD: "${PASSWORD_GLOBAL}",
346
- // Soulseek network credentials (separate account)
347
- SLSKD_SLSK_USERNAME: "${USERNAME_SOULSEEK}",
348
- SLSKD_SLSK_PASSWORD: "${PASSWORD_SOULSEEK}",
349
- },
350
- secrets: [
351
- {
352
- name: "USERNAME_SOULSEEK",
353
- description: "Soulseek network username (your Soulseek account)",
354
- required: true,
355
- },
356
- {
357
- name: "PASSWORD_SOULSEEK",
358
- description: "Soulseek network password",
359
- required: true,
360
- mask: true,
361
- },
362
- ],
363
- homepage: { icon: "slskd.png", widget: "slskd" },
364
- autoSetup: {
365
- type: "partial",
366
- description: "Generates slskd.yml with API key for Homepage widget and Soularr integration",
367
- },
368
- logVolume: "/app/logs",
369
- },
370
-
371
- soularr: {
372
- id: "soularr",
373
- name: "Soularr",
374
- description: "Connects Lidarr with Soulseek via Slskd",
375
- category: "downloader",
376
- defaultPort: 0, // No web UI
377
- image: "mrusse08/soularr:latest",
378
- puid: 13017,
379
- pgid: 13000,
380
- volumes: (root) => [`${root}/data/slskd_downloads:/downloads`, `${root}/config/soularr:/data`],
381
- environment: {
382
- SCRIPT_INTERVAL: "300",
383
- },
384
- dependsOn: ["lidarr", "slskd"],
385
- },
386
-
387
- // === MEDIA SERVERS ===
388
- plex: {
389
- id: "plex",
390
- name: "Plex",
391
- description: "Media server with streaming",
392
- category: "mediaserver",
393
- defaultPort: 32400,
394
- image: "lscr.io/linuxserver/plex:latest",
395
- puid: 13010,
396
- pgid: 13000,
397
- // TRaSH: Media servers only need media access, use /data/media for consistent paths
398
- volumes: (root) => [`${root}/config/plex:/config`, `${root}/data/media:/data/media`],
399
- environment: { VERSION: "docker", PLEX_CLAIM: "${PLEX_CLAIM}" },
400
- trashGuide: "docs/Plex/",
401
- apiKeyMeta: {
402
- configFile: "Library/Application Support/Plex Media Server/Preferences.xml",
403
- parser: "regex",
404
- selector: 'PlexOnlineToken="([^"]+)"',
405
- },
406
- homepage: { icon: "plex.png", widget: "plex" },
407
- logVolume: "/config/Library/Application Support/Plex Media Server/Logs",
408
- autoSetup: {
409
- type: "full",
410
- description: "Claim server with token, create media libraries",
411
- envVars: ["PLEX_CLAIM"],
412
- },
413
- },
414
-
415
- jellyfin: {
416
- id: "jellyfin",
417
- name: "Jellyfin",
418
- description: "Free open-source media server",
419
- category: "mediaserver",
420
- defaultPort: 8096,
421
- image: "lscr.io/linuxserver/jellyfin:latest",
422
- puid: 0,
423
- pgid: 13000,
424
- volumes: (root) => [`${root}/config/jellyfin:/config`, `${root}/data/media:/data/media`],
425
- homepage: { icon: "jellyfin.png", widget: "jellyfin" },
426
- logVolume: "/config/log",
427
- },
428
-
429
- tautulli: {
430
- id: "tautulli",
431
- name: "Tautulli",
432
- description: "Plex monitoring and statistics",
433
- category: "mediaserver",
434
- defaultPort: 8181,
435
- image: "lscr.io/linuxserver/tautulli:latest",
436
- puid: 0,
437
- pgid: 13000,
438
- volumes: (root) => [`${root}/config/tautulli:/config`],
439
- dependsOn: ["plex"],
440
- apiKeyMeta: {
441
- configFile: "config.ini",
442
- parser: "regex",
443
- selector: "api_key\\s*=\\s*(.+)",
444
- },
445
- homepage: { icon: "tautulli.png", widget: "tautulli" },
446
- autoSetup: {
447
- type: "partial",
448
- description: "Connect to Plex, enable API",
449
- requires: ["plex"],
450
- },
451
- logVolume: "/config/logs",
452
- },
453
-
454
- tdarr: {
455
- id: "tdarr",
456
- name: "Tdarr",
457
- description: "Audio/video transcoding automation",
458
- category: "mediaserver",
459
- defaultPort: 8265,
460
- image: "ghcr.io/haveagitgat/tdarr:latest",
461
- puid: 0,
462
- pgid: 13000,
463
- volumes: (root) => [
464
- `${root}/config/tdarr/server:/app/server`,
465
- `${root}/config/tdarr/configs:/app/configs`,
466
- `${root}/config/tdarr/logs:/app/logs`,
467
- `${root}/data/media:/data`,
468
- ],
469
- environment: { serverIP: "0.0.0.0", internalNode: "true" },
470
- homepage: { icon: "tdarr.png", widget: "tdarr" },
471
- logVolume: "/app/logs",
472
- },
473
-
474
- // === REQUEST MANAGEMENT ===
475
- overseerr: {
476
- id: "overseerr",
477
- name: "Overseerr",
478
- description: "Request management for Plex",
479
- category: "request",
480
- defaultPort: 5055,
481
- image: "sctx/overseerr:latest",
482
- puid: 13009,
483
- pgid: 13000,
484
- volumes: (root) => [`${root}/config/overseerr:/app/config`],
485
- dependsOn: ["plex"],
486
- apiKeyMeta: {
487
- configFile: "settings.json",
488
- parser: "json",
489
- selector: "main.apiKey",
490
- },
491
- homepage: { icon: "overseerr.png", widget: "overseerr" },
492
- autoSetup: {
493
- type: "full",
494
- description: "Connect to Plex, configure Radarr/Sonarr",
495
- requires: ["plex"],
496
- },
497
- logVolume: "/app/config/logs",
498
- },
499
-
500
- jellyseerr: {
501
- id: "jellyseerr",
502
- name: "Jellyseerr",
503
- description: "Request management for Jellyfin",
504
- category: "request",
505
- defaultPort: 5055,
506
- image: "fallenbagel/jellyseerr:latest",
507
- puid: 13012,
508
- pgid: 13000,
509
- volumes: (root) => [`${root}/config/jellyseerr:/app/config`],
510
- dependsOn: ["jellyfin"],
511
- apiKeyMeta: {
512
- configFile: "settings.json",
513
- parser: "json",
514
- selector: "main.apiKey",
515
- },
516
- homepage: { icon: "jellyseerr.png", widget: "jellyseerr" },
517
- logVolume: "/app/config/logs",
518
- },
519
-
520
- // === DASHBOARDS ===
521
- homarr: {
522
- id: "homarr",
523
- name: "Homarr",
524
- description: "Modern dashboard for all services",
525
- category: "dashboard",
526
- defaultPort: 7575,
527
- image: "ghcr.io/ajnart/homarr:latest",
528
- puid: 0,
529
- pgid: 0,
530
- volumes: (root) => [
531
- `${root}/config/homarr/configs:/app/data/configs`,
532
- `${root}/config/homarr/icons:/app/public/icons`,
533
- `${root}/config/homarr/data:/data`,
534
- "/var/run/docker.sock:/var/run/docker.sock",
535
- ],
536
- homepage: { icon: "homarr.png" }, // No widget, just icon (it's a dashboard itself)
537
- logVolume: "/app/data/logs",
538
- },
539
-
540
- heimdall: {
541
- id: "heimdall",
542
- name: "Heimdall",
543
- description: "Application dashboard and launcher",
544
- category: "dashboard",
545
- defaultPort: 8082,
546
- image: "lscr.io/linuxserver/heimdall:latest",
547
- puid: 0,
548
- pgid: 13000,
549
- volumes: (root) => [`${root}/config/heimdall:/config`],
550
- homepage: { icon: "heimdall.png" }, // No widget, just icon (it's a dashboard itself)
551
- logVolume: "/config/log",
552
- },
553
-
554
- homepage: {
555
- id: "homepage",
556
- name: "Homepage",
557
- description: "Highly customizable application dashboard",
558
- category: "dashboard",
559
- defaultPort: 3009,
560
- internalPort: 3000,
561
- image: "ghcr.io/gethomepage/homepage:latest",
562
- puid: 0,
563
- pgid: 0,
564
- volumes: (root) => [
565
- `${root}/config/homepage:/app/config`,
566
- "/var/run/docker.sock:/var/run/docker.sock",
567
- ],
568
- environment: {
569
- HOMEPAGE_ALLOWED_HOSTS:
570
- "homepage,homepage.${CLOUDFLARE_DNS_ZONE},${CLOUDFLARE_DNS_ZONE},localhost,${LOCAL_DOCKER_IP},${LOCAL_DOCKER_IP}:3009",
571
- },
572
- logVolume: "/app/config/logs",
573
- },
574
-
575
- // === UTILITIES ===
576
- portainer: {
577
- id: "portainer",
578
- name: "Portainer",
579
- description: "Docker container management UI",
580
- category: "utility",
581
- defaultPort: 9000,
582
- image: "portainer/portainer-ce:latest",
583
- puid: 0,
584
- pgid: 0,
585
- volumes: (root) => [
586
- `${root}/config/portainer:/data`,
587
- "/var/run/docker.sock:/var/run/docker.sock",
588
- ],
589
- minPasswordLength: 12, // Portainer requires minimum 12 character password
590
- homepage: { icon: "portainer.png", widget: "portainer" },
591
- logVolume: "/data/logs",
592
- },
593
-
594
- huntarr: {
595
- id: "huntarr",
596
- name: "Huntarr",
597
- description: "Missing content manager for *arr apps",
598
- category: "utility",
599
- defaultPort: 9705,
600
- image: "huntarr/huntarr:latest",
601
- puid: 0,
602
- pgid: 13000,
603
- volumes: (root) => [`${root}/config/huntarr:/config`],
604
- dependsOn: ["sonarr", "radarr", "lidarr", "readarr"],
605
- homepage: {
606
- icon: "huntarr.png",
607
- widget: "customapi",
608
- widgetFields: {
609
- url: "http://huntarr:9705/api/cycle/status",
610
- mappings: JSON.stringify([
611
- { field: "sonarr.next_cycle", label: "Sonarr", format: "relativeDate" },
612
- { field: "radarr.next_cycle", label: "Radarr", format: "relativeDate" },
613
- { field: "lidarr.next_cycle", label: "Lidarr", format: "relativeDate" },
614
- { field: "readarr.next_cycle", label: "Readarr", format: "relativeDate" },
615
- { field: "whisparr.next_cycle", label: "Whisparr", format: "relativeDate" },
616
- ]),
617
- },
618
- },
619
- autoSetup: {
620
- type: "full",
621
- description: "Test connections to Sonarr, Radarr, Lidarr, Readarr, Whisparr",
622
- requires: ["sonarr", "radarr"],
623
- },
624
- logVolume: "/config/logs",
625
- },
626
-
627
- maintainerr: {
628
- id: "maintainerr",
629
- name: "Maintainerr",
630
- description: "Automated media management and cleanup for Plex",
631
- category: "utility",
632
- defaultPort: 6246,
633
- image: "ghcr.io/maintainerr/maintainerr:latest",
634
- puid: 0,
635
- pgid: 13000,
636
- volumes: (root) => [`${root}/config/maintainerr:/opt/data`],
637
- dependsOn: ["plex"],
638
- homepage: {
639
- icon: "maintainerr.png",
640
- widget: "customapi",
641
- widgetFields: {
642
- url: "http://maintainerr:6246/api/settings/version",
643
- mappings: JSON.stringify([{ field: "version", label: "Version" }]),
644
- },
645
- },
646
- autoSetup: {
647
- type: "full",
648
- description: "Generate API key, configure Plex/Radarr/Sonarr/Overseerr/Tautulli connections",
649
- requires: ["plex"],
650
- },
651
- logVolume: "/opt/data/logs",
652
- },
653
-
654
- unpackerr: {
655
- id: "unpackerr",
656
- name: "Unpackerr",
657
- description: "Archive extraction for *arr apps",
658
- category: "utility",
659
- defaultPort: 5656,
660
- image: "golift/unpackerr",
661
- puid: 0,
662
- pgid: 13000,
663
- volumes: (root) => [`${root}/config/unpackerr:/config`, `${root}/data:/data`],
664
- logVolume: "/config/logs",
665
- },
666
-
667
- filebot: {
668
- id: "filebot",
669
- name: "FileBot",
670
- description: "Media file renaming and automator",
671
- category: "utility",
672
- defaultPort: 5452,
673
- image: "rednoah/filebot",
674
- puid: 13000,
675
- pgid: 13000,
676
- volumes: (root) => [`${root}/config/filebot:/data`, `${root}/data:/data`],
677
- environment: { DARK_MODE: "1" },
678
- logVolume: "/data/logs",
679
- },
680
-
681
- chromium: {
682
- id: "chromium",
683
- name: "Chromium",
684
- description: "Web browser for secure remote browsing",
685
- category: "utility",
686
- defaultPort: 3000,
687
- image: "lscr.io/linuxserver/chromium:latest",
688
- puid: 13000,
689
- pgid: 13000,
690
- volumes: (root) => [`${root}/config/chromium:/config`],
691
- environment: { TITLE: "Chromium" },
692
- logVolume: "/config/logs",
693
- },
694
-
695
- guacamole: {
696
- id: "guacamole",
697
- name: "Guacamole",
698
- description: "Clientless remote desktop gateway",
699
- category: "utility",
700
- defaultPort: 8080,
701
- image: "guacamole/guacamole",
702
- puid: 0,
703
- pgid: 0,
704
- volumes: (root) => [`${root}/config/guacamole:/config`],
705
- environment: {
706
- WEBAPP_CONTEXT: "ROOT",
707
- GUACD_HOSTNAME: "guacd",
708
- POSTGRESQL_HOSTNAME: "postgresql",
709
- POSTGRESQL_DATABASE: "guacamole",
710
- POSTGRESQL_USER: "${USERNAME_POSTGRESQL}",
711
- POSTGRESQL_PASSWORD: "${PASSWORD_POSTGRESQL}",
712
- },
713
- dependsOn: ["guacd", "postgresql"],
714
- secrets: [
715
- {
716
- name: "USERNAME_POSTGRESQL",
717
- description: "PostgreSQL Username",
718
- required: true,
719
- default: "postgres",
720
- },
721
- {
722
- name: "PASSWORD_POSTGRESQL",
723
- description: "PostgreSQL Password",
724
- required: true,
725
- mask: true,
726
- },
727
- ],
728
- logVolume: "/guacamole/logs",
729
- },
730
-
731
- guacd: {
732
- id: "guacd",
733
- name: "Guacd",
734
- description: "Guacamole proxy daemon",
735
- category: "utility",
736
- defaultPort: 4822,
737
- image: "guacamole/guacd",
738
- puid: 0, // Guacd runs as restricted user inside, or PUID? MediaStack sets user: PUID:PGID
739
- pgid: 13000,
740
- volumes: (root) => [`${root}/config/guacd:/config`], // Not really used but keeps structure
741
- dependsOn: ["postgresql"],
742
- logVolume: "/guacd/logs",
743
- },
744
-
745
- "ddns-updater": {
746
- id: "ddns-updater",
747
- name: "DDNS-Updater",
748
- description: "Dynamic DNS record updater",
749
- category: "utility",
750
- defaultPort: 8000,
751
- image: "qmcgaw/ddns-updater",
752
- puid: 13000,
753
- pgid: 13000,
754
- volumes: (root) => [`${root}/config/ddns-updater:/data`],
755
- logVolume: "/data/logs",
756
- },
757
-
758
- easiarr: {
759
- id: "easiarr",
760
- name: "easiarr",
761
- description: "Exposes easiarr config and bookmarks for Homepage dashboard",
762
- category: "utility",
763
- defaultPort: 3010,
764
- internalPort: 8080,
765
- image: "halverneus/static-file-server:latest",
766
- puid: 0,
767
- pgid: 0,
768
- volumes: () => [
769
- "${XDG_CONFIG_HOME}/easiarr/config.json:/web/config.json:ro",
770
- "${XDG_CONFIG_HOME}/easiarr/bookmarks-local.html:/web/bookmarks-local.html:ro",
771
- "${XDG_CONFIG_HOME}/easiarr/bookmarks-remote.html:/web/bookmarks-remote.html:ro",
772
- ],
773
- environment: {
774
- FOLDER: "/web",
775
- CORS: "true",
776
- },
777
- homepage: {
778
- icon: "mdi-docker",
779
- widget: "customapi",
780
- widgetFields: {
781
- url: "http://easiarr:8080/config.json",
782
- mappings: JSON.stringify([
783
- { field: "version", label: "Version" },
784
- { field: "apps.length", label: "Apps" },
785
- ]),
786
- },
787
- },
788
- },
789
-
790
- recyclarr: {
791
- id: "recyclarr",
792
- name: "Recyclarr",
793
- description: "Automatic TRaSH Guides profile sync for *arr apps",
794
- category: "utility",
795
- defaultPort: 0, // No web UI - runs as cron job
796
- image: "ghcr.io/recyclarr/recyclarr:latest",
797
- puid: 0, // Uses Docker user: directive
798
- pgid: 0,
799
- useDockerUser: true,
800
- volumes: (root) => [`${root}/config/recyclarr:/config`],
801
- environment: {
802
- RECYCLARR_CREATE_CONFIG: "false", // We generate the config ourselves
803
- CRON_SCHEDULE: "@daily", // Run sync daily at midnight
804
- },
805
- dependsOn: ["radarr", "sonarr"],
806
- autoSetup: {
807
- type: "full",
808
- description: "Generate recyclarr.yml config for enabled *arr apps with TRaSH profiles",
809
- requires: ["radarr", "sonarr"],
810
- },
811
- },
812
- profilarr: {
813
- id: "profilarr",
814
- name: "Profilarr",
815
- description: "Web UI for managing TRaSH Guides profiles (alternative to Recyclarr)",
816
- category: "utility",
817
- defaultPort: 6868,
818
- image: "santiagosayshey/profilarr:latest",
819
- puid: 1000,
820
- pgid: 1000,
821
- volumes: (root) => [`${root}/config/profilarr:/config`],
822
- dependsOn: ["radarr", "sonarr"],
823
- homepage: {
824
- icon: "profilarr",
825
- },
826
- },
827
- // === VPN ===
828
- gluetun: {
829
- id: "gluetun",
830
- name: "Gluetun",
831
- description: "VPN client container for routing traffic",
832
- category: "vpn",
833
- defaultPort: 8888,
834
- image: "qmcgaw/gluetun:latest",
835
- puid: 0,
836
- pgid: 0,
837
- cap_add: ["NET_ADMIN"],
838
- devices: ["/dev/net/tun:/dev/net/tun"],
839
- volumes: (root) => [`${root}/config/gluetun:/gluetun`],
840
- environment: {
841
- VPN_SERVICE_PROVIDER: "${VPN_SERVICE_PROVIDER}",
842
- OPENVPN_USER: "${USERNAME_VPN}",
843
- OPENVPN_PASSWORD: "${PASSWORD_VPN}",
844
- WIREGUARD_PRIVATE_KEY: "${WIREGUARD_PRIVATE_KEY}",
845
- HTTPPROXY: "on",
846
- SHADOWSOCKS: "on",
847
- },
848
- secrets: [
849
- {
850
- name: "VPN_SERVICE_PROVIDER",
851
- description: "VPN Provider (e.g. custom, airvpn)",
852
- required: true,
853
- default: "custom",
854
- },
855
- {
856
- name: "USERNAME_VPN",
857
- description: "OpenVPN Username",
858
- required: false,
859
- },
860
- {
861
- name: "PASSWORD_VPN",
862
- description: "OpenVPN Password",
863
- required: false,
864
- mask: true,
865
- },
866
- {
867
- name: "WIREGUARD_PRIVATE_KEY",
868
- description: "WireGuard Private Key",
869
- required: false,
870
- mask: true,
871
- },
872
- ],
873
- homepage: { icon: "gluetun.png", widget: "gluetun" },
874
- logVolume: "/gluetun",
875
- },
876
-
877
- // === MONITORING ===
878
- grafana: {
879
- id: "grafana",
880
- name: "Grafana",
881
- description: "Visual monitoring dashboard",
882
- category: "monitoring",
883
- defaultPort: 3001,
884
- image: "grafana/grafana-enterprise",
885
- puid: 0,
886
- pgid: 13000,
887
- volumes: (root) => [`${root}/config/grafana:/var/lib/grafana`],
888
- homepage: { icon: "grafana.png", widget: "grafana" },
889
- autoSetup: {
890
- type: "full",
891
- description: "Setup admin user, configure Prometheus datasource",
892
- requires: ["prometheus"],
893
- },
894
- logVolume: "/var/log/grafana",
895
- },
896
-
897
- prometheus: {
898
- id: "prometheus",
899
- name: "Prometheus",
900
- description: "Systems and service monitoring",
901
- category: "monitoring",
902
- defaultPort: 9090,
903
- image: "prom/prometheus",
904
- puid: 0,
905
- pgid: 13000,
906
- volumes: (root) => [`${root}/config/prometheus:/prometheus`],
907
- homepage: { icon: "prometheus.png", widget: "prometheus" },
908
- logVolume: "/prometheus/logs",
909
- },
910
-
911
- dozzle: {
912
- id: "dozzle",
913
- name: "Dozzle",
914
- description: "Real-time log viewer for Docker containers",
915
- category: "monitoring",
916
- defaultPort: 8080,
917
- image: "amir20/dozzle",
918
- puid: 0,
919
- pgid: 0,
920
- volumes: () => ["/var/run/docker.sock:/var/run/docker.sock"],
921
- },
922
-
923
- "uptime-kuma": {
924
- id: "uptime-kuma",
925
- name: "Uptime Kuma",
926
- description: "Self-hosted monitoring tool",
927
- category: "monitoring",
928
- defaultPort: 3001, // Commonly 3001
929
- image: "louislam/uptime-kuma:1",
930
- puid: 0,
931
- pgid: 0,
932
- volumes: (root) => [
933
- `${root}/config/uptime-kuma:/app/data`,
934
- "/var/run/docker.sock:/var/run/docker.sock",
935
- ],
936
- homepage: { icon: "uptime-kuma.png", widget: "uptimekuma" },
937
- autoSetup: {
938
- type: "full",
939
- description: "Create admin user, add monitors for enabled apps",
940
- },
941
- logVolume: "/app/data/logs",
942
- },
943
-
944
- // === INFRASTRUCTURE ===
945
- traefik: {
946
- id: "traefik",
947
- name: "Traefik",
948
- description: "Reverse proxy and load balancer",
949
- category: "infrastructure",
950
- defaultPort: 80,
951
- internalPort: 80,
952
- image: "traefik:latest",
953
- puid: 0,
954
- pgid: 0,
955
- volumes: (root) => [
956
- `${root}/config/traefik:/etc/traefik`,
957
- `${root}/config/traefik/letsencrypt:/letsencrypt`,
958
- "/var/run/docker.sock:/var/run/docker.sock:ro",
959
- ],
960
- // Dashboard exposed on 8083 (internal 8080) for Homepage widget
961
- secondaryPorts: ["8083:8080"],
962
- secrets: [
963
- {
964
- name: "CLOUDFLARE_DNS_ZONE",
965
- description: "Root Domain (e.g. example.com)",
966
- required: true,
967
- },
968
- ],
969
- homepage: { icon: "traefik.png", widget: "traefik" },
970
- logVolume: "/etc/traefik/logs",
971
- },
972
-
973
- caddy: {
974
- id: "caddy",
975
- name: "Caddy",
976
- description: "Web server with automatic HTTPS and reverse proxy",
977
- category: "infrastructure",
978
- defaultPort: 80,
979
- internalPort: 80,
980
- secondaryPorts: ["443:443"],
981
- image: "caddy:latest",
982
- puid: 0,
983
- pgid: 0,
984
- volumes: (root) => [
985
- `${root}/config/caddy/Caddyfile:/etc/caddy/Caddyfile`,
986
- `${root}/config/caddy/data:/data`,
987
- `${root}/config/caddy/config:/config`,
988
- ],
989
- homepage: { icon: "caddy.png" },
990
- logVolume: "/data/logs",
991
- },
992
-
993
- cloudflared: {
994
- id: "cloudflared",
995
- name: "Cloudflared",
996
- description: "Cloudflare Tunnel for secure external access without port forwarding",
997
- category: "infrastructure",
998
- defaultPort: 0, // No exposed port - tunnel is outbound only
999
- image: "cloudflare/cloudflared:latest",
1000
- puid: 0,
1001
- pgid: 0,
1002
- volumes: () => [],
1003
- environment: {
1004
- TUNNEL_TOKEN: "${CLOUDFLARE_TUNNEL_TOKEN}",
1005
- },
1006
- command: "tunnel run",
1007
- dependsOn: ["traefik"],
1008
- secrets: [
1009
- {
1010
- name: "CLOUDFLARE_API_TOKEN",
1011
- description: "Cloudflare API Token (for automated tunnel setup via Menu)",
1012
- required: false,
1013
- mask: true,
1014
- },
1015
- {
1016
- name: "CLOUDFLARE_TUNNEL_TOKEN",
1017
- description: "Cloudflare Tunnel Token (auto-generated or from Zero Trust)",
1018
- required: true,
1019
- mask: true,
1020
- },
1021
- ],
1022
- homepage: { icon: "cloudflare-zero-trust.png", widget: "cloudflared" },
1023
- },
1024
-
1025
- "traefik-certs-dumper": {
1026
- id: "traefik-certs-dumper",
1027
- name: "Traefik Certs Dumper",
1028
- description: "Extracts certificates from Traefik",
1029
- category: "infrastructure",
1030
- defaultPort: 0,
1031
- image: "ldez/traefik-certs-dumper:latest",
1032
- puid: 0,
1033
- pgid: 0,
1034
- volumes: (root) => [
1035
- `${root}/config/traefik/letsencrypt:/traefik:ro`,
1036
- `${root}/config/traefik/certs:/output`,
1037
- ],
1038
- dependsOn: ["traefik"],
1039
- },
1040
-
1041
- crowdsec: {
1042
- id: "crowdsec",
1043
- name: "CrowdSec",
1044
- description: "Intrusion prevention system",
1045
- category: "infrastructure",
1046
- defaultPort: 8080,
1047
- image: "crowdsecurity/crowdsec:latest",
1048
- puid: 0,
1049
- pgid: 0,
1050
- volumes: (root) => [
1051
- `${root}/config/crowdsec:/etc/crowdsec`,
1052
- "/var/run/docker.sock:/var/run/docker.sock:ro",
1053
- ],
1054
- homepage: { icon: "crowdsec.png", widget: "crowdsec" },
1055
- },
1056
-
1057
- headscale: {
1058
- id: "headscale",
1059
- name: "Headscale",
1060
- description: "Open-source Tailscale control server",
1061
- category: "infrastructure",
1062
- defaultPort: 8084,
1063
- image: "headscale/headscale:latest",
1064
- puid: 0,
1065
- pgid: 0,
1066
- volumes: (root) => [
1067
- `${root}/config/headscale:/etc/headscale`,
1068
- `${root}/config/headscale/data:/var/lib/headscale`,
1069
- ],
1070
- homepage: { icon: "headscale.png", widget: "headscale" },
1071
- },
1072
-
1073
- headplane: {
1074
- id: "headplane",
1075
- name: "Headplane",
1076
- description: "Headscale web UI",
1077
- category: "infrastructure",
1078
- defaultPort: 3000,
1079
- image: "ghcr.io/tale/headplane:latest",
1080
- puid: 0,
1081
- pgid: 0,
1082
- volumes: (root) => [`${root}/config/headplane:/config`],
1083
- dependsOn: ["headscale"],
1084
- },
1085
-
1086
- tailscale: {
1087
- id: "tailscale",
1088
- name: "Tailscale",
1089
- description: "VPN mesh network client",
1090
- category: "infrastructure",
1091
- defaultPort: 0,
1092
- image: "tailscale/tailscale:latest",
1093
- puid: 0,
1094
- pgid: 0,
1095
- cap_add: ["NET_ADMIN"],
1096
- devices: ["/dev/net/tun:/dev/net/tun"],
1097
- volumes: (root) => [`${root}/config/tailscale:/var/lib/tailscale`],
1098
- secrets: [
1099
- {
1100
- name: "TAILSCALE_AUTHKEY",
1101
- description: "Tailscale Auth Key",
1102
- required: true,
1103
- mask: true,
1104
- },
1105
- ],
1106
- homepage: { icon: "tailscale.png", widget: "tailscale" },
1107
- },
1108
-
1109
- authentik: {
1110
- id: "authentik",
1111
- name: "Authentik",
1112
- description: "Identity provider and SSO (Server)",
1113
- category: "infrastructure",
1114
- defaultPort: 9001,
1115
- image: "ghcr.io/goauthentik/server:latest",
1116
- puid: 0,
1117
- pgid: 13000,
1118
- volumes: (root) => [
1119
- `${root}/config/authentik/media:/media`,
1120
- `${root}/config/authentik/templates:/templates`,
1121
- ],
1122
- environment: {
1123
- AUTHENTIK_REDIS__HOST: "valkey",
1124
- AUTHENTIK_POSTGRESQL__HOST: "postgresql",
1125
- AUTHENTIK_POSTGRESQL__NAME: "authentik",
1126
- AUTHENTIK_POSTGRESQL__USER: "${USERNAME_POSTGRESQL}",
1127
- AUTHENTIK_POSTGRESQL__PASSWORD: "${PASSWORD_POSTGRESQL}",
1128
- AUTHENTIK_SECRET_KEY: "${AUTHENTIK_SECRET_KEY}",
1129
- },
1130
- dependsOn: ["postgresql", "valkey", "authentik-worker"],
1131
- secrets: [
1132
- {
1133
- name: "AUTHENTIK_SECRET_KEY",
1134
- description: "Authentik Secret Key",
1135
- required: true,
1136
- mask: true,
1137
- generate: true,
1138
- },
1139
- {
1140
- name: "USERNAME_POSTGRESQL",
1141
- description: "Postgres Username",
1142
- required: true,
1143
- default: "postgres",
1144
- },
1145
- {
1146
- name: "PASSWORD_POSTGRESQL",
1147
- description: "Postgres Password",
1148
- required: true,
1149
- mask: true,
1150
- },
1151
- ],
1152
- homepage: { icon: "authentik.png", widget: "authentik" },
1153
- },
1154
-
1155
- "authentik-worker": {
1156
- id: "authentik-worker",
1157
- name: "Authentik Worker",
1158
- description: "Identity provider background worker",
1159
- category: "infrastructure",
1160
- defaultPort: 0,
1161
- image: "ghcr.io/goauthentik/server:latest",
1162
- puid: 0,
1163
- pgid: 13000,
1164
- volumes: (root) => [
1165
- `${root}/config/authentik/media:/media`,
1166
- `${root}/config/authentik/templates:/templates`,
1167
- `${root}/config/authentik/certs:/certs`,
1168
- "/var/run/docker.sock:/var/run/docker.sock",
1169
- ],
1170
- environment: {
1171
- AUTHENTIK_REDIS__HOST: "valkey",
1172
- AUTHENTIK_POSTGRESQL__HOST: "postgresql",
1173
- AUTHENTIK_POSTGRESQL__NAME: "authentik",
1174
- AUTHENTIK_POSTGRESQL__USER: "${USERNAME_POSTGRESQL}",
1175
- AUTHENTIK_POSTGRESQL__PASSWORD: "${PASSWORD_POSTGRESQL}",
1176
- AUTHENTIK_SECRET_KEY: "${AUTHENTIK_SECRET_KEY}",
1177
- },
1178
- dependsOn: ["postgresql", "valkey"],
1179
- },
1180
-
1181
- postgresql: {
1182
- id: "postgresql",
1183
- name: "PostgreSQL",
1184
- description: "Database server",
1185
- category: "infrastructure",
1186
- defaultPort: 5432,
1187
- image: "docker.io/library/postgres:latest",
1188
- puid: 0,
1189
- pgid: 13000,
1190
- volumes: (root) => [`${root}/config/postgresql:/var/lib/postgresql/data`],
1191
- environment: {
1192
- POSTGRES_USER: "${USERNAME_POSTGRESQL}",
1193
- POSTGRES_PASSWORD: "${PASSWORD_POSTGRESQL}",
1194
- POSTGRES_DB: "authentik", // Default to authentik db or user needs to change?
1195
- },
1196
- secrets: [
1197
- {
1198
- name: "USERNAME_POSTGRESQL",
1199
- description: "PostgreSQL Username",
1200
- required: true,
1201
- default: "postgres",
1202
- },
1203
- {
1204
- name: "PASSWORD_POSTGRESQL",
1205
- description: "PostgreSQL Password",
1206
- required: true,
1207
- mask: true,
1208
- },
1209
- ],
1210
- },
1211
-
1212
- valkey: {
1213
- id: "valkey",
1214
- name: "Valkey",
1215
- description: "Redis-compatible key-value store",
1216
- category: "infrastructure",
1217
- defaultPort: 6379,
1218
- image: "valkey/valkey:alpine",
1219
- puid: 0,
1220
- pgid: 13000,
1221
- volumes: (root) => [`${root}/config/valkey:/data`],
1222
- },
1223
- }
1224
-
1225
- export function getAppsByCategory(): Record<string, AppDefinition[]> {
1226
- const result: Record<string, AppDefinition[]> = {}
1227
-
1228
- for (const app of Object.values(APPS)) {
1229
- if (!result[app.category]) {
1230
- result[app.category] = []
1231
- }
1232
- result[app.category].push(app)
1233
- }
1234
-
1235
- return result
1236
- }
1237
-
1238
- export function getApp(id: AppId): AppDefinition | undefined {
1239
- return APPS[id]
1240
- }
1241
-
1242
- export function getAllApps(): AppDefinition[] {
1243
- return Object.values(APPS)
1244
- }
1245
-
1246
- export function getAppIds(): AppId[] {
1247
- return Object.keys(APPS) as AppId[]
1248
- }
1249
-
1250
- /**
1251
- * Get all apps compatible with the current system architecture
1252
- */
1253
- export function getCompatibleApps(): AppDefinition[] {
1254
- const arch = getSystemArch()
1255
- return Object.values(APPS).filter((app) => isAppCompatible(app, arch))
1256
- }
1257
-
1258
- /**
1259
- * Get apps that have warnings for the current architecture (deprecated but may work)
1260
- */
1261
- export function getAppsWithArchWarnings(): { app: AppDefinition; warning: string }[] {
1262
- const arch = getSystemArch()
1263
- const result: { app: AppDefinition; warning: string }[] = []
1264
-
1265
- for (const app of Object.values(APPS)) {
1266
- const warning = getArchWarning(app, arch)
1267
- if (warning) {
1268
- result.push({ app, warning })
1269
- }
1270
- }
1271
-
1272
- return result
1273
- }
1274
-
1275
- export { getSystemArch, isAppCompatible, getArchWarning, isAppDeprecated }