<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Self-Hosting on Bastien Traverse</title>
    <link>https://bastientraverse.com/en/tags/self-hosting/</link>
    <description>Recent content in Self-Hosting on Bastien Traverse</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Thu, 28 May 2026 00:00:00 +0200</lastBuildDate><atom:link href="https://bastientraverse.com/en/tags/self-hosting/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Deploy Immich on IncusOS</title>
      <link>https://bastientraverse.com/en/posts/2026-05/immich-incusos/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0200</pubDate>
      
      <guid>https://bastientraverse.com/en/posts/2026-05/immich-incusos/</guid>
      <description>&lt;p&gt;Here are the steps I followed to set up &lt;a href=&#34;https://immich.app/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Immich&lt;/a&gt; on my home server using &lt;a href=&#34;https://linuxcontainers.org/incus-os/introduction/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;IncusOS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I chose to do it via Incus&amp;rsquo; native &lt;a href=&#34;https://www.youtube.com/watch?v=A-cW5XyCjFk&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OCI container support&lt;/a&gt;, instead of going through the more usual approach of spinning up a Docker host in an instance. As far as I can tell this approach hasn&amp;rsquo;t been documented anywhere yet, which makes me quite happy to be able to contribute it.&lt;/p&gt;
&lt;h2 id=&#34;what-differs-in-this-approach&#34;&gt;&lt;a href=&#34;#what-differs-in-this-approach&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;What differs in this approach&lt;/h2&gt;&lt;p&gt;Going with Incus native OCI support means we cannot rely on docker-compose: although &lt;a href=&#34;https://gitlab.com/r3j0/incus-compose&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;incus-compose&lt;/a&gt; is quite promising, &lt;a href=&#34;https://discuss.linuxcontainers.org/t/early-development-version-of-the-resurrected-incus-compose-online/25690/33?u=neitsab&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;it is not there yet for this use case&lt;/a&gt;. We will have to do everything manually, and that&amp;rsquo;s what this post covers.&lt;/p&gt;
&lt;p&gt;Since it wouldn&amp;rsquo;t be fun if this was my sole &amp;ldquo;handicap&amp;rdquo;, I&amp;rsquo;m also using the immutable OS purpose-built for Incus. This means we cannot use bind mounts for the persisted data: instead we will use &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/explanation/storage/#storage-volume-types&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;custom filesystem storage volumes&lt;/a&gt;, which on IncusOS are backed by ZFS file system datasets.&lt;/p&gt;
&lt;h2 id=&#34;step-1-download-and-review-the-upstream-config&#34;&gt;&lt;a href=&#34;#step-1-download-and-review-the-upstream-config&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Step 1: Download and review the upstream config&lt;/h2&gt;&lt;p&gt;The first step is to read and understand what the upstream Docker Compose setup would do.&lt;/p&gt;
&lt;p&gt;Follow &lt;a href=&#34;https://docs.immich.app/install/docker-compose/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;the official instructions&lt;/a&gt; to retrieve the files and pay attention to where and how the variables from the &lt;code&gt;.env&lt;/code&gt; file are used in the Compose file.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the upstream &lt;code&gt;.env&lt;/code&gt; as of writing this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# You can find documentation for all the supported env variables at https://docs.immich.app/install/environment-variables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The location where your uploaded files are stored&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;UPLOAD_LOCATION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;./library
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The location where your database files are stored. Network shares are not supported for the database&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DB_DATA_LOCATION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;./postgres
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# TZ=Etc/UTC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The Immich version to use. You can pin this to a specific version like &amp;#34;v2.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;IMMICH_VERSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;v2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Connection secret for postgres. You should change it to a random password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Please use only the characters `A-Za-z0-9`, without special characters or spaces&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DB_PASSWORD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;postgres
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The values below this line do not need to be changed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;###################################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DB_USERNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;postgres
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DB_DATABASE_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As outlined in &lt;a href=&#34;https://docs.immich.app/install/environment-variables/#docker-compose&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Immich docs&lt;/a&gt;, &lt;code&gt;UPLOAD_LOCATION&lt;/code&gt;, &lt;code&gt;DB_DATA_LOCATION&lt;/code&gt; and &lt;code&gt;IMMICH_VERSION&lt;/code&gt; are only useful if using Docker Compose, so I commented them out.&lt;/p&gt;
&lt;p&gt;I also uncommented and set the &lt;code&gt;TZ&lt;/code&gt; variable and changed the &lt;code&gt;DB_PASSWORD&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Since we are not using Docker Compose and its network &lt;del&gt;shenanigans&lt;/del&gt; helpers, we also need to set the &lt;a href=&#34;https://docs.immich.app/install/environment-variables/#database&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;database&lt;/a&gt; and &lt;a href=&#34;https://docs.immich.app/install/environment-variables/#redis&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Redis&lt;/a&gt; &lt;code&gt;HOST&lt;/code&gt;  environment variables so that our Immich server is able to find them.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;IMMICH_MACHINE_LEARNING_URL&lt;/code&gt; was &lt;a href=&#34;https://github.com/immich-app/immich/discussions/6630#discussioncomment-8235018&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;deprecated in 2024&lt;/a&gt; but still works, otherwise it can be configured in the web app settings or via the config file.&lt;/p&gt;
&lt;p&gt;Result for me:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# You can find documentation for all the supported env variables at https://docs.immich.app/install/environment-variables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The location where your uploaded files are stored&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# not used with Incus&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#UPLOAD_LOCATION=library&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The location where your database files are stored. Network shares are not supported for the database&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# not used with Incus&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#DB_DATA_LOCATION=postgres&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TZ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;Europe/Paris
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The Immich version to use. You can pin this to a specific version like &amp;#34;v2.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# not used with Incus&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#IMMICH_VERSION=v2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Connection secret for postgres. You should change it to a random password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Please use only the characters `A-Za-z0-9`, without special characters or spaces&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DB_PASSWORD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;MySuperStrongPassword
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The values below this line do not need to be changed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;###################################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DB_USERNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;postgres
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DB_DATABASE_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Needed when not using Docker Compose&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Uncomment the DB_STORAGE_TYPE: &amp;#39;HDD&amp;#39; var if your database isn&amp;#39;t stored on SSDs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#DB_STORAGE_TYPE=HDD&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DB_HOSTNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich-postgres.incus
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;REDIS_HOSTNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich-redis.incus
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;IMMICH_MACHINE_LEARNING_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://immich-ml.incus:3003
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note the Incus-specific &lt;code&gt;.incus&lt;/code&gt; TLD used: this is the default &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/reference/network_bridge/#network_bridge-common:dns.domain&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;DNS domain&lt;/a&gt; used on managed bridges, and allows to reach instances on the same network with their hostname (which here is automatically derived from the instance name).&lt;/p&gt;
&lt;p&gt;With the application config out of the way, let&amp;rsquo;s move to setting up the infrastructure.&lt;/p&gt;
&lt;h2 id=&#34;step-2-set-up-a-dedicated-incus-project-and-network&#34;&gt;&lt;a href=&#34;#step-2-set-up-a-dedicated-incus-project-and-network&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Step 2: Set up a dedicated Incus project and network&lt;/h2&gt;&lt;p&gt;This is optional, but to separate concerns I prefer to group multi-container Compose projects inside dedicated &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/explanation/projects/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Incus projects&lt;/a&gt;. This way they get their own namespace which can be managed independently from other projects:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus project create immich --config features.images&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;--config features.images=false&lt;/code&gt; disables &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/reference/projects/#project-features&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;images isolation&lt;/a&gt;, &lt;em&gt;i.e.&lt;/em&gt; images in this project are shared with the default project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Incus instances needs a default &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/profiles/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;profile&lt;/a&gt; to define their root disk and default network, so we copy the default profile from the default project into our &lt;code&gt;immich&lt;/code&gt; project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus profile show default &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; incus profile edit default --project immich
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I also set up a dedicated network to better replicate what docker-compose does by default and be able to manage more easily it later on.&lt;/p&gt;
&lt;p&gt;For reasons unknown to me, &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/explanation/networks/#fully-controlled-networks&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Incus managed bridged networks&lt;/a&gt; cannot be created &lt;a href=&#34;https://discuss.linuxcontainers.org/t/what-kinds-of-network-can-be-project-specific/19527/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;outside the default project&lt;/a&gt;, so we have to create it there first and then the &lt;code&gt;immich&lt;/code&gt; project use it for by default:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus network create immich-net
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus profile device &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; default eth0 &lt;span class=&#34;nv&#34;&gt;network&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich-net --project immich
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# optionnal: restrict the project to using only this network&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus project &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; immich restricted.networks.access&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich-net
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Before we continue, let&amp;rsquo;s switch the CLI context to this project so as to avoid having to add &lt;code&gt;--project immich&lt;/code&gt; to every single command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;incus project switch immich
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;step-3-create-the-storage-volumes&#34;&gt;&lt;a href=&#34;#step-3-create-the-storage-volumes&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Step 3: Create the storage volumes&lt;/h2&gt;&lt;p&gt;This will be where all our important project data will be stored. The &lt;a href=&#34;https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;upstream compose file&lt;/a&gt; uses two bind mounts and one named volume, which we replace with three custom storage volumes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; i in postgres uploads model-cache&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    incus storage volume create &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; immich_&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;admonition note&#34;&gt;
  If you are not using IncusOS, your pool will likely be named &lt;code&gt;default&lt;/code&gt; instead of &lt;code&gt;local&lt;/code&gt;.
