2026-04-30 18:05:24 -04:00
|
|
|
package immich
|
|
|
|
|
|
|
|
|
|
import (
|
2026-05-05 12:37:46 -04:00
|
|
|
"fmt"
|
|
|
|
|
|
2026-04-30 18:05:24 -04:00
|
|
|
"danicos.dev/daniel/go-kube/pkg/kube"
|
|
|
|
|
"danicos.dev/daniel/go-kube/pkg/stack"
|
2026-05-05 12:35:57 -04:00
|
|
|
"danicos.dev/daniel/homelab/pkg/postgres"
|
2026-04-30 18:05:24 -04:00
|
|
|
"danicos.dev/daniel/homelab/pkg/root"
|
2026-05-01 14:11:41 -04:00
|
|
|
apps "k8s.io/api/apps/v1"
|
2026-04-30 18:05:24 -04:00
|
|
|
core "k8s.io/api/core/v1"
|
2026-05-01 15:24:38 -04:00
|
|
|
"k8s.io/apimachinery/pkg/api/resource"
|
2026-04-30 18:05:24 -04:00
|
|
|
)
|
|
|
|
|
|
2026-05-01 13:38:11 -04:00
|
|
|
var Secret = struct {
|
|
|
|
|
Name string
|
|
|
|
|
DBNameKey string
|
|
|
|
|
DBUsernameKey string
|
|
|
|
|
DBPasswordKey string
|
|
|
|
|
DBHostKey string
|
|
|
|
|
DBPortKey string
|
|
|
|
|
}{
|
2026-05-05 12:35:57 -04:00
|
|
|
Name: postgres.ImmichPGSecret.Name,
|
2026-05-01 13:38:11 -04:00
|
|
|
DBNameKey: "db_name",
|
|
|
|
|
DBUsernameKey: "db_username",
|
|
|
|
|
DBPasswordKey: "db_password",
|
|
|
|
|
DBHostKey: "db_host",
|
|
|
|
|
DBPortKey: "db_port",
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 12:23:57 -04:00
|
|
|
const RedisPort = 6379
|
|
|
|
|
|
2026-04-30 18:05:24 -04:00
|
|
|
var meta kube.Metadata
|
|
|
|
|
var Namespace = kube.Namespace(root.Immich.Name)
|
|
|
|
|
var srv core.Service
|
2026-05-01 13:48:44 -04:00
|
|
|
var uploads_pvc core.PersistentVolumeClaim
|
2026-05-05 12:23:57 -04:00
|
|
|
var redis_meta kube.Metadata
|
|
|
|
|
var redis_srv core.Service
|
2026-04-30 18:05:24 -04:00
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
meta = kube.NewMetadata(root.Immich.Name, Namespace)
|
2026-05-01 14:11:41 -04:00
|
|
|
srv = meta.Service(root.Immich.Port)
|
2026-05-05 14:18:44 -04:00
|
|
|
srv.Spec.Type = core.ServiceTypeNodePort
|
|
|
|
|
srv.Spec.Ports[0].NodePort = int32(root.Immich.Public.NodePort)
|
|
|
|
|
|
2026-05-01 13:48:44 -04:00
|
|
|
uploads_pvc = meta.PVC()
|
|
|
|
|
uploads_pvc.Spec.StorageClassName = new(root.TrueNASSTorageClassNFS)
|
|
|
|
|
uploads_pvc.Spec.AccessModes = []core.PersistentVolumeAccessMode{core.ReadWriteMany}
|
2026-05-05 19:31:27 -04:00
|
|
|
req := kube.StorageRequest(resource.MustParse("200Gi"))
|
2026-05-01 15:24:38 -04:00
|
|
|
uploads_pvc.Spec.Resources = core.VolumeResourceRequirements{
|
|
|
|
|
Requests: req,
|
|
|
|
|
}
|
2026-05-05 12:23:57 -04:00
|
|
|
|
|
|
|
|
redis_meta = kube.NewMetadata("redis", Namespace)
|
|
|
|
|
redis_srv = redis_meta.Service(RedisPort)
|
2026-04-30 18:05:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Stack() stack.Stack {
|
|
|
|
|
kz := kube.NewKuztomizedStack(
|
|
|
|
|
meta,
|
|
|
|
|
map[string]any{
|
2026-05-05 12:27:12 -04:00
|
|
|
"namespace": Namespace,
|
|
|
|
|
"uploads-pvc": uploads_pvc,
|
|
|
|
|
"redis-srv": redis_srv,
|
|
|
|
|
"redis-deployment": Redis(),
|
|
|
|
|
"immich-deployment": Deployment(),
|
|
|
|
|
"immich-srv": srv,
|
2026-04-30 18:05:24 -04:00
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
return kz.Stack("immich")
|
|
|
|
|
}
|
2026-05-01 14:11:41 -04:00
|
|
|
|
|
|
|
|
func Deployment() apps.Deployment {
|
|
|
|
|
uploadVol := kube.NewVolumeFrom(kube.VolumeSourcePVC, "upload", uploads_pvc.Name)
|
2026-05-05 12:23:57 -04:00
|
|
|
localtimeVol := core.Volume{
|
|
|
|
|
Name: "localtime",
|
|
|
|
|
VolumeSource: core.VolumeSource{
|
|
|
|
|
HostPath: &core.HostPathVolumeSource{
|
|
|
|
|
Path: "/etc/localtime",
|
|
|
|
|
Type: new(core.HostPathFile),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
2026-05-05 12:37:46 -04:00
|
|
|
envMapping := map[string]string{
|
|
|
|
|
"REDIS_PORT": fmt.Sprintf("%d", RedisPort),
|
|
|
|
|
"IMMICH_PORT": fmt.Sprintf("%d", root.Immich.Port),
|
|
|
|
|
}
|
2026-05-01 14:11:41 -04:00
|
|
|
secretMapping := map[string]string{
|
|
|
|
|
"DB_HOSTNAME": Secret.DBHostKey,
|
|
|
|
|
"DB_PORT": Secret.DBPortKey,
|
|
|
|
|
"DB_USERNAME": Secret.DBUsernameKey,
|
|
|
|
|
"DB_PASSWORD": Secret.DBPasswordKey,
|
|
|
|
|
"DB_DATABASE_NAME": Secret.DBUsernameKey,
|
|
|
|
|
}
|
|
|
|
|
podSpec := core.PodSpec{
|
|
|
|
|
Containers: []core.Container{
|
|
|
|
|
{
|
|
|
|
|
Name: root.Immich.Name + "-server",
|
|
|
|
|
Image: root.Immich.Image,
|
|
|
|
|
Env: kube.NewEnvVarWithSecret(envMapping, secretMapping, Secret.Name),
|
|
|
|
|
Ports: []core.ContainerPort{{ContainerPort: root.Immich.Port}},
|
2026-05-05 14:57:42 -04:00
|
|
|
VolumeMounts: []core.VolumeMount{
|
|
|
|
|
{
|
|
|
|
|
Name: uploadVol.Name,
|
|
|
|
|
MountPath: "/data",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: localtimeVol.Name,
|
|
|
|
|
MountPath: "/etc/localtime",
|
|
|
|
|
ReadOnly: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-05-01 14:11:41 -04:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Volumes: []core.Volume{
|
|
|
|
|
uploadVol,
|
2026-05-05 12:23:57 -04:00
|
|
|
localtimeVol,
|
2026-05-01 14:11:41 -04:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return kube.NewDeployment(meta, podSpec)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Redis() apps.Deployment {
|
2026-05-05 12:23:57 -04:00
|
|
|
podSpec := core.PodSpec{
|
|
|
|
|
Containers: []core.Container{
|
|
|
|
|
{
|
2026-05-05 12:25:26 -04:00
|
|
|
Name: "redis",
|
2026-05-05 12:23:57 -04:00
|
|
|
Image: "docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return kube.NewDeployment(redis_meta, podSpec)
|
2026-05-01 14:11:41 -04:00
|
|
|
}
|