<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Server on Bastien Traverse</title>
    <link>https://bastientraverse.com/en/tags/server/</link>
    <description>Recent content in Server 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/server/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>Optimized cloud-init templates on Proxmox</title>
      <link>https://bastientraverse.com/en/posts/2024-10/proxmox-optimized-cloud-init-templates/</link>
      <pubDate>Fri, 04 Oct 2024 00:00:00 +0200</pubDate>
      
      <guid>https://bastientraverse.com/en/posts/2024-10/proxmox-optimized-cloud-init-templates/</guid>
      <description>&lt;p&gt;There are already quite a few resources out there demonstrating how to create a cloud-init enabled VM template in Proxmox. Here are the ones I mainly used to discover the topic, and which I suggest you go through because what follows depends on them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Proxmox &lt;a href=&#34;https://pve.proxmox.com/wiki/Cloud-Init_FAQ&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;FAQ&lt;/a&gt;, &lt;a href=&#34;https://pve.proxmox.com/wiki/Cloud-Init_Support&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;wiki&lt;/a&gt; and mostly identical &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_cloud_init&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;official documentation&lt;/a&gt; on Cloud-Init support&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/shiIi38cJe4&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Perfect Proxmox Template with Cloud Image and Cloud Init&lt;/a&gt; (YouTube, Techno Tim 2022-03)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What those and many similar resources give are step-by-step instructions divided in as many commands to facilitate understanding. What I haven&amp;rsquo;t seen so far though, is an &lt;em&gt;all-in-one, optimized&lt;/em&gt; command to do the same thing, so here&amp;rsquo;s my contribution to the field:&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;qm create &lt;span class=&#34;m&#34;&gt;1000&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;    --name debian12-cloud &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;    --description &lt;span class=&#34;s2&#34;&gt;&amp;#34;Debian 12 cloud-init template&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;    --template &lt;span class=&#34;m&#34;&gt;1&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;    --ostype l26 &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;    --machine q35 &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;    --cpu host &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;    --cores &lt;span class=&#34;m&#34;&gt;2&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;    --memory &lt;span class=&#34;m&#34;&gt;4096&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;    --balloon &lt;span class=&#34;m&#34;&gt;512&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;    --scsihw virtio-scsi-single &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;    --scsi0 local-lvm:0,import-from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/path/to/debian-12-generic-amd64.qcow2,discard&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;on,iothread&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1,ssd&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&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;    --net0 virtio,bridge&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;vmbr0 &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;    --tablet &lt;span class=&#34;m&#34;&gt;0&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;    --rng0 &lt;span class=&#34;nv&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/urandom &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;    --boot &lt;span class=&#34;nv&#34;&gt;order&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;scsi0 &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;    --vga serial0 --serial0 socket &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;    --ide2 local-lvm:cloudinit &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;    --ciuser myuser &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;    --cipassword changeme &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;    --sshkey /path/to/your-public.key &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;    --ciupgrade &lt;span class=&#34;m&#34;&gt;0&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;    --ipconfig0 &lt;span class=&#34;nv&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;dhcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The same thing as a one-liner for the latest Ubuntu:&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;qm create &lt;span class=&#34;m&#34;&gt;2000&lt;/span&gt; --name ubuntu-server-2404-cloud --description &lt;span class=&#34;s2&#34;&gt;&amp;#34;Ubuntu Server 24.04 cloud-init template&amp;#34;&lt;/span&gt;  --template &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; --ostype l26 --machine q35 --cpu host --cores &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; --memory &lt;span class=&#34;m&#34;&gt;4096&lt;/span&gt; --balloon &lt;span class=&#34;m&#34;&gt;512&lt;/span&gt; --scsihw virtio-scsi-single --scsi0 local-lvm:0,import-from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/path/to/ubuntu-24.04-server-cloudimg-amd64.img,discard&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;on,iothread&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1,ssd&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; --net0 virtio,bridge&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;vmbr0 --rng0 &lt;span class=&#34;nv&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/urandom --tablet &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; --boot &lt;span class=&#34;nv&#34;&gt;order&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;scsi0 --vga serial0 --serial0 socket --ide2 local-lvm:cloudinit --ciuser myuser --cipassword changeme --sshkey /path/to/your-public.key --ciupgrade &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; --ipconfig0 &lt;span class=&#34;nv&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;dhcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that you cannot copy-paste those blindly, you have to adjust a few parameters to your local environment (especially the VMID, disk image and SSH key paths).&lt;/p&gt;
