blob: 6635d8bb81119fe88471791c27a3a1f96e10cbb8 [file] [log] [blame]
gio404e2372025-07-11 12:50:26 +04001import (
2 "encoding/yaml"
3 "encoding/json"
4)
5
6input: {
7 network: #Network @name(Network)
8 subdomain: string @name(Subdomain)
9 mapEnabled: bool | *false @name(Map)
10 storageSize: string | *"10Gi" @name(Storage Size)
11}
12
13_domain: "\(input.subdomain).\(input.network.domain)"
14url: "https://\(_domain)"
15
16name: "Immich"
17namespace: "app-immich"
18readme: "Self-hosted photo and video management solution"
19description: "Easily back up, organize, and manage your photos on your own server. Immich helps you browse, search and organize your photos and videos with ease, without sacrificing your privacy."
20icon: """
21<svg width='50px' height='50px' version="1.1" id="Flower" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
22 viewBox="0 0 792 792" style="enable-background:new 0 0 792 792;" xml:space="preserve">
23<style type="text/css">
24 .st0{fill:#FA2921;}
25 .st1{fill:#ED79B5;}
26 .st2{fill:#FFB400;}
27 .st3{fill:#1E83F7;}
28 .st4{fill:#18C249;}
29</style>
30<g id="Flower_00000077325900055813483940000000694823054982625702_">
31 <path class="st0" d="M375.48,267.63c38.64,34.21,69.78,70.87,89.82,105.42c34.42-61.56,57.42-134.71,57.71-181.3
32 c0-0.33,0-0.63,0-0.91c0-68.94-68.77-95.77-128.01-95.77s-128.01,26.83-128.01,95.77c0,0.94,0,2.2,0,3.72
33 C300.01,209.24,339.15,235.47,375.48,267.63z"/>
34 <path class="st1" d="M164.7,455.63c24.15-26.87,61.2-55.99,103.01-80.61c44.48-26.18,88.97-44.47,128.02-52.84
35 c-47.91-51.76-110.37-96.24-154.6-110.91c-0.31-0.1-0.6-0.19-0.86-0.28c-65.57-21.3-112.34,35.81-130.64,92.15
36 c-18.3,56.34-14.04,130.04,51.53,151.34C162.05,454.77,163.25,455.16,164.7,455.63z"/>
37 <path class="st2" d="M681.07,302.19c-18.3-56.34-65.07-113.45-130.64-92.15c-0.9,0.29-2.1,0.68-3.54,1.15
38 c-3.75,35.93-16.6,81.27-35.96,125.76c-20.59,47.32-45.84,88.27-72.51,118c69.18,13.72,145.86,12.98,190.26-1.14
39 c0.31-0.1,0.6-0.2,0.86-0.28C695.11,432.22,699.37,358.52,681.07,302.19z"/>
40 <path class="st3" d="M336.54,510.71c-11.15-50.39-14.8-98.36-10.7-138.08c-64.03,29.57-125.63,75.23-153.26,112.76
41 c-0.19,0.26-0.37,0.51-0.53,0.73c-40.52,55.78-0.66,117.91,47.27,152.72c47.92,34.82,119.33,53.54,159.86-2.24
42 c0.56-0.76,1.3-1.78,2.19-3.01C363.28,602.32,347.02,558.08,336.54,510.71z"/>
43 <path class="st4" d="M617.57,482.52c-35.33,7.54-82.42,9.33-130.72,4.66c-51.37-4.96-98.11-16.32-134.63-32.5
44 c8.33,70.03,32.73,142.73,59.88,180.6c0.19,0.26,0.37,0.51,0.53,0.73c40.52,55.78,111.93,37.06,159.86,2.24
45 c47.92-34.82,87.79-96.95,47.27-152.72C619.2,484.77,618.46,483.75,617.57,482.52z"/>
46</g>
47</svg>"""
48
49out: {
50 ingress: {
51 immich: {
52 auth: enabled: false
53 network: input.network
54 subdomain: input.subdomain
55 service: {
56 name: "immich-server"
57 port: _httpPort
58 }
59 }
60 }
61
62 // TODO(gio): configure busybox
63 images: {
64 immich: {
65 registry: "ghcr.io"
66 repository: "immich-app"
67 name: "immich-server"
68 tag: "v1.135.3"
69 pullPolicy: "IfNotPresent"
70 }
71 ml: {
72 registry: "ghcr.io"
73 repository: "immich-app"
74 name: "immich-machine-learning"
75 tag: "v1.135.3"
76 pullPolicy: "IfNotPresent"
77 }
78 }
79
80 charts: {
81 immich: {
82 kind: "GitRepository"
83 address: "https://code.v1.dodo.cloud/helm-charts"
84 branch: "main"
85 path: "charts/immich"
86 }
87 oauth2Client: {
88 kind: "GitRepository"
89 address: "https://code.v1.dodo.cloud/helm-charts"
90 branch: "main"
91 path: "charts/oauth2-client"
92 }
93 resourceRenderer: {
94 kind: "GitRepository"
95 address: "https://code.v1.dodo.cloud/helm-charts"
96 branch: "main"
97 path: "charts/resource-renderer"
98 }
99 }
100
101 volume: immich: size: input.storageSize
102
103 _httpPort: 2283
104 _oauth2ClientSecretName: "oauth2-client"
105
106 helm: {
107 "oauth2-client": {
108 chart: charts.oauth2Client
109 info: "Creating OAuth2 client"
110 // TODO(gio): remove once hydra maester is installed as part of dodo itself
111 dependsOn: [{
112 name: "auth"
113 namespace: "\(global.namespacePrefix)core-auth"
114 }]
115 values: {
116 name: "\(release.namespace)-immich"
117 secretName: _oauth2ClientSecretName
118 grantTypes: ["authorization_code"]
119 responseTypes: ["code"]
120 scope: "openid profile email groups"
121 redirectUris: [
122 "app.immich:///oauth-callback",
123 "https://\(_domain)/auth/login",
124 "https://\(_domain)/user-settings",
125 ]
126 tokenEndpointAuthMethod: "client_secret_post"
127 hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
128 }
129 }
130 "config-renderer": {
131 chart: charts.resourceRenderer
132 info: "Generating Immich configuration"
133 values: {
134 name: "config-renderer"
135 secretName: _oauth2ClientSecretName
136 resourceTemplate: yaml.Marshal({
137 apiVersion: "v1"
138 kind: "ConfigMap"
139 metadata: {
140 name: _immichConfigMapName
141 namespace: "\(release.namespace)"
142 }
143 data: {
144 "immich-config.json": json.Marshal({
145 {
146 "ffmpeg": {
147 "crf": 23
148 "threads": 0
149 "preset": "ultrafast"
150 "targetVideoCodec": "h264"
151 "acceptedVideoCodecs": ["h264"]
152 "targetAudioCodec": "aac"
153 "acceptedAudioCodecs": ["aac", "mp3", "libopus", "pcm_s16le"]
154 "acceptedContainers": ["mov", "ogg", "webm"]
155 "targetResolution": "720"
156 "maxBitrate": "0"
157 "bframes": -1
158 "refs": 0
159 "gopSize": 0
160 "temporalAQ": false
161 "cqMode": "auto"
162 "twoPass": false
163 "preferredHwDevice": "auto"
164 "transcode": "required"
165 "tonemap": "hable"
166 "accel": "disabled"
167 "accelDecode": false
168 }
169 "backup": {
170 "database": {
171 "enabled": true
172 "cronExpression": "0 02 * * *"
173 "keepLastAmount": 14
174 }
175 }
176 "job": {
177 "backgroundTask": {
178 "concurrency": 5
179 }
180 "smartSearch": {
181 "concurrency": 2
182 }
183 "metadataExtraction": {
184 "concurrency": 5
185 }
186 "faceDetection": {
187 "concurrency": 2
188 }
189 "search": {
190 "concurrency": 5
191 }
192 "sidecar": {
193 "concurrency": 5
194 }
195 "library": {
196 "concurrency": 5
197 }
198 "migration": {
199 "concurrency": 5
200 }
201 "thumbnailGeneration": {
202 "concurrency": 3
203 }
204 "videoConversion": {
205 "concurrency": 1
206 }
207 "notifications": {
208 "concurrency": 5
209 }
210 }
211 "logging": {
212 "enabled": true
213 "level": "log"
214 }
215 "machineLearning": {
216 "enabled": true
217 "urls": ["http://immich-machine-learning:3003"]
218 "clip": {
219 "enabled": true
220 "modelName": "ViT-B-32__openai"
221 }
222 "duplicateDetection": {
223 "enabled": true
224 "maxDistance": 0.01
225 }
226 "facialRecognition": {
227 "enabled": true
228 "modelName": "buffalo_l"
229 "minScore": 0.7
230 "maxDistance": 0.5
231 "minFaces": 3
232 }
233 }
234 "map": {
235 "enabled": input.mapEnabled
236 "lightStyle": "https://tiles.immich.cloud/v1/style/light.json"
237 "darkStyle": "https://tiles.immich.cloud/v1/style/dark.json"
238 }
239 "reverseGeocoding": {
240 "enabled": true
241 }
242 "metadata": {
243 "faces": {
244 "import": false
245 }
246 }
247 "oauth": {
248 "autoLaunch": true
249 "autoRegister": true
250 "buttonText": "Login with dodo"
251 "clientId": "{{ .client_id }}"
252 "clientSecret": "{{ .client_secret }}"
253 "defaultStorageQuota": null
254 "enabled": true
255 "issuerUrl": "https://hydra.\(networks.public.domain)"
256 "mobileOverrideEnabled": false
257 "mobileRedirectUri": ""
258 "scope": "openid email profile"
259 "signingAlgorithm": "RS256"
260 "profileSigningAlgorithm": "none"
261 "storageLabelClaim": "preferred_username"
262 "storageQuotaClaim": "immich_quota"
263 }
264 "passwordLogin": {
265 "enabled": false
266 }
267 "storageTemplate": {
268 "enabled": false
269 "hashVerificationEnabled": true
270 "template": "{{`{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}`}}"
271 }
272 "image": {
273 "thumbnail": {
274 "format": "webp"
275 "size": 250
276 "quality": 80
277 }
278 "preview": {
279 "format": "jpeg"
280 "size": 1440
281 "quality": 80
282 }
283 "colorspace": "p3"
284 "extractEmbedded": false
285 }
286 "newVersionCheck": {
287 "enabled": true
288 }
289 "trash": {
290 "enabled": true
291 "days": 30
292 }
293 "theme": {
294 "customCss": ""
295 }
296 "library": {
297 "scan": {
298 "enabled": true
299 "cronExpression": "0 0 * * *"
300 }
301 "watch": {
302 "enabled": false
303 }
304 }
305 "server": {
306 "externalDomain": "https://\(_domain)"
307 "loginPageMessage": ""
308 }
309 "notifications": {
310 "smtp": {
311 "enabled": false
312 "from": ""
313 "replyTo": ""
314 "transport": {
315 "ignoreCert": false
316 "host": ""
317 "port": 587
318 "username": ""
319 "password": ""
320 }
321 }
322 }
323 "user": {
324 "deleteDelay": 7
325 }
326 }})
327 }
328 })
329 }
330 }
331 immich: {
332 chart: charts.immich
333 info: "Installing Immich server"
334 values: {
335 image: tag: "v1.135.3"
336 immich: existingConfiguration: _immichConfigMapName
337 persistence: library: existingClaim: "immich"
338 }
339 }
340 }
341}
342
343_immichConfigMapName: "immich-config"