&lt;/div&gt;
&lt;p&gt;Then it&amp;rsquo;s finally time to create the containers themselves!&lt;/p&gt;
&lt;h2 id=&#34;step-4-create-the-containers&#34;&gt;&lt;a href=&#34;#step-4-create-the-containers&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Step 4: Create the containers&lt;/h2&gt;&lt;p&gt;We&amp;rsquo;ll proceed in reverse order compared to how the Compose file is laid out, with the &lt;code&gt;database&lt;/code&gt;, &lt;code&gt;redis&lt;/code&gt; and &lt;code&gt;machine-learning&lt;/code&gt; containers first and &lt;code&gt;immich-server&lt;/code&gt; last.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the &lt;code&gt;database&lt;/code&gt; container section of the official Compose file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;database&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;immich_postgres&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${DB_PASSWORD}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;POSTGRES_USER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${DB_USERNAME}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;POSTGRES_DB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${DB_DATABASE_NAME}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;POSTGRES_INITDB_ARGS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;--data-checksums&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Uncomment the DB_STORAGE_TYPE: &amp;#39;HDD&amp;#39; var if your database isn&amp;#39;t stored on SSDs&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# DB_STORAGE_TYPE: &amp;#39;HDD&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;${DB_DATA_LOCATION}:/var/lib/postgresql/data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shm_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;128mb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;healthcheck&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First we create the container itself with the required environment variables:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus create &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    ghcr:immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    immich-postgres &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -c environment.POSTGRES_PASSWORD&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MySuperStrongPassword&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -c environment.POSTGRES_USER&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;postgres&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -c environment.POSTGRES_DB&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;immich&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -c environment.POSTGRES_INITDB_ARGS&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--data-checksums&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or, if like me you&amp;rsquo;d rather keep the environment in a separate file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cat &amp;gt; .postgres-env &lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;POSTGRES_PASSWORD=MySuperStrongPassword
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;POSTGRES_USER=postgres
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;POSTGRES_DB=immich
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;POSTGRES_INITDB_ARGS=--data-checksums
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus create &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    ghcr:immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    immich-postgres &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    --environment-file .postgres-env
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;admonition warning&#34;&gt;&lt;p class=&#34;admonition-title&#34;&gt;Warning&lt;/p&gt;
  Do &lt;em&gt;&lt;strong&gt;not&lt;/strong&gt;&lt;/em&gt; use quotes for the values inside the env file, as it leads to double-quoting and the container will fail to start: see my &lt;a href=&#34;https://github.com/lxc/incus/issues/3371&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;bug report&lt;/a&gt; (update: this was fixed while I was writing this post and is awaiting a release).