&lt;p&gt;Follows a description of relevant options at the exclusion of self-evident ones (&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;cores&lt;/code&gt;, &lt;code&gt;memory&lt;/code&gt;&amp;hellip;), as well as some possible variations you might want.&lt;/p&gt;
&lt;h3 id=&#34;generic-options&#34;&gt;&lt;a href=&#34;#generic-options&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Generic options&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;qm create 1000&lt;/code&gt;: the Proxmox CLI command to create a VM. Replace &lt;code&gt;1000&lt;/code&gt; by the VMID of your choice (must be ≥ 100)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--template 1&lt;/code&gt;: directly convert the created VM to a template&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;performance-related-options&#34;&gt;&lt;a href=&#34;#performance-related-options&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Performance related options&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--ostype l26&lt;/code&gt;: hint to optimize for a Linux 2.x-6.x-based system&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--machine q35&lt;/code&gt;: use a modern &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_machine_type&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;machine type&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--cpu host&lt;/code&gt;: pass-through the host &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#_cpu_type&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CPU type&lt;/a&gt; to make all its features available in the VM&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--balloon 512&lt;/code&gt;: when set to a lower value than &lt;code&gt;memory&lt;/code&gt;, enables &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_memory&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;dynamic memory allocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--scsihw virtio-scsi-single&lt;/code&gt;: the most performant &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_hard_disk&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;SCSI controller&lt;/a&gt;, especially when combined with &lt;code&gt;iothread=1&lt;/code&gt; (see next point)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--scsi0 local-lvm:0,import-from=/path/to/debian-12-generic-amd64.qcow2,iothread=1,discard=on,ssd=1&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;import (&lt;em&gt;i.e.&lt;/em&gt; copy) the referenced cloud image as the VM disk
&lt;ul&gt;
&lt;li&gt;replace &lt;code&gt;/path/to/&lt;/code&gt; with the full path to where you downloaded the cloud image (which you should have already done by now if you have followed the resources linked above 😉)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;configure it with performance (&lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_hard_disk_iothread&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;IO Thread&lt;/a&gt;), &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_hard_disk_discard&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;thin-provisioning&lt;/a&gt; and SSD-optimized settings
&lt;ul&gt;
&lt;li&gt;remove &lt;code&gt;discard=on&lt;/code&gt; and/or &lt;code&gt;ssd=1&lt;/code&gt; if not applicable to your storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--tablet 0&lt;/code&gt;: one of the lesser-known performance tips but one of the most important! &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_options&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Disables the USB tablet device&lt;/a&gt; only needed when connecting via the integrated console to guests with a GUI (&lt;em&gt;e.g.&lt;/em&gt; Ubuntu Desktop). Reported to have a &lt;a href=&#34;https://reddit.com/r/homelab/comments/q1m383/a_small_but_useful_tip_for_proxmox_users/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;big performance impact&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rng0 source=/dev/urandom&lt;/code&gt; (optional): provides a &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_virtio_rng&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;virtual hardware random number generator&lt;/a&gt; to get entropy from the host system (can speed things up during the first boot)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Up to here were performance-related options applicable to all VM templates, not only cloud-init ones. Here comes the cloud-init specific bits:&lt;/p&gt;
&lt;h3 id=&#34;cloud-init-related-options&#34;&gt;&lt;a href=&#34;#cloud-init-related-options&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Cloud-init related options&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--boot order=scsi0&lt;/code&gt;: apparently &lt;a href=&#34;https://pve.proxmox.com/wiki/Cloud-Init_Support#_preparing_cloud_init_templates&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;speeds up booting&lt;/a&gt; for cloud-init enabled images&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--vga serial0 --serial0 socket&lt;/code&gt;: creates the serial connection &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_cloud_init&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;expected by most cloud images&lt;/a&gt; in their &amp;ldquo;native&amp;rdquo; cloud environments; also useful to monitor and troubleshoot the boot process via the Proxmox console
&lt;ul&gt;
&lt;li&gt;verified to work with Debian 12 and Ubuntu 24.04 server  cloud images; remove if causing issues with the image you&amp;rsquo;re using&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--ide2 local-lvm:cloudinit&lt;/code&gt;: creates the required cloud-init &amp;ldquo;CD-ROM&amp;rdquo; drive&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--ciuser myuser&lt;/code&gt; (optional): provides a custom username for the user account provisioned by cloud-init; without it the account name will depend on the distribution&amp;rsquo;s default (&lt;code&gt;debian&lt;/code&gt; for Debian, &lt;code&gt;ubuntu&lt;/code&gt; for Ubuntu&amp;hellip; Check your cloud image docs about this)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--cipassword changeme&lt;/code&gt; (optional): generally not needed nor recommended, but useful for quickly making sure everything is all right the first few times over; afterwards use a SSH key instead&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--sshkey /path/to/your-public.key&lt;/code&gt; (&lt;strong&gt;required&lt;/strong&gt; if not setting a password): the authorized SSH public key that will be placed in the user account created by cloud-init&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--ciupgrade 0&lt;/code&gt; (optional): disable automatically upgrading packages during first boot; useful to speed things up during testing, afterwards remove it/set it to &lt;code&gt;1&lt;/code&gt; (the default) if you want &amp;ldquo;always fresh&amp;rdquo; clones (which is probably a smart choice)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--ipconfig0 ip=dhcp&lt;/code&gt;: cloud-init in Proxmox doesn&amp;rsquo;t have a network configuration by default, so use this to let DHCP handle it or use something like &lt;code&gt;--ipconfig0 ip=10.0.10.123/24,gw=10.0.10.1&lt;/code&gt; for static config. Can be done later for each VM individually, just don&amp;rsquo;t leave it empty otherwise they won&amp;rsquo;t have any network by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you already have &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#_custom_cloud_init_configuration&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;custom cloud-init snippets&lt;/a&gt;, specify them via &lt;code&gt;--cicustom &amp;quot;user=&amp;lt;volume&amp;gt;,network=&amp;lt;volume&amp;gt;,meta=&amp;lt;volume&amp;gt;&amp;quot;&lt;/code&gt;, &lt;em&gt;e.g.&lt;/em&gt; &lt;code&gt;--cicustom &amp;quot;user=local:snippets/user-config.yaml&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you do, &lt;strong&gt;make sure you have the equivalents of the Proxmox cloud-init options above set in your custom config&lt;/strong&gt;, because &lt;a href=&#34;https://forum.proxmox.com/threads/proxmox-ignores-custom-cloud-init-from-cicustom-paramter-tested-with-ubuntu-centos.78070/#post-346322&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;using a custom user snippet overrides the complete user config set in the GUI or config&lt;/a&gt;! Yeah I know, it sucks and it&amp;rsquo;s not documented, boo Proxmox.&lt;/p&gt;
&lt;p&gt;Fortunately, as mentioned in the docs the GUI config can be dumped to serve as a base for custom configs:&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;qm cloudinit dump &lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt; user
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;qm cloudinit dump &lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt; network
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;admonition info&#34;&gt;&lt;p class=&#34;admonition-title&#34;&gt;Note&lt;/p&gt;
  Unlike Proxmox&amp;rsquo; implementation, when using &lt;code&gt;--cicustom&lt;/code&gt; and in the absence of network configuration, the image&amp;rsquo;s &lt;code&gt;cloud-init&lt;/code&gt; process will generate a network configuration that will issue a DHCP request on a “first” network interface. So if DHCP is what you want, you don&amp;rsquo;t have to supply a &lt;code&gt;&amp;quot;network:...&amp;quot;&lt;/code&gt; snippet besides the &lt;code&gt;&amp;quot;user:...&amp;quot;&lt;/code&gt; one.
&lt;/div&gt;
&lt;h2 id=&#34;post-creation-steps&#34;&gt;&lt;a href=&#34;#post-creation-steps&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Post-creation steps&lt;/h2&gt;&lt;p&gt;The only thing that cannot be done in the same step (due to using &lt;code&gt;import-from&lt;/code&gt;) is resizing the disk image. I personally prefer doing it on the cloned VMs rather than on the template itself to reduce cloning time and adjust the size depending on the VM&amp;rsquo;s needs, but there is also a case to be made to do it on the template directly.&lt;/p&gt;
&lt;p&gt;So in my case I first clone the template to a new VM:&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;qm clone &lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;150&lt;/span&gt; --full --name &lt;span class=&#34;s2&#34;&gt;&amp;#34;debian12-cloud&amp;#34;&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;&lt;p class=&#34;admonition-title&#34;&gt;Note&lt;/p&gt;
  &lt;p&gt;Besides being generally recommended for VMs you will keep around, it seems we can only use a &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_copy_and_clone&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;full clone&lt;/a&gt; when using &lt;code&gt;--scsihw virtio-scsi-single&lt;/code&gt; as without the  &lt;code&gt;--full&lt;/code&gt; option I get:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Linked clone feature is not supported for drive &#39;scsi0&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;YMMV.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Then expand its disk size:&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;qm resize &lt;span class=&#34;m&#34;&gt;150&lt;/span&gt; scsi0 15G
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then we&amp;rsquo;re ready to fire up the VM!&lt;/p&gt;
&lt;div class=&#34;admonition tip&#34;&gt;
  Double-click on the VM name (or on the &amp;ldquo;Console&amp;rdquo; button at the top right) instead of going through the integrated VM-specific menu &amp;ldquo;Console&amp;rdquo; element, because the pop-up window it opens can be resized fullscreen and allows to scroll back the buffer and read the boot log if necessary.
&lt;/div&gt;
&lt;p&gt;After checking everything works, you may want to stop and destroy this test VM:&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;qm stop &lt;span class=&#34;m&#34;&gt;150&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;qm destroy &lt;span class=&#34;m&#34;&gt;150&lt;/span&gt; --purge --destroy-unreferenced-disks &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now you can do the final adjustments to your template (&lt;em&gt;e.g.&lt;/em&gt; remove &lt;code&gt;--cipassword&lt;/code&gt;, &lt;code&gt;--ciupgrade 0&lt;/code&gt; etc.) and you are ready to rock the cloud-init lifestyle in Proxmox! ☁️🤘🕺&lt;/p&gt;
&lt;h2 id=&#34;uefi-variant&#34;&gt;&lt;a href=&#34;#uefi-variant&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;UEFI variant&lt;/h2&gt;&lt;p&gt;Generally I try to use as modern a stack as is reasonable, because software written in the last few years is more likely to be tested with it than a more legacy stack.&lt;/p&gt;
&lt;p&gt;But I have realized that &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_bios_and_uefi&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;UEFI&lt;/a&gt; is much less commonplace in virtualized environments than on bare metal, making it less tested and I&amp;rsquo;d say, slightly less supported overall (case in point: it&amp;rsquo;s still not the default in QEMU/Proxmox).&lt;/p&gt;
&lt;p&gt;However it is easy enough to use it in our templates by adding the following options:&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;--bios ovmf --efidisk0 local-lvm:0,efitype&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;4m,size&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;4M,pre-enrolled-keys&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The only thing to note is that &lt;code&gt;pre-enrolled-keys=0&lt;/code&gt; disables Secure Boot, which trips up all the distros that don&amp;rsquo;t want to play the Microsoft game (Arch Linux being a notable one for me). Leave the parameter out or switch its value to &lt;code&gt;1&lt;/code&gt; for a Secure Boot-enabled template (confirmed working with Ubuntu for example)!&lt;/p&gt;
&lt;h2 id=&#34;the-qemu-guest-agent-conundrum&#34;&gt;&lt;a href=&#34;#the-qemu-guest-agent-conundrum&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;The QEMU Guest Agent conundrum&lt;/h2&gt;&lt;p&gt;By default, no cloud images I know of come with &lt;code&gt;qemu-guest-agent&lt;/code&gt; preinstalled, but it&amp;rsquo;s &lt;a href=&#34;https://pve.proxmox.com/wiki/Qemu-guest-agent&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pretty&lt;/a&gt; &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_qemu_agent&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;useful&lt;/a&gt; on Proxmox.&lt;/p&gt;
&lt;p&gt;To install it in your cloud images, you basically have two options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install and use libguestfs&amp;rsquo; &lt;a href=&#34;https://libguestfs.org/virt-customize.1.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;virt-customize&lt;/a&gt; to the cloud images themselves, as illustrated &lt;a href=&#34;https://totaldebug.uk/posts/proxmox-template-with-cloud-image-and-cloud-init/#install-packages&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;in this random blog post I found&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Let cloud-init do it during the first boot of each cloned VM using a &lt;a href=&#34;https://pve.proxmox.com/pve-docs/chapter-qm.html#_custom_cloud_init_configuration&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;custom cloud-init snippet&lt;/a&gt;: see &lt;a href=&#34;https://superuser.com/a/1787022&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;this SuperUser answer&lt;/a&gt; for an example. The required lines to add to your &lt;code&gt;user-config.yaml&lt;/code&gt; are:&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;c&#34;&gt;#cloud-config&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;nn&#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;package_update&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;true&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;packages&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;l&#34;&gt;qemu-guest-agent&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&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;runcmd&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;l&#34;&gt;systemctl enable --now qemu-guest-agent&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;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Remember that using a custom user snippet &lt;a href=&#34;https://forum.proxmox.com/threads/proxmox-ignores-custom-cloud-init-from-cicustom-paramter-tested-with-ubuntu-centos.78070/#post-346322&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;overrides the complete user config set in the GUI or config&lt;/a&gt;, so those lines must be added to your complete user snippet!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this case add &lt;code&gt;--cicustom &amp;quot;user=local:snippets/user-config.yaml&amp;quot;&lt;/code&gt; and&lt;code&gt;--agent 1,fstrim_cloned_disks=1&lt;/code&gt; when creating the template (see &lt;a href=&#34;https://pve.proxmox.com/pve-docs/qm.1.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;the docs&lt;/a&gt; for details).&lt;/p&gt;
&lt;h2 id=&#34;tips--tricks&#34;&gt;&lt;a href=&#34;#tips--tricks&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Tips &amp;amp; tricks&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;don&amp;rsquo;t use Debian &lt;code&gt;genericcloud&lt;/code&gt; image: its kernel is optimized for Azure &amp;amp; AWS environments and in my tests, didn&amp;rsquo;t work with Proxmox. I had started with this one (being fooled by the wording on &lt;a href=&#34;https://cdimage.debian.org/images/cloud/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;the download page&lt;/a&gt; (&amp;quot;&lt;em&gt;genericcloud: Similar to generic. Should run in any virtualised environment. Is smaller than &lt;code&gt;generic&lt;/code&gt; by excluding drivers for physical hardware&lt;/em&gt;&amp;quot;), spent quite a bit of time troubleshooting the VM booting but cloud-init not kicking in, until I eventually tried the &lt;code&gt;generic&lt;/code&gt; image where everything worked perfectly. &lt;a href=&#34;https://wiki.debian.org/Cloud/#What_is_the_difference_between_the_generic_and_genericcloud_images.3F&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;The Debian wiki&lt;/a&gt; actually sets the record straight:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The generic image uses Debian&amp;rsquo;s standard Linux kernel packages, while the genericcloud image uses the cloud kernel build. The cloud kernel disables a large number of device drivers and primarily targets the Amazon EC2 and Microsoft Azure VM device models. It may be usable in other environments, but for maximum compatibility we recommend using the generic images.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While troubleshooting I&amp;rsquo;ve seen plenty of other reports of people having issues making the &lt;code&gt;genericcloud&lt;/code&gt; image work with Proxmox, while it worked for some others&amp;hellip; &lt;code&gt;generic&lt;/code&gt; is the reliable, consistant option. &amp;rsquo;nough said!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;you can get Proxmox to display &lt;code&gt;.qcow2&lt;/code&gt; images alongside regular &lt;code&gt;.iso&lt;/code&gt; in its GUI, by simply suffixing/replacing their extension with &lt;code&gt;.img&lt;/code&gt; (like Ubuntu does). It&amp;rsquo;s a regex issue ¯\_(ツ)_/¯&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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>
    
    <item>
      <title>Graphical management interfaces for Linux servers</title>
      <link>https://bastientraverse.com/en/posts/2023-12/server-management-gui/</link>
      <pubDate>Mon, 11 Dec 2023 00:00:00 +0100</pubDate>
      
      <guid>https://bastientraverse.com/en/posts/2023-12/server-management-gui/</guid>
      <description>&lt;h2 id=&#34;terminology-considerations&#34;&gt;&lt;a href=&#34;#terminology-considerations&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Terminology considerations&lt;/h2&gt;&lt;p&gt;&amp;ldquo;&lt;em&gt;Server management interface&lt;/em&gt;&amp;rdquo;, &amp;ldquo;&lt;em&gt;control panel&lt;/em&gt;&amp;rdquo;, &amp;ldquo;&lt;em&gt;dashboard&lt;/em&gt;&amp;rdquo;&amp;hellip; While investigating Free and Open Source graphical server management software, I had trouble establishing the categorical difference between the different solutions I was reading about.&lt;/p&gt;
&lt;p&gt;My use case being a &amp;ldquo;single user homelab/server&amp;rdquo; and not a multi-tenancy reseller/web hosting solution, I initially left aside the well established category of &lt;a href=&#34;https://www.linode.com/docs/guides/how-to-choose-a-control-panel/#what-is-a-control-panel&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;control panels&lt;/a&gt; (with the exception of HestiaCP).&lt;/p&gt;
&lt;p&gt;The projects that caught my interest were &lt;a href=&#34;https://cockpit-project.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cockpit&lt;/a&gt;, &lt;a href=&#34;https://hestiacp.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;HestiaCP&lt;/a&gt;, &lt;a href=&#34;https://www.portainer.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Portainer&lt;/a&gt;, &lt;a href=&#34;https://caprover.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CapRover&lt;/a&gt;, &lt;a href=&#34;https://casaos.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CasaOS&lt;/a&gt;, &lt;a href=&#34;https://www.cloudron.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cloudron&lt;/a&gt;, and to a lesser extent, &lt;a href=&#34;https://github.com/SelfhostedPro/Yacht&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Yacht&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But try as I might, I just couldn&amp;rsquo;t wrap my head around what precisely distinguished them. Of course I could see that they had different focus: some were more sysadmin/general server management-oriented while others were more app- and Docker-oriented; but I lacked a general &lt;em&gt;category theory&lt;/em&gt; for them.&lt;/p&gt;
&lt;p&gt;My search-fu not yielding anything relevant, I thought I&amp;rsquo;d probe ChatGPT about it. This resulted in a most enlightening conversation, as it answered with a distinction that felt like a Eureka moment to me:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The solutions you&amp;rsquo;ve mentioned, including Portainer, HestiaCP, CapRover, CasaOS, Cloudron, and Yacht, represent a different category of software compared to the &lt;strong&gt;server management tools&lt;/strong&gt; like Cockpit, Webmin, Ajenti, and others.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It then went on to provide the following breakup:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Server Management Tools&lt;/strong&gt; (e.g. Cockpit, Webmin, Ajenti):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Purpose:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Primarily focused on server administration and configuration.&lt;/li&gt;
&lt;li&gt;Provide a broad range of controls over system settings, users, and services.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Complexity:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Varies from beginner-friendly to advanced, catering to users with different skill levels.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Interface Type:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Often web-based but can include desktop GUI options.&lt;/li&gt;
&lt;li&gt;Aimed at managing servers directly, not specifically for application or container orchestration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scalability:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Typically suitable for small to large enterprises.&lt;/li&gt;
&lt;li&gt;Designed for overall server management, including security, networking, and system configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Community Support:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Active open-source communities provide support and contribute to feature development.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integration:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Extensive third-party module or plugin support for customization.&lt;/li&gt;
&lt;li&gt;May include features for managing server-wide tasks and configurations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Application and Container Orchestration Tools&lt;/strong&gt; (e.g. Portainer, HestiaCP, CapRover, CasaOS, Cloudron, Yacht):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Purpose:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Focused on managing and orchestrating applications, containers, and services.&lt;/li&gt;
&lt;li&gt;Streamlined for deploying and managing web applications and services in containerized environments.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Complexity:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Typically designed to be user-friendly, catering to developers and administrators with varying skill levels.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Interface Type:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Primarily web-based interfaces, emphasizing container and application management.&lt;/li&gt;
&lt;li&gt;Often include features for easy deployment, scaling, and monitoring of applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scalability:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Suited for small to medium-scale applications and services.&lt;/li&gt;
&lt;li&gt;Designed for ease of use in deploying and managing containerized applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Community Support:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Active communities, often developer-focused, providing support and contributing to the development of container-related features.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integration:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Strong integration with containerization technologies (e.g., Docker, Kubernetes).&lt;/li&gt;
&lt;li&gt;Emphasis on managing application stacks, updating applications, and maintaining service availability.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the content of some categories don&amp;rsquo;t really fit their header (&lt;em&gt;e.g.&lt;/em&gt; &amp;ldquo;Interface Type&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;HestiaCP is lumped in the &amp;ldquo;Application and Container Orchestration Tools&amp;rdquo; category, despite its &lt;a href=&#34;https://hestiacp.com/features.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;features&lt;/a&gt; being arguably more control panel-y/towards server management.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is to just highlight the very reasonable limits of ChatGPT (3.5), in what was otherwise a super useful answer.&lt;/p&gt;
&lt;h2 id=&#34;coming-up-with-a-unified-categorization&#34;&gt;&lt;a href=&#34;#coming-up-with-a-unified-categorization&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Coming up with a unified categorization&lt;/h2&gt;&lt;p&gt;I kept poking at the prompt until I managed to formulate a General Category Theory of Server Management Graphical User Interfaces™, inclusive of control panels and &lt;em&gt;mere&lt;/em&gt; dashboards. Here&amp;rsquo;s the result:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The terms &amp;ldquo;server management tools&amp;rdquo;, &amp;ldquo;control panels&amp;rdquo;, &amp;ldquo;application and container orchestration tools&amp;rdquo; and &amp;ldquo;server dashboards&amp;rdquo; are sometimes used interchangeably, but they often refer to different aspects of managing and monitoring servers. Here&amp;rsquo;s how you can distinguish between them:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Server Management Tools:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose:&lt;/strong&gt; Server management tools are software applications designed to facilitate the configuration, administration, and monitoring of servers. They offer a range of features for tasks such as user management, service configuration, and system monitoring.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope:&lt;/strong&gt; Server management tools encompass a broad set of functionalities related to overall server administration, configuration, and maintenance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples:&lt;/strong&gt; Cockpit, Webmin, Ajenti and ISPConfig are examples of server management tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Control Panels:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose:&lt;/strong&gt; Control panels are specialized interfaces that provide centralized control over specific server functionalities, often in a web-based environment. They are designed to simplify the management of specific server aspects, such as web hosting, email services, or database management.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope:&lt;/strong&gt; Control panels are more focused and may not cover all aspects of server management. They often excel in specific use cases and are user-friendly for individuals who may not have extensive server administration experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples:&lt;/strong&gt; HestiaCP, Froxlor and Virtualmin are examples of control panels.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Application and Container Orchestration Tools&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose:&lt;/strong&gt; These tools aim to streamline application deployment, scale applications automatically to handle varying workloads, provide centralized management for containers, and automate various aspects of deployment and updates, ultimately enhancing overall efficiency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope:&lt;/strong&gt; Their scope includes container orchestration, service discovery, load balancing, health monitoring, and automated rollbacks and updates. They focus on managing and coordinating the deployment, scaling, and operation of application containers in a containerized environment, ensuring seamless and efficient operations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: Portainer, CapRover and Yacht are examples of application and container orchestration tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Server Dashboards:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose:&lt;/strong&gt; Server dashboards are visual representations of real-time or historical server data, allowing users to monitor key metrics and performance indicators. They provide a quick overview of the server&amp;rsquo;s health and status.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope:&lt;/strong&gt; Dashboards are primarily focused on providing visibility into server performance metrics and may not offer the same depth of configuration and administration features as management tools or control panels.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples:&lt;/strong&gt; Grafana, Kibana, and custom dashboards created using tools like Prometheus or Nagios are examples of server dashboards.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In summary, while there is some overlap in functionality, server management tools generally provide a comprehensive set of features for overall server administration. Control panels are more specialized, focusing on specific server functionalities. Application and container orchestration tools are geared towards managing and orchestrating applications and containers, ensuring efficient deployment, scaling, and maintenance. Server dashboards, on the other hand, offer visual representations of server performance metrics for monitoring purposes. The choice between them depends on the specific needs and preferences of the user or organization.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, even though ChatGPT kind of threw my FOSS requirement to the wind by mentioning famous proprietary panels (that I replaced here), all in all I feel like we did a great job coming up with a good &lt;em&gt;typology of graphical, general purpose GNU/Linux server management solutions&lt;/em&gt; (what a mouthful 😅).&lt;/p&gt;
&lt;h2 id=&#34;category-members&#34;&gt;&lt;a href=&#34;#category-members&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Category members&lt;/h2&gt;&lt;p&gt;Now that our categories are well defined, it is time to flesh them out by filling them with our candidates!&lt;/p&gt;
&lt;p&gt;Without further ado, here&amp;rsquo;s a curated list with stuff somewhat beyond my initial use case:&lt;/p&gt;
&lt;h3 id=&#34;server-management-tools&#34;&gt;&lt;a href=&#34;#server-management-tools&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Server Management Tools:&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://cockpit-project.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cockpit Project&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; LGPL 2.1&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Web-based server administration and monitoring.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Beginner to Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for both SMEs and large enterprises.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Growing community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Focus on integration with systemd and containers.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/cockpit-project/cockpit&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.webmin.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Webmin&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; BSD&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Comprehensive web-based server configuration and management.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Varies from beginner-friendly to advanced.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs and large enterprises.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Extensive third-party module support.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/webmin/webmin&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://ajenti.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Ajenti&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; AGPLv3&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Web-based server administration with support for plugins.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Supports various plugins for extended functionality.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ajenti/ajenti&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ispconfig.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ISPConfig&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; BSD&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; All-in-one server management panel.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate to Advanced.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs and large enterprises.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Strong support for multi-server setups.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/servisys/ispconfig_setup&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://zentyal.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Zentyal&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; GPLv2&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Linux Small Business Server.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Offers a wide range of server modules.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/zentyal/zentyal&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;web-hostingcontrol-panels&#34;&gt;&lt;a href=&#34;#web-hostingcontrol-panels&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Web hosting/Control Panels&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://hestiacp.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;HestiaCP&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; GPLv3&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Web hosting control panel.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Manages website hosting, email services, and server configurations.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/hestiacp/hestiacp&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.froxlor.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Froxlor&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; GPL&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Server management panel with a focus on web hosting and server administration.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Manages web hosting, domain configurations, and server settings.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Froxlor/Froxlor&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.virtualmin.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Virtualmin&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; GPL&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Web hosting control panel with a focus on managing virtual hosts.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Manages website hosting, email services, and server configurations.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/virtualmin/virtualmin&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt; &lt;em&gt;(Note: Virtualmin is primarily available through its official website, and its source code is available on GitHub for specific components.)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://cyberpanel.net/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CyberPanel&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; GPL&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Web hosting control panel with a focus on performance and security.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Manages website hosting, email services, and server configurations.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/usmannasir/cyberpanel&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt; &lt;em&gt;(Note: CyberPanel is primarily available through its official website, and its source code is available on GitHub.)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://alternc.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;AlternC&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; GPLv3&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Web hosting control panel with a focus on environmental responsibility.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/AlternC/AlternC&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;applicationcontainer-orchestration-tools&#34;&gt;&lt;a href=&#34;#applicationcontainer-orchestration-tools&#34; class=&#34;headerlink anchor&#34;&gt;&lt;i class=&#34;iconfont icon-link&#34;&gt;&lt;/i&gt;&lt;/a&gt;Application/Container Orchestration Tools:&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.portainer.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Portainer&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; AGPLv3&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Docker container management.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Beginner to Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Manages Docker containers with a user-friendly interface.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/portainer/portainer&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://caprover.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CapRover&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; Apache License 2.0&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Automated deployment for web apps.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Beginner to Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Focus on automated deployment of web applications.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/caprover/caprover&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://casaos.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CasaOS&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; AGPLv3&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Server management and automation.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Provides server management and automation features.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/casaos/casaos&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.cloudron.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Cloudron&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; Proprietary&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Self-hosted web app platform.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Beginner to Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Manages self-hosted web applications.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://git.cloudron.io/cloudron&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/SelfhostedPro/Yacht&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Yacht&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;License:&lt;/strong&gt; MIT&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Purpose:&lt;/em&gt; Docker management with a focus on simplicity.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Complexity:&lt;/em&gt; Beginner to Intermediate.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interface Type:&lt;/em&gt; Web-based.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Scalability:&lt;/em&gt; Suitable for SMEs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Community Support:&lt;/em&gt; Active community.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Integration:&lt;/em&gt; Simplifies Docker container management.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/SelfhostedPro/Yacht&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now it&amp;rsquo;s experimentation time! 🥳&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PS: If you need even more, &lt;a href=&#34;https://medevel.com/os-server-control-panel/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here is a random article&lt;/a&gt; listing 30 similar solutions including many dashboards.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
