Setup storage of immich resouces and add tailscale access to allow uploading files too large to go over cloudflare (<100mb) See https://github.com/immich-app/immich/issues/17729 and https://github.com/immich-app/immich/pull/22385

This commit is contained in:
2025-10-13 20:48:35 +11:00
parent e6c6bb0c91
commit 4a5ad8d36b
3 changed files with 199 additions and 10 deletions

View File

@@ -35,13 +35,16 @@ job "immich" {
tags = [
"traefik.enable=true",
"traefik.http.routers.immich.middlewares=auth@file",
"traefik.http.routers.immich-token.rule=Host(`c3ll7nbevl5j4j8rcnfxnr95q48fuayz-immich.othrayte.one`)",
]
# Todo try GET /server/ping (https://api.immich.app/endpoints/server/pingServer)
# https://github.com/immich-app/immich-charts/blob/main/charts/immich/templates/server.yaml#L57
# Use the Immich server ping endpoint
# See: https://api.immich.app/endpoints/server/pingServer
check {
name = "alive"
type = "tcp"
type = "http"
path = "/api/server/ping"
method = "GET"
port = "http"
interval = "10s"
timeout = "2s"
@@ -49,10 +52,11 @@ job "immich" {
}
env {
UPLOAD_LOCATION = "./library"
TZ = "Australia/Melbourne"
REDIS_HOSTNAME = "localhost"
DB_HOSTNAME = "localhost"
IMMICH_LOG_LEVEL = "log"
TZ = "Australia/Melbourne"
REDIS_HOSTNAME = "localhost"
DB_HOSTNAME = "localhost"
IMMICH_IGNORE_MOUNT_CHECK_ERRORS = "true" # Let immich start whilst we figure out what's wrong with the mount permissions
}
volume_mount {
@@ -61,9 +65,28 @@ job "immich" {
read_only = false
}
volume_mount {
volume = "unraid_media_photosvideos"
destination = "/data/library"
read_only = false
}
volume_mount {
volume = "unraid_media_immich_encodedvideo"
destination = "/data/encoded-video"
read_only = false
}
volume_mount {
volume = "unraid_mediadump_photosvideos"
destination = "/data/upload"
read_only = false
}
resources {
cpu = 200
memory = 1024
cpu = 200
memory = 512
memory_max = 1500
}
template {
@@ -88,11 +111,53 @@ EOH
}
}
volume "unraid_media_photosvideos" {
type = "csi"
read_only = false
source = "unraid_media_photosvideos"
access_mode = "single-node-writer"
attachment_mode = "file-system"
mount_options {
mount_flags = ["uid=1000", "gid=1000"]
}
}
volume "unraid_media_immich_encodedvideo" {
type = "csi"
read_only = false
source = "unraid_media_immich_encodedvideo"
access_mode = "single-node-writer"
attachment_mode = "file-system"
mount_options {
mount_flags = ["uid=1000", "gid=1000"]
}
}
volume "unraid_mediadump_photosvideos" {
type = "csi"
read_only = false
source = "unraid_mediadump_photosvideos"
access_mode = "single-node-writer"
attachment_mode = "file-system"
mount_options {
mount_flags = ["uid=1000", "gid=1000"]
}
}
task "immich-machine-learning" {
driver = "docker"
config {
image = "ghcr.io/immich-app/immich-machine-learning:release"
}
resources {
cpu = 200
memory = 500
memory_max = 2000
}
}
task "redis" {
@@ -101,6 +166,44 @@ EOH
config {
image = "docker.io/valkey/valkey:8-bookworm@sha256:fea8b3e67b15729d4bb70589eb03367bab9ad1ee89c876f54327fc7c6e618571"
}
resources {
cpu = 30
memory = 10
memory_max = 50
}
}
task "tailscale" {
driver = "docker"
config {
image = "tailscale/tailscale:latest"
}
env = {
TS_HOSTNAME = "immich"
TS_EXTRA_ARGS = "--advertise-tags=tag:nomad"
}
resources {
cpu = 100
memory = 100
memory_max = 300
}
lifecycle {
hook = "prestart"
sidecar = true
}
template {
data = <<EOH
TS_AUTHKEY="{{ with nomadVar "nomad/jobs/immich" }}{{ .tailscale_oauthsecret }}{{ end }}?ephemeral=true"
EOH
destination = "secrets/ts_oauth.env"
env = true # Load the file as environment variables
}
}
}
}

View File

@@ -29,7 +29,8 @@ resource "postgresql_extension" "immich_earthdistance" {
resource "nomad_variable" "immich" {
path = "nomad/jobs/immich"
items = {
database_pw = data.sops_file.secrets.data["immich.database_pw"]
database_pw = data.sops_file.secrets.data["immich.database_pw"]
tailscale_oauthsecret = data.sops_file.secrets.data["tailscale.oauthsecret"]
}
}
@@ -58,3 +59,82 @@ resource "nomad_csi_volume_registration" "unraid_appdata_immich" {
"password" = data.sops_file.secrets.data["unraid.nomad"]
}
}
resource "nomad_csi_volume_registration" "unraid_media_photosvideos" {
#Note: Before chaning the definition of this volume you need to stop the jobs that are using it
depends_on = [data.nomad_plugin.smb]
plugin_id = "smb"
volume_id = "unraid_media_photosvideos"
name = "unraid_media_photosvideos"
external_id = "unraid_media_photosvideos"
capability {
access_mode = "single-node-writer"
attachment_mode = "file-system"
}
context = {
source = "//192.168.1.192/media"
subDir = "Photos and Videos" # Note: Needs to be manually created on the share
}
secrets = {
"username" = "nomad"
"password" = data.sops_file.secrets.data["unraid.nomad"]
}
}
resource "nomad_csi_volume_registration" "unraid_media_immich_encodedvideo" {
#Note: Before chaning the definition of this volume you need to stop the jobs that are using it
depends_on = [data.nomad_plugin.smb]
plugin_id = "smb"
volume_id = "unraid_media_immich_encodedvideo"
name = "unraid_media_immich_encodedvideo"
external_id = "unraid_media_immich_encodedvideo"
capability {
access_mode = "single-node-writer"
attachment_mode = "file-system"
}
context = {
source = "//192.168.1.192/media"
subDir = "immich/encoded-video" # Note: Needs to be manually created on the share
}
secrets = {
"username" = "nomad"
"password" = data.sops_file.secrets.data["unraid.nomad"]
}
}
resource "nomad_csi_volume_registration" "unraid_mediadump_photosvideos" {
#Note: Before chaning the definition of this volume you need to stop the jobs that are using it
depends_on = [data.nomad_plugin.smb]
plugin_id = "smb"
volume_id = "unraid_mediadump_photosvideos"
name = "unraid_mediadump_photosvideos"
external_id = "unraid_mediadump_photosvideos"
capability {
access_mode = "single-node-writer"
attachment_mode = "file-system"
}
context = {
source = "//192.168.1.192/media-dump"
subDir = "Photos and Videos" # Note: Needs to be manually created on the share
}
secrets = {
"username" = "nomad"
"password" = data.sops_file.secrets.data["unraid.nomad"]
}
}

View File

@@ -40,3 +40,9 @@ data "nomad_plugin" "smb" {
plugin_id = "smb"
wait_for_healthy = true
}
resource "nomad_scheduler_config" "config" {
memory_oversubscription_enabled = true
}