&lt;/div&gt;
&lt;p&gt;Then we attach the database volume to the created container:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus config device add immich-postgres pgdata disk &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;pool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich_postgres &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/var/lib/postgresql/data
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# or&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# incus storage volume attach local immich_postgres immich-postgres pgdata /var/lib/postgresql/data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As well as a &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/reference/devices_disk/#:~:text=tmpfs&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;tmpfs&lt;/a&gt; one to equate the &lt;code&gt;shm_size: 128mb&lt;/code&gt; from the Compose file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus config device add immich-postgres shm disk &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;tmpfs: &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;128MiB &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/shm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can launch our container and check its console output to make sure it started correctly:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus start immich-postgres
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus console immich-postgres --show-log
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I won&amp;rsquo;t repeat this last part for the next ones, but it is a good idea to check the console logs every time you start a new container (you can add &lt;code&gt;--console&lt;/code&gt; to &lt;code&gt;incus launch|start&lt;/code&gt; as well).&lt;/p&gt;
&lt;p&gt;The Redis/Valkey one is the simplest, going from:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;redis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;immich_redis&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;healthcheck&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;redis-cli ping || exit 1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus launch &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    docker:valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    immich-redis
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I set up the machine learning one without hardware acceleration, as IncusOS &lt;a href=&#34;https://github.com/lxc/incus-os/issues/992&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;doesn&amp;rsquo;t yet provide what is required at the host level&lt;/a&gt;, so any GPU acceleration which requires installing something on the host is &lt;a href=&#34;https://discuss.linuxcontainers.org/t/nvidia-drivers-not-enabled-after-installing-gpu-support/26434/2&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;only available inside VMs&lt;/a&gt;  with a GPU passthrough.&lt;/p&gt;
&lt;p&gt;Without it the container setup is pretty straightforward:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Create the container with its environment populated with the .env file content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus create &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    ghcr:immich-app/immich-machine-learning:v2 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    immich-ml &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    --environment-file .env
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Attach the model-cache volume&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus config device add immich-ml model-cache disk &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;pool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich-model-cache &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus start immich-ml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s finally time for the &lt;em&gt;pièce de résistance&lt;/em&gt;, &lt;code&gt;immich-server&lt;/code&gt; itself. This is where we need the extra environment variables for connecting to the other containers, so if you have already added them to the &lt;code&gt;.env&lt;/code&gt; file it is as simple as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus create &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    ghcr:immich-app/immich-server:v2 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    immich-server &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    --environment-file .env
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Otherwise you need to add the following to the previous command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -c environment.DB_HOSTNAME&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich-postgres.incus &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -c environment.REDIS_HOSTNAME&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich-redis.incus &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -c environment.IMMICH_MACHINE_LEARNING_URL&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://immich-ml.incus:3003
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For storage we have the all so important library/uploads volume:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus config device add immich-server uploads disk &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;pool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;immich-uploads &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To replicate the exposed port form the Compose file we can use a &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/reference/devices_proxy/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;proxy device&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus config device add immich-server web proxy &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;tcp:0.0.0.0:2283&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;tcp:127.0.0.1:2283&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will make sure to redirect connections on the host port 2283 to the container&amp;rsquo;s.&lt;/p&gt;
&lt;p&gt;Now we are finally ready to start it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;incus start immich-server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Check the logs to make sure everything is ok!&lt;/p&gt;
&lt;div class=&#34;admonition tip&#34;&gt;&lt;p class=&#34;admonition-title&#34;&gt;Tip&lt;/p&gt;
  &lt;p&gt;If you have &lt;a href=&#34;https://linuxcontainers.org/incus-os/docs/main/reference/system/network/#dns-ntp-timezone&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;set a different timezone&lt;/a&gt; in IncusOS (or on your regular OS where Incus is installed), you might want to replicate the bind mount of &lt;code&gt;/etc/localtime&lt;/code&gt;; however &lt;a href=&#34;https://github.com/lxc/lxc/issues/4697&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;liblxc prevents mounting over a symlink&lt;/a&gt;, and so starting the container with the host localtime mounted over the container&amp;rsquo;s one fails.&lt;/p&gt;
&lt;p&gt;Two possible workarounds: start the container without mounting &lt;code&gt;/etc/localtime&lt;/code&gt;, and either:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;delete the file inside the container and then mount it from the host via a disk device:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# make sure the container is started&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus start immich-server
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# delete the existing symlink&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; immich-server -- rm /etc/localtime
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# mount the file from the&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus config device add immich-server localtime disk &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;realpath /etc/localtime&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/etc/localtime &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nv&#34;&gt;readonly&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;overwrite the symlink inside the container with the desired timezone file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;incus exec immich-server -- ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Both workarounds will need to be reapplied anytime you rebuild/update the container.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;accessing-immich&#34;&gt;&lt;a href=&#34;#accessing-immich&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Accessing Immich&lt;/h2&gt;&lt;p&gt;Thanks to the proxy device, it is just a matter of opening &lt;code&gt;http://&amp;lt;server-ip&amp;gt;:2283&lt;/code&gt; in a browser (http&lt;strong&gt;s&lt;/strong&gt; doesn&amp;rsquo;t work) and completing the &lt;a href=&#34;https://docs.immich.app/install/post-install&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Post-Install setup&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was able to set up the mobile app on my phone and upload pictures right away, and it&amp;rsquo;s been running fine since then. Pretty nice!&lt;/p&gt;
&lt;h2 id=&#34;improvement-set-a-startstop-order&#34;&gt;&lt;a href=&#34;#improvement-set-a-startstop-order&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Improvement: set a start/stop order&lt;/h2&gt;&lt;p&gt;After restarting the server a few times, I noticed that because I didn&amp;rsquo;t set a &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/reference/instance_options/#instance-boot:boot.autostart.priority&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;boot.autostart.priority&lt;/code&gt;&lt;/a&gt; the containers were being started in parallel, which resulted in errors in &lt;code&gt;immich-server&lt;/code&gt; logs showing it was waiting on the &lt;code&gt;postgres&lt;/code&gt; one.&lt;/p&gt;
&lt;p&gt;Therefore I configured a start and stop priority for &lt;code&gt;immich-server&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;incus config &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; immich-server boot.autostart.priority&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; boot.stop.priority&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This benefits from the fact that &amp;ldquo;&lt;em&gt;Instances without a priority set will be started (with some parallelism) ahead of instances with a priority set&lt;/em&gt;&amp;rdquo;, which matches exactly what we want in this case: the three supporting containers should be started before &lt;code&gt;immich-server&lt;/code&gt; proper.&lt;/p&gt;
&lt;p&gt;We could also set &lt;a href=&#34;https://linuxcontainers.org/incus/docs/main/reference/instance_options/#instance-boot:boot.autorestart&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;boot.autorestart&lt;/code&gt;&lt;/a&gt; to &lt;code&gt;true&lt;/code&gt; so that &lt;code&gt;immich-server&lt;/code&gt; gets restarted up to 10 times over a minute in case of unexpected failure.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;I hope this will help some of you set up Immich &amp;ldquo;the hard way&amp;rdquo; on Incus/IncusOS! Let me know by &lt;a href=&#34;mailto:contact@esrevart.net&#34;&gt;email&lt;/a&gt; or on the &lt;a href=&#34;https://discuss.linuxcontainers.org/u/neitsab&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;forums&lt;/a&gt; if you have any feedback.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Remote rescue without a KVM</title>
      <link>https://bastientraverse.com/en/posts/2024-04/remote-rescue-sans-kvm/</link>
      <pubDate>Mon, 08 Apr 2024 00:00:00 +0200</pubDate>
      
      <guid>https://bastientraverse.com/en/posts/2024-04/remote-rescue-sans-kvm/</guid>
      <description>&lt;h2 id=&#34;context&#34;&gt;&lt;a href=&#34;#context&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Context&lt;/h2&gt;&lt;p&gt;I was looking for a way to get remote access to my laptop-turned-server even in the case the OS became unbootable (e.g. if I try to remotely encrypt the root and bork something), or more generally have a way to reinstall it from afar.&lt;/p&gt;
&lt;p&gt;In other words, I wanted to emulate the functionalities of a KVM/cloud shell, but on consumer hardware with no remote management functionalities (e.g. vPro).&lt;/p&gt;
&lt;h2 id=&#34;first-pass&#34;&gt;&lt;a href=&#34;#first-pass&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;First pass&lt;/h2&gt;&lt;p&gt;My first idea was to leave a USB drive containing a Live rescue system plugged into the laptop. The issue then becomes: how do I access the rescue environment?&lt;/p&gt;
&lt;p&gt;One has to find either a Live system with sshd enabled by default and a default password (risky), or make/customize one so that either user-configured credentials are used (e.g. an SSH public key) or some kind of tunnel is opened automatically from the live system (I was thinking about unattended Tailnet joining, but as it sounded quite more convoluted than a simple preconfigured SSH key I didn&amp;rsquo;t explore this path further).&lt;/p&gt;
&lt;p&gt;Searching for &amp;ldquo;live distro with ssh pre enabled&amp;rdquo; led me to two Q&amp;amp;A threads that proved quite useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://askubuntu.com/questions/821009/most-simple-way-to-create-a-bootable-usb-stick-for-headless-installation-with-ss&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://askubuntu.com/questions/821009/most-simple-way-to-create-a-bootable-usb-stick-for-headless-installation-with-ss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://unix.stackexchange.com/questions/43012/remote-accessible-live-distribution-aka-live-cd&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://unix.stackexchange.com/questions/43012/remote-accessible-live-distribution-aka-live-cd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some specific Live systems were mentioned for their easy configurability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Plop: &lt;a href=&#34;https://www.plop.at/en/ploplinux/live/faq.html#faq2&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://www.plop.at/en/ploplinux/live/faq.html#faq2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;grml: &lt;a href=&#34;http://blog.grml.org/archives/367-Create-a-Grml-ISO-image-with-your-own-ssh-keys-for-password-less-login.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;http://blog.grml.org/archives/367-Create-a-Grml-ISO-image-with-your-own-ssh-keys-for-password-less-login.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, I then discovered that my beloved Arch had cloud-init support baked into its regular ISO, which I am already familiar with and know to be very versatile, so I went for that.&lt;/p&gt;
&lt;h2 id=&#34;the-chosen-path&#34;&gt;&lt;a href=&#34;#the-chosen-path&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;The chosen path&lt;/h2&gt;&lt;p&gt;As usual the Arch Wiki didn&amp;rsquo;t disappoint, offering short and practical instructions on &lt;a href=&#34;https://wiki.archlinux.org/title/Install_Arch_Linux_via_SSH#Installation_on_a_headless_server&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;how to use cloud-init to configure user-defined SSH keys and repacking the Live ISO&lt;/a&gt; so that I could burn it to my USB drive.&lt;/p&gt;
&lt;div class=&#34;admonition tip&#34;&gt;&lt;p class=&#34;admonition-title&#34;&gt;Tip&lt;/p&gt;
  The &amp;ldquo;single ISO&amp;rdquo; method isn&amp;rsquo;t compatible with a default Ventoy configuration; it didn&amp;rsquo;t recognize the appended partition containing cloud-init data, and therefore it didn&amp;rsquo;t behave any different than the standard archiso. That&amp;rsquo;s why I went for burning the ISO to the drive.
&lt;/div&gt;
&lt;p&gt;After making sure I could SSH with my SSH key into the live system from the local network, I set up port redirection on the router to forward SSH requests to this machine (which I had already set up a static DHCP lease for previously).&lt;/p&gt;
&lt;p&gt;The last and trickiest part was: how to boot on the live system only in case it&amp;rsquo;s needed?&lt;/p&gt;
&lt;h2 id=&#34;deciding-on-the-boot-order&#34;&gt;&lt;a href=&#34;#deciding-on-the-boot-order&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Deciding on the boot order&lt;/h2&gt;&lt;p&gt;Configuring the firmware to always boot from the USB drive wouldn&amp;rsquo;t work, because unlike with a proper KVM I don&amp;rsquo;t have access to the bootloader screen to choose booting from the first drive/continuing to boot normally.&lt;/p&gt;
&lt;p&gt;I certainly can configure the next boot to use the USB drive just once by using &lt;code&gt;efibootmgr -n&lt;/code&gt;/&lt;code&gt;bootctl&lt;/code&gt; on the installed system, but what if the server isnt accessible anymore? Then game over, I either need a benevolent human or a domestic robot. Or, you know, pay hundreds of €€€ to fly there myself 😂&lt;/p&gt;
&lt;p&gt;In this case this laptop-server stays at some relatives&amp;rsquo; place, so I can rely on them to punctually press F2 to select a different boot entry.&lt;/p&gt;
&lt;p&gt;For those who are not so lucky, I cannot think of any other parry than going with something like a &lt;a href=&#34;https://jetkvm.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Jet&lt;/a&gt;/&lt;a href=&#34;https://pikvm.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;PiKVM&lt;/a&gt;; after all, this is exactly why server motherboard/CPUs usually come with remote management features like vPro.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;&lt;a href=&#34;#conclusion&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Even though it will require a third-party intervention for &lt;em&gt;abnormal&lt;/em&gt;/rescue situations, I am pretty happy I made this solution available on my setup. It provides some easy-to-trigger reassurance. Without it it&amp;rsquo;d feel like abandoning my brave laptop-turned-server to its own device (&lt;em&gt;ha!&lt;/em&gt;) in a chilly closet under the stairs, like an electronic Harry Potter&amp;hellip; This way at least, I feel like I can &lt;em&gt;care&lt;/em&gt; for it.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
