Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Help about MediaWiki
FUTO
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Introduction to a Self Managed Life: a 13 hour & 28 minute presentation by FUTO software
(section)
Main Page
Discussion
English
Read
Edit
Edit source
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
Edit source
View history
General
What links here
Related changes
Special pages
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
= Setting Up Immich: Google Photos/iCloud replacement = <span id="what-is-immich"></span> == What is immich? == Immich is like Google photos or iCloud, if you hosted it yourself; but better! It has the following features that make it stand out to me: <span id="why-immich"></span> == Why Immich? == <span id="insanely-fast"></span> ==== Insanely fast ==== '''Immich''' loads & scrolls through things on a core i3 NUC with an old SATA drive faster than '''nextcloud''' allowed me to on an i7-14700k with an NVME SSD. it’s snappy even on slower computers & phones. '''Nextcloud''' made the experience of browsing through images & photos not on my phone so bad I stopped doing it; a flagship phone and an i7-14700k, 64 GB of RAM, and a $400 SSD wasn’t good enough to make this usable. <span id="machine-learning-for-image-search"></span> ==== Machine learning for image search ==== I can type ''“cat on chair”'' and have every image of a cat on a chair show up. It actually works, it isn’t half assed and full of false positives. Immich’s machine learning features & included libraries are also used for '''face detection'''. Immich can sort your images by people, so you can see every image with your dad, cousin, girlfriend, ex-girlfriend, etc. You can [https://huggingface.co/immich-app choose the model you want to use]. The default model works best for me, but I appreciate Immich respecting my right to choose the model I want. Immich’s machine learning is done LOCALLY. '''Immich can be blocked from connecting to the internet and all machine learning & facial recognition will still work.''' When people hear the words ''“Artificial intelligence,”'' ''“cloud,”'' & ''“machine learning,”'' they hear buzzwords for processes which were supposed to be used for our benefit, but instead have become tools of data mining & abusive models. These are not bad things when they are done in a freedom-respecting way. I have no problem with machine learning algorithms going through all of my photos & videos & knowing the names of the people in my photos, because that information will never leave my computer. <span id="easy-proxies"></span> ==== Easy proxies ==== Immich supports video & image proxy files. Proxies are photos & videos that are further compressed. They are lower in quality, but their smaller size allows you to load them faster when you’re on a poor internet connection. I use a google pixel, so this is handy. Google pixels have horrible cellphone service & reception because Google is too stubborn to use Qualcomm modems. Google decided that its users care more about [https://www.reddit.com/r/GooglePixel/comments/1etk3l6/nothing_makes_me_less_excited_about_pixel_than/ lame AI features] than [https://www.reddit.com/r/GooglePixel/comments/x61kee/today_i_have_measured_just_how_bad_my_pixel_6s/ having working cell service]; This is where image proxies & video proxies come in handy. '''Nextcloud''' allows image proxies(with config file editing; ew). Immich allows both ''image'' AND ''video'' proxies, so high bitrate videos can still be loaded & viewed on slow internet. <span id="ease-of-use"></span> ==== Ease of use ==== This program is so easy to use you’ll almost forget you’re using GNU/Linux. When I set up my Nextcloud instance, I had to edit config files to get thumbnails to work. Further, nextcloud only allows ''image'' thumbnails, but not ''video'' proxies. Not only is it more work with nextcloud to get thumbnails & proxies so you have something that loads well on a slow connection - it’s not as functional. Everything here is doable within the web interface after installation, and it’s easy as can be. This program has the easiest installation & documentation I’ve found for this type of GNU/Linux software. It is useless for me to provide instructions here because [following Immich team’s instructions, this will all work perfectly(https://immich.app/docs/install/docker-compose/) with no confusion. Immich is as good as as bitwarden with regards to “just working” out of the box & a big part of why I fell in love with their progam. <span id="prerequisites-1"></span> == Prerequisites == Before starting, ensure you have: * Docker Compose version 2.x installed(you should’ve done this setting up onlyoffice on this VM earlier) * Docker installed from the official Docker repository(you should’ve done this setting up onlyoffice on this VM earlier) * Enough storage space for the photos & videos from your phone * Did I mention not to install docker using SNAP from the ubuntu install? Don’t do that. <span id="step-1-install-docker-properly."></span> === Step 1: Install docker properly. === <blockquote>'''NOTE:''' This step may not be necessary! </blockquote> **YOU DO NOT NEED TO PERFORM THIS STEP IF YOU INSTALLED DOCKER WHILE INSTALLING ONLYOFFICE. IF YOU INSTALLED DOCKER PRIOR TO INSTALLING ONLYOFFICE, SKIP THIS STEP! IF YOU DID NOT INSTALL ONLYOFFICE BECAUSE YOU DIDN’T WANT ONLYOFFICE, THAT MEANS YOU SKIPPED INSTALLING DOCKER AS WELL; IN WHICH CASE, YOU WILL NEED TO FOLLOW THESE INSTRUCTIONS. <span id="never-use-ubuntus-snap-version-of-docker-1"></span> ==== Never use Ubuntu’s snap version of docker ==== Ubuntu installs docker by default using the cancerous snap. We do not want to use snap. Ubuntu installer will ask if you want to install Docker, and you should always say No. <span id="doesnt-onlyoffices-install-script-install-docker-for-me-1"></span> ==== Doesn’t onlyoffice’s install script install docker for me? ==== Onlyoffice’s installation script '''DOES''' install docker for you. I am still going to have you do it manually. * If you choose to not install onlyoffice, and wish to install Immich, I want you to know how to install docker on this virtual machine ''yourself.'' * I don’t want to rely on onlyoffice’s script. It won’t install docker for us if it detects Docker already, so we’re not going to do a double install. What if onlyoffice’s installation script stops installing docker the same way in a new version, or stops installing docker at all within its script? It’s little work to install Docker the right way for our purposes manually, and it’s good to have it documented so that you can use docker for immich even if you elect not to install Onlyoffice. <span id="update-and-upgrade-your-system-3"></span> ==== 1.1 Update and upgrade your system ==== <pre>sudo apt update && sudo apt upgrade -y sudo apt install curl git wget -y</pre> <span id="check-for-other-docker-installations-2"></span> ==== 1.2 Check for other Docker installations: ==== Run <code>docker --version</code> and see what is installed. Nothing should be installed yet since this is a fresh system. If something is installed, remove it. <pre># Just in case you accidentally installed snap version of docker: sudo snap remove docker # For other versions of docker: sudo apt remove docker docker-engine docker.io containerd runc</pre> <span id="install-docker-using-official-docker-script-3"></span> ==== 1.3 Install Docker using official Docker script: ==== <pre>curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh</pre> <blockquote>'''Note:''' It’s very important to use the official Docker installation and not the Snap version. The Snap version can cause issues due to its sandboxed nature, making it a mess for mailcow’s requirements. Docker snap makes me sad, and it’ll make you sad too if you try to make things work with it. </blockquote> <span id="install-docker-compose-2"></span> ==== 1.4 Install Docker Compose: ==== Ubuntu’s <code>docker-compose-plugin</code> is safe to use, it is not snap cancer. <pre>sudo apt install docker-compose-plugin -y sudo systemctl enable --now docker</pre> <span id="verify-the-install-2"></span> ==== 1.5 Verify the install ==== Run <code>docker compose version</code> and make sure the version is 2.0 or higher. Run <code>docker --version</code> and make sure version is 24.0.0 or higher <span id="set-proper-permissions-3"></span> ==== 1.6 Set proper permissions: ==== Docker needs to be run as root for some operations, but you can add your user to the docker group to avoid using <code>sudo</code> all the time. To be clear, mailcow’s own [https://docs.mailcow.email/getstarted/install/#check-selinux-specifics documentation] and [https://community.mailcow.email/d/59-mailcow-containers-running-as-root community] suggest starting with root or <code>sudo</code>, and you should trust them more than me. To quote mailcow developers, ''“Controlling the Docker daemon as non-root user does not give you additional security. The unprivileged user will spawn the containers as root likewise. The behaviour of the stack is identical.”'' Run this command to add your user: <pre>sudo usermod -aG docker $USER</pre> Log out and log back in, or run: <code>newgrp docker</code> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:immichdiagrambad.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:immichok.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:immichdiagramgood.png </gallery> </div> <span id="step-2-understand-how-this-will-be-set-up-differently-from-stock-setup."></span> == Step 2: Understand how this will be set up differently from stock setup. == <span id="how-youre-supposed-to-use-immich"></span> ==== 2.1 How you’re supposed to use Immich ==== The stock setup of Immich, by default, is to have Immich upload your images & videos from your phone to the immich server. You control your library on your phone & on your server in the immich application. <span id="syncthing-conflict-with-immich"></span> ==== 2.2 Syncthing conflict with Immich ==== Didn’t we already set up syncthing to do this? Yes, we did! I don’t want to use Immich to sync my phone’s '''DCIM/Camera''' folder, and then syncthing for everything else. In my opinion, it doesn’t make sense to use Immich by itself to do this; Immich is for photos & videos, it is not for Music, Documents, & all the other folders on our phone. If we used syncthing for those files & folders, and used Immich for photos/videos, that means we have two applications running at the same time, that do the same thing. This means 2 points of failure rather than 1. Syncthing was designed with one purpose in mind; transfer files from device to device. I would prefer to use a tool that was designed for the job. As a result, I am going to set up the <code>~/androidbackup/DCIM</code> folder as an '''external library''' in Immich. <span id="attaching-zfs-pool-to-immich"></span> ==== 2.3 Attaching ZFS pool to Immich ==== See Also, remember the giant ZFS pool we created? On my setup, that’s over 100 terabytes of stuff! Much of that are old images & videos that are not in my phone photo backup directory. I want to see those in Immich. We created a Samba share for our ZFS pool so we could access it from elsewhere. I am going to create a '''read only''' samba share that is mounted on <code>~/Pictures</code>, and then set this up with Immich as a '''second external library.''' TL;DR - Immich will have access to everything stored in your ZFS pool archive as a photo library, as well as your android phone’s photos. This allows me to perform machine learning on everything; my android phone photo backups, current android phone photos, as well as all of my stuff from the past 15 years all within one piece of software. After this is done I will be able to use the search feature and find photos I forgot about within seconds, dating back 15 years. Awesome. :) <blockquote>'''QUESTION:''' Why do we want the zfs pool share to be read only? The '''androidstuff''' virtual machine that houses our syncthing backup of our android phone is going to be backed up regularly to our zfs pool. We have a copy of that being backed up every week. The entire ZFS pool, for me, is over 100 terabytes - so having version controlled backups is much more difficult. As a result, I am personally much more protective of the data on my zfs pool than I am the data on my androidphone backups. </blockquote> <span id="step-3-mount-a-read-only-samba-share-of-the-zfs-pool-for-immich-onto-the-androidstuff-virtual-machine"></span> == Step 3: Mount a read only samba share of the ZFS pool for Immich onto the androidstuff virtual machine == We are going to do the following: # On the '''happycloud''' host machine, create another samba share of our ZFS pool <code>/mediapool/archive</code> that is read only. # Mount this inside the '''androidstuff''' virtual machine on <code>~/Pictures</code> which is the Pictures subdirectory of my home directory. <code>~/</code> is shorthand for your home directory; in my case, <code>~/</code> is the same as <code>/home/louis/</code> <span id="modify-samba-configuration-on-happycloud-host-machine"></span> ==== 3.1 Modify samba configuration on happycloud host machine ==== SSH into the happycloud host machine: <pre>ssh louis@happycloud.home.arpa</pre> or <pre>ssh louis@192.168.5.2</pre> Our <code>/etc/samba/smb.conf</code> file currently looks like this: <pre>[global] # Network settings workgroup = HOME realm = home.arpa netbios name = happycloud server string = ZFS Archive Server dns proxy = no # Security settings security = user map to guest = bad user server signing = auto client signing = auto # Logging log level = 1 log file = /var/log/samba/%m.log max log size = 1000 # Performance optimization socket options = TCP_NODELAY IPTOS_LOWDELAY read raw = yes write raw = yes use sendfile = yes min receivefile size = 16384 aio read size = 16384 aio write size = 16384 # Multichannel support server multi channel support = yes # Disable unused services load printers = no printing = bsd printcap name = /dev/null disable spoolss = yes # Character/Unix settings unix charset = UTF-8 dos charset = CP932 [archive] comment = ZFS Archive Share path = /mediapool/archive valid users = louis invalid users = root browseable = yes read only = no writable = yes create mask = 0644 force create mode = 0644 directory mask = 0755 force directory mode = 0755 force user = louis force group = louis veto files = /._*/.DS_Store/.Thumbs.db/.Trashes/ delete veto files = yes follow symlinks = yes wide links = no ea support = yes inherit acls = yes hide unreadable = yes guest ok = no</pre> We are going to add something like this to the bottom of the <code>/etc/samba/smb.conf</code> file. Obviously '''feel free to set the <code>path</code> folder to what YOU want Immich to see'''. This will be read-only, so if something happens on your host, you won’t lost everything. Use nano to edit the file: <pre>sudo nano -w /etc/samba/smb.conf</pre> Enter the following at the end. Hit enter so there’s a pretty little space before the new section. :) <pre>[immich] comment = ZFS Archive Share (Read-Only) path = /mediapool/archive valid users = louis browseable = yes read only = yes guest ok = no create mask = 0644 directory mask = 0755 veto files = /._*/.DS_Store/.Thumbs.db/.Trashes/ delete veto files = yes follow symlinks = yes wide links = no ea support = yes inherit acls = yes hide unreadable = yes</pre> <span id="configure-the-samba-share-on-the-androidstuff-virtual-machine"></span> ==== 3.2 Configure the samba share on the androidstuff virtual machine ==== We want this to mount each time the '''androidstuff''' virtual machine that will run Immich boots. To do this, we will edit <code>/etc/fstab</code> - the file that defines where hard drives, partitions, network shares, are mounted on the filesystem. We have to install the packages that allow us to mount samba shares: <pre>sudo apt install cifs-utils -y</pre> Edit the file: <pre>sudo nano -w /etc/fstab</pre> Add the following line: <pre>//192.168.5.2/immich /home/louis/Pictures cifs ro,credentials=/etc/samba_credentials,iocharset=utf8,vers=3.0 0 0</pre> Make sure that the IP address matches the IP address of the machine that you have your ZFS pool on. * <code>//192.168.5.2</code> is the address of the computer that is running samba server for our samba share. ** <code>immich</code> is the name of the samba share. ** In '''happycloud'''’s’ <code>/etc/samba/smb.conf</code> configuration file, the line<code>path = /mediapool/archive</code> is present under the <code>[immich]</code> share settings. ** Therefore, `<code>//192.168.5.2/immich</code> will show us <code>/mediapool/archive</code> on the machine located at <code>192.168.5.2</code> * <code>cifs</code> is the filesystem type. CIFS stands for '''Common Internet File System'''. * <code>ro</code> means readonly. * <code>/etc/samba_credentials</code> is the file that will house the username & password to access this share. * For the love of god, do not forget to set the proper permissions on the<code>/etc/samba_credentials</code> file when I tell you to. Once you’re done adding that line to the file, we need to provide it a username/password so it can log into the password protected share. <pre># Create the credentials file that will house the username & password: sudo nano -w /etc/samba_credentials</pre> Add your username and password you set when you set the password for your samba user to the file in the following format: <pre>username=louis password=passwordman</pre> If you forgot what the samba password is for your user, refer to '''step 6.5''' in the '''Setting up ZFS for data storage''' portion of the guide. '''Make sure that this file is not accessible by anyone besides root!''' <pre>sudo chown root /etc/samba_credentials sudo chmod 600 /etc/samba_credentials</pre> <span id="set-the-permissions-for-samba-credentials-file"></span> ==== 3.3 Set the permissions for samba credentials file ==== Important enough to be worth stating again: <pre>sudo chown root /etc/samba_credentials sudo chmod 600 /etc/samba_credentials</pre> ----- <span id="mount-the-samba-share-on-the-androidstuff-virtual-machine"></span> ==== 3.4 Mount the samba share on the androidstuff virtual machine ==== Run the following to mount everything in the <code>/etc/fstab</code> file, including your samba share. <pre>sudo mount -a sudo systemctl daemon-reload</pre> <span id="make-sure-it-worked."></span> ==== 3.5 Make sure it worked. ==== In <code>/home/louis/Pictures</code>on the '''androidstuff''' virtual machine you should see everything that is on <code>/mediapool/archive</code> on the '''happycloud''' host server. Try making a file and saving it there. It shouldn’t work. Create a file on happycloud. Go to the terminal window for happycloud, or just ssh in if you don’t have one open. <pre>ssh louis@happycloud.home.arpa # Put a file called hello_world.log that says "hi" inside of it into the /mediapool/archive directory echo "hi" > /mediapool/archive/helloworld.log</pre> Then, on the '''androidstuff''' virtual machine, try to view it. We mounted this samba share on <code>/home/louis/Pictures</code> so <code>hello_world.log</code> should show up on <code>/home/louis/Pictures/hello_world.log</code> <pre>louis@androidstuff:~$ cat helloworld.log louis@androidstuff:~$ cat ~/Pictures/helloworld.log hi louis@androidstuff:~$ rm ~/Pictures/helloworld.log rm: remove write-protected regular file '/home/louis/Pictures/helloworld.log'? y rm: cannot remove '/home/louis/Pictures/helloworld.log': Read-only file system louis@androidstuff:~$ sudo rm ~/Pictures/helloworld.log [sudo] password for louis: rm: cannot remove '/home/louis/Pictures/helloworld.log': Read-only file system </pre> As you can see, I can see the file, I can read the file, but I can’t delete the file. Perfect. <span id="step-4-make-your-directories"></span> == Step 4: Make your directories == <span id="create-directory-structure"></span> ==== 4.1 Create Directory Structure ==== I like to put the programs I am downloading/working on in <code>/home/louis/Downloads/programs</code> The <code>~/</code> means your home directory: so if your username is chris, <code>~/Downloads/programs</code> means <code>/home/chris/Downloads/programs</code> <pre># Create and enter directory mkdir -p ~/Downloads/programs/immich-app cd ~/Downloads/programs/immich-app</pre> <span id="download-program"></span> ==== 4.2 Download Program ==== This is installed via docker and the installation files/instructions from Immich themselves are completely plug & play. a <pre># Get docker-compose.yml wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml # Get environment file wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env</pre> <span id="optional-hardware-acceleration-files"></span> ==== 4.3 Optional Hardware Acceleration Files ==== I don’t use hardware acceleration since my machine does not have a GPU, or any sort of coral device. This is experimental as well so it may give you issues. However, if you plan to use hardware acceleration, grab these to set them up & [https://immich.app/docs/features/ml-hardware-acceleration/ follow the instructions from Immich documentation]. <pre># For transcoding acceleration wget -O hwaccel.transcoding.yml https://github.com/immich-app/immich/releases/latest/download/hwaccel.transcoding.yml # For machine learning acceleration wget -O hwaccel.ml.yml https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml</pre> <span id="step-5-edit-docker-compose.yml-environment-file"></span> == Step 5: Edit docker-compose.yml & Environment File == <span id="edit-the-.env-file"></span> ==== 5.1 Edit the <code>.env</code> file ==== <pre>nano -w .env</pre> <ol style="list-style-type: decimal;"> <li><p>'''Database Setting'''</p> <ul> <li>Change <code>DB_PASSWORD</code> . You should use characters from A to Z, a to z, and 0 to 9 - don’t use anything funky. I recommend the [https://bitwarden.com/password-generator/#password-generator Bitwarden password generator]. <ul> <li>You can use bitwarden password generator on their website without installing their program, but I suggest installing their program at some point.</li></ul> </li></ul> </li> <li><p>'''Upload Location'''</p> <ul> <li><p>Set <code>UPLOAD_LOCATION</code> to where you want items you upload to immich to go.</p> <p>-I don’t use this because I use syncthing to upload things to <code>/home/louis/androidbackup</code>** rather than uploading straight to immich.</p></li> <li><p>For the purposes of how I use Immich & this guide, I will not be changing this.</p></li></ul> </li> <li><p>'''Timezone'''</p> <ul> <li>Uncomment and set the <code>TZ=</code> line to your timezone.</li> <li>Find timezone codes [https://en.wikipedia.org/wiki/List_of_tz_database_time_zones here]</li> <li>For example, mine would be <code>America/Chicago</code></li></ul> </li></ol> <span id="edit-the-docker-compose.yml-file"></span> ==== 5.2 Edit the <code>docker-compose.yml</code> file ==== Open the file for editing: <pre>nano -w docker-compose.yml</pre> This file in its entirety is fine as is. Nothing has to be changed. The two lines I add are to allow immich access to the <code>~/Pictures</code> directory where my ZFS pool’s files are located, and the <code>~/androidbackup/DCIM</code> directory where the photos & videos I took using the camera app on my android phone are stored. The two lines I added to the file below are: <pre> - /home/louis/androidbackup/DCIM:/files/phonepics:rw - /home/louis/Pictures:/files/zfspics:ro</pre> These lines do the following: * Makes <code>/home/louis/androidbackup/DCIM</code> on the host computer Immich is running on show up as <code>/files/phonepics</code> inside the docker container for Immich, with read write permissions. * Makes <code>/home/louis/Pictures</code> on the host computer Immich is running on show up as <code>/files/zfspics</code> inside the docker container for Immich, with read only permissions. To see where I put these in the context of the full file, look below: <pre># # WARNING: Make sure to use the docker-compose.yml of the current release: # # https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml # # The compose file on main may not be compatible with the latest release. # name: immich services: immich-server: container_name: immich_server image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} # extends: # file: hwaccel.transcoding.yml # service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding volumes: # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file - ${UPLOAD_LOCATION}:/usr/src/app/upload - /etc/localtime:/etc/localtime:ro - /home/louis/androidbackup/DCIM:/files/phonepics:rw - /home/louis/Pictures:/files/zfspics:ro env_file: - .env ports: - '2283:2283' depends_on: - redis - database restart: always healthcheck: disable: false immich-machine-learning: container_name: immich_machine_learning # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag. # Example tag: ${IMMICH_VERSION:-release}-cuda image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration # file: hwaccel.ml.yml # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable volumes: - model-cache:/cache env_file: - .env restart: always healthcheck: disable: false redis: container_name: immich_redis image: docker.io/redis:6.2-alpine@sha256:2ba50e1ac3a0ea17b736ce9db2b0a9f6f8b85d4c27d5f5accc6a416d8f42c6d5 healthcheck: test: redis-cli ping || exit 1 restart: always database: container_name: immich_postgres image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: ${DB_DATABASE_NAME} POSTGRES_INITDB_ARGS: '--data-checksums' volumes: # 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 - ${DB_DATA_LOCATION}:/var/lib/postgresql/data healthcheck: test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1 interval: 5m start_interval: 30s start_period: 5m command: [ 'postgres', '-c', 'shared_preload_libraries=vectors.so', '-c', 'search_path="$$user", public, vectors', '-c', 'logging_collector=on', '-c', 'max_wal_size=2GB', '-c', 'shared_buffers=512MB', '-c', 'wal_compression=on', ] restart: always volumes: model-cache:</pre> <blockquote>'''DOCKER CHEAT SHEET: going through <code>docker-compose.yml</code> file for Immich''' This file sets up a bunch of containers''(virtualized, minimalistic computers that run inside your computer)'' for the Immich photo gallery/library/machine learning & management system. '''1. <code>name: immich</code>''' This is the name of the overall Docker Compose project. '''2. <code>services:</code>''' This section lists all the containers (services) that make up the Immich application. Each service is a part of the overall program. '''immich-server''' '''3. <code>immich-server:</code>''' This is the primary backend service of Immich. It handles the main functions of the program like uploading, managing, & displaying photos. '''4. <code>container_name: immich_server</code>''' This is the name of the container so when you run <code>docker ps -a</code> to see what containers are running you can see this one and know what it is for immediately. Custom name for the main immich container so it is easy to find when you type <code>docker ps -a</code> . Sometimes while debugging things that are not working you may want to enter the environment of the virtual container''(this is like sshing into your server, but into the virtual server that runs immich)'', which you can do by typing <code>docker exec -it immich_server bash</code> - but to do that you need to know which container is which! This is where using sensible names comes into play. '''5. <code>image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}</code>''' This tells it what Docker image to use for the backend. It pulls the latest stable version unless you’ve overridden <code>IMMICH_VERSION</code> in your <code>.env</code> file. Since Immich does not destroy their software with new releases, I am setting it to grab the latest version. '''6. <code>volumes:</code>''' * <code>${UPLOAD_LOCATION}:/usr/src/app/upload</code>: Links the photo upload storage location from your system to the container. The path <code>${UPLOAD_LOCATION}</code> is defined in the <code>.env</code> file. Whatever this is will show up inside the container at <code>/usr/src/app/upload</code> * <code>/etc/localtime:/etc/localtime:ro</code>: This makes the container use the same time as your computer’s time. The <code>:ro</code> makes it read-only so your computer can’t do what the characters in predestination did. The only thing worse than using google photos is '''''SPOILER ALERT''''' having your machine send you back in time so you are an orphan who was its own mother like in '''Predestination'''. Still a decent time travel movie but it has nothing on '''Primer'''. * <code>/home/louis/androidbackup/DCIM:/files/phonepics:rw</code>: Maps a directory with phone pictures to <code>/files/phonepics</code> in the container. This is read-write (<code>rw</code>). SO whatever is inside my <code>/home/louis/androidbackup/DCIM</code> directory on the <code>androidstuff</code> virtual machine running at <code>192.168.5.5</code> that we set up will show up inside the <code>immich-server</code> docker container under the directory <code>/files/phonepics</code>. * <code>/home/louis/Pictures:/files/zfspics:ro</code>: Maps a directory with other pictures to <code>/files/zfspics</code> in the container. This one is read-only (<code>ro</code>). '''7. <code>env_file:</code>''' Loads environment variables from the <code>.env</code> file, which centralizes configuration settings. '''8. <code>ports:</code>''' * <code>'2283:2283'</code>: Maps port <code>2283</code> on your host system to port <code>2283</code> in the container. This allows you to access Immich’s server on your browser at <code>http://192.168.5.5:2283</code> since we are installing this dockerized deployment of Immich to the <code>androidstuff</code> virtual machine located at <code>192.168.5.5</code> '''9. <code>depends_on:</code>''' This lists the services this container depends on. <code>redis</code> and <code>database</code> must be running before the server starts. Don’t be scared by the word depends. It is included in ''“dependency”'', but you’re using a docker image deployed by good developers; dependencies are no longer something to be afraid of :) I promise :) '''10. <code>restart: always</code>''' Automatically restarts the container if it crashes or if the system reboots. When you turn the system on immich will be on without having to go to its directory & run <code>docker compose up -d</code> each time the computer starts. '''11. <code>healthcheck:</code>''' Monitors the container’s health. The <code>disable: false</code> line means health checks are enabled. '''immich-machine-learning''' '''12. <code>immich-machine-learning:</code>''' This container handles machine learning tasks, like face or object recognition''(searching for “cat on chair”)'' in your photos. '''13. <code>container_name: immich_machine_learning</code>''' Custom name for the machine learning container so it is easy to find when you type <code>docker ps -a</code> . Sometimes while debugging things that are not working you may want to enter the environment of the virtual container''(this is like sshing into your server, but into the virtual server that runs immich)'', which you can do by typing <code>docker exec -it immich_machine_learning bash</code> - but to do that you need to know which container is which! This is where using sensible names comes into play. '''14. <code>image:</code>''' Pulls the machine learning image from GitHub. You can enable hardware acceleration by adding a specific tag (e.g., <code>-cuda</code>) if supported by your system. '''15. <code>volumes:</code>''' * <code>model-cache:/cache</code>: Links a Docker-managed volume to the container’s <code>/cache</code> directory for storing machine learning model data. '''16. <code>env_file:</code>''' Loads environment variables from <code>.env</code> for consistent configuration. For instance, instead of editing certain configuration files after or while setting up/compiling the program, you put them in the environment file and when the docker container starts, it uses what is in the environment file. '''17. <code>restart: always</code>''' The container restarts if it crashes & will start up with the computer. '''18. <code>healthcheck:</code>''' Keeps the container healthy and ensures it’s running properly. '''redis''' '''19. <code>redis:</code>''' Redis is a high-speed database used for caching data and managing background tasks. '''20. <code>container_name: immich_redis</code>''' Custom name for the Redis container so it is easy to find when you type <code>docker ps -a</code> . Sometimes while debugging things that are not working you may want to enter the environment of the virtual container''(this is like sshing into your server, but into the virtual server that runs immich)'', which you can do by typing <code>docker exec -it immich_redis bash</code> - but to do that you need to know which container is which! This is where using sensible names comes into play. '''21. <code>image:</code>''' Specifies the exact Redis image to use, including a SHA256 checksum for security. '''22. <code>healthcheck:</code>''' Runs a simple test (<code>redis-cli ping</code>) to confirm the Redis service is working. '''23. <code>restart: always</code>''' Automatically restarts Redis if it fails/it starts with the computer. '''database''' '''24. <code>database:</code>''' This is the PostgreSQL database, which stores metadata and application data for Immich. '''25. <code>container_name: immich_postgres</code>''' Custom name for the database container so it is easy to find when you type <code>docker ps -a</code> . Sometimes while debugging things that are not working you may want to enter the environment of the virtual container''(this is like sshing into your server, but into the virtual server that runs immich)'', which you can do by typing <code>docker exec -it immich_postgres bash</code> - but to do that you need to know which container is which! This is where using sensible names comes into play. '''26. <code>image:</code>''' Specifies a custom PostgreSQL image with vector support, used by Immich for advanced search features. '''27. <code>environment:</code>''' - <code>POSTGRES_PASSWORD</code>: Password for the database. - <code>POSTGRES_USER</code>: Username for the database. - <code>POSTGRES_DB</code>: Name of the database. - <code>POSTGRES_INITDB_ARGS</code>: Additional arguments for database '''28. <code>volumes:</code>''' * <code>${DB_DATA_LOCATION}:/var/lib/postgresql/data</code>: Maps the database storage location from your system to the container. Edit <code>${DB_DATA_LOCATION}</code> in the <code>.env</code> file to change where your database files are stored. '''29. <code>healthcheck:</code>''' Runs periodic checks to ensure the database is healthy. It verifies that the database is running, accessible, and free of checksum errors. '''30. <code>command:</code>''' Customizes PostgreSQL’s behavior with specific options, like enabling vector indexing (<code>shared_preload_libraries=vectors.so</code>) & improving performance with optimized settings like <code>max_wal_size=2GB</code>. '''31. <code>restart: always</code>''' Makes database container restart if something goes wrong/it starts with the computer. '''volumes''' '''32. <code>volumes:</code>''' - <code>model-cache</code>: A named volume for storing machine learning models. This ensures that cached data persists across container restarts or recreations. </blockquote> <span id="step-5-start-the-system"></span> == Step 5: Start the System == While in the directory you downloaded the <code>docker-compose.yml</code> and <code>.env</code> file to, run the following: <pre>docker compose up</pre> I like to type <code>docker compose up</code> at first without the <code>-d</code> because I can see what is happening without having to use tail on a logfile somewhere. If you don’t care to do that, you can start it up like this with the <code>-d</code> which allows the program to start without it stopping when you close the terminal window you ran the command in. <pre>docker compose up -d</pre> '''Visiting Immich web interface''': at this point you should be able to visit <code>http://192.168.5.5:2283</code> or <code>http://androidstuff.home.arpa:2283</code> and see Immich, in all its glory :) <span id="if-it-doesnt-work"></span> == If it doesn’t work: == # '''Wrong Docker Version''' If you get <code>unknown shorthand flag: 'd' in -d</code>, you’re likely using the wrong Docker version. Fix by: #* Remove the distribution’s docker.io package. If you used snap, I will hurt you. #* Install Docker from the official repository #* If you used ubuntu version of docker installed via snap upon installation of ubuntu server after all the times I told you not to in the past 1000 pages of this guide….. #* You asked for this. # '''Docker Compose Command''' #* Use <code>docker compose</code> (not <code>docker-compose</code>) #* Installing from Docker official repository is required here. You saw how to do this in the onlyoffice setup section on this virtual machine. <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114081931118.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114081943465.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114081947837.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114081952635.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082104266.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082148529.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082040918.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082203688.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082215711.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082308766.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082636100.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082702362.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114082732250.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114083349204.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114102736005.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085055146.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085114634.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085134227.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085158141.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085215897.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085323218.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085419575.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114102843677.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085501334.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114103219273.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085653523.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085749209.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085900361.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085939405.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114085956763.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114090009152.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114090053347.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114103825099.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114104024871.png </gallery> </div> <span id="step-6-configure-immich"></span> == Step 6: Configure Immich == Once it’s started it’ll ask you to set up a username and a password. Once that’s done, we have a few tasks to complete. <span id="set-up-your-android-backup-zfs-pool-as-libraries-in-immich"></span> ==== 6.1 Set up your android backup & zfs pool as libraries in Immich ==== This is necessary so you can see your files. <ol style="list-style-type: decimal;"> <li><p>Click the circle in the upper right corner that has the first letter of your username.</p></li> <li><p>Click '''Administration'''</p></li> <li><p>Click '''External Libraries''' on the left menu</p></li> <li><p>Click on the plus or on the '''Create Library''' button in the upper right to create a library.</p></li> <li><p>Create two libraries: and set yourself as the owner of each.</p></li> <li><p>Click on the three dots next to the library.</p></li> <li><p>Click '''Rename'''</p></li> <li><p>Name each library - (e.g. '''zfs pool''' and '''android phone'''.)</p></li> <li><p>Click the three dots again and click '''Edit Import Paths'''</p></li> <li><p>Set each external library to have the path we chose above for our zfs pool and our android phone backup. <code>- /home/louis/androidbackup/DCIM:/files/phonepics:rw - /home/louis/Pictures:/files/zfspics:ro</code></p></li> <li><p>Once done with this, go back to '''Settings''' in the left hand menu</p></li> <li><p>Go to '''Video Transcoding Settings'''</p></li> <li><p>If you want video proxies created so you are watching lower bitrate files when you load immich(useful if you use this on a phone with bad internet speeds), change '''Transcode policy''' to '''All videos'''</p> <blockquote><p>'''NOTE:''' Transcoding videos doesn’t delete the original. It creates new videos in a subfolder of the <code>immich-app</code> directory. The original video file is preserved in full quality in its original location.</p></blockquote></li> <li><p>If you have a fast computer, or lots of patience, set '''Preset''' to '''fast''' - this will make video files that are smaller for the same quality as '''ultrafast'''. For '''Constant Rate Factor''', higher is smaller file/worse quality, lower number is larger file/better quality. If you are making video proxies because your internet service sucks I’d set this to 28.</p></li> <li><p>In '''Settings''', go over to '''External Library'''</p></li> <li><p>Under '''Library Watching''' enable '''Watch external libraries for file changes'''</p></li> <li><p>Under '''Periodic Scanning''' Make sure this is turned on. I would make this something daring; perhaps once an hour. Remember, since we are not using the Immich app to upload the photos to Immich, Immich is not aware without scanning manually if we have added files or not.</p></li> <li><p>On the left hand menu, go over to '''Jobs'''.</p></li> <li><p>Next to '''LIBRARY''', click the ALL button.</p></li> <li><p>Wait patiently.</p></li> <li><p>You’re done. :)</p></li></ol> <span id="step-7-enjoy-immich"></span> == Step 7: Enjoy Immich == Once the '''Jobs''' tab shows that Immich is done processing everything, head over to the homepage, and try the search box. It’s awesome. <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114111713397.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114111737760.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114111751348.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114112125953.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114112154974.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114114756999.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114115240120.png </gallery> </div> <div class="figure"> <gallery mode="packed-hover" heights=250 widths=400 perrow=2> File:image-20241114115256590.png </gallery> </div> <span id="step-8-install-android-app"></span> == Step 8: Install Android App == <span id="install-the-f-droid-store-app"></span> ==== 8.1 Install the F-Droid store app ==== Download F-Droid from the [https://f-droid.org/docs/Get_F-Droid/ F-Droid website] and then open the apk to install it. F-Droid allows you to downlod all sorts of interesting open source apps. <span id="install-immich"></span> ==== 8.2 Install Immich ==== Find & install Immich <span id="start-immich"></span> ==== 8.3 Start Immich ==== When you start Immich, in the '''Server Endpoint URL''' field, but the same thing you put in your web browser to connect; <code>http://192.168.5.5:2283</code> or <code>http://androidstuff.home.arpa:2283</code> Don’t forget to put the port. Also, this will only work on local wifi or with your VPN on from your smartphone. '''Make sure you are connected to wifi or are connected to the VPN!''' <span id="notes-on-upgradesupdates"></span> === Notes on upgrades/updates: === * ''“Breaking changes”'' are when an old version of Immich will not work properly when updating to a new version of immich. * Review release notes to see if this is the case with your version. This is something that is being worked on so it won’t happen in the future. Alex is great with informing users on these changes. <span id="update-process"></span> === Update Process === To upgrade to a new version, go to the directory with Immich, in our case, <code>~/Downloads/programs/immich-app</code>. Turn Immich off, pull the new version, and then turn it on again. '''I suggest having a backup of everything before doing this.''' Doing perfect VM backups will be in the next section. <pre>cd ~/Downloads/programs/immich-app docker compose down docker compose pull docker compose up -d</pre> <span id="nextcloud-notes-to-replace-google-keep"></span>
Summary:
Please note that all contributions to FUTO may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
FUTO:Copyrights
for details).
Do not submit copyrighted work without permission!
To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:
Cancel
Editing help
(opens in new window)