1
0
mirror of https://github.com/funkypenguin/geek-cookbook/ synced 2025-12-13 09:46:23 +00:00

Tidy up blog section (a bit)

Signed-off-by: David Young <davidy@funkypenguin.co.nz>
This commit is contained in:
David Young
2023-02-07 17:19:22 +13:00
parent 13cdf16a04
commit 364e96f279
21 changed files with 95 additions and 442 deletions

View File

@@ -0,0 +1,8 @@
---
description: CHANGELOG - What's new in the cookbook
---
# CHANGELOG
This category lists the posts which highlight new and improved recipes in Funky Penguin's Geek Cookbook. The idea is that subscribing to the [RSS feed](/rss/) will provide automatic notification of fresh recipes!
--8<-- "common-links.md"

View File

@@ -0,0 +1,8 @@
---
description: Funky Penguin's notes-in-progress
---
# Notes
Sometimes you discover something which doesn't fit neatly into the "recipe" format. That's what this category of blog posts is for. I note information I don't want to loose, but I don't know (yet) how to fit it into the structure of the cookbook.
--8<-- "common-links.md"

View File

@@ -0,0 +1,7 @@
---
description: My reviews of popular self-hosted apps
---
I love experimenting with new self-hosted tools. Typically I'll review a tool while creating a recipe, although popular enough tools (*like [Plex][plex]*) don't **need** a review, in which case I'll just jump straight into the recipe!
--8<-- "common-links.md"

View File

@@ -1,7 +1,7 @@
# Funky Penguin's Geek Cookblog
Welcome to the Funky Blog!
Welcome to Funky Penguin's Blog!
After years of trying to use alternate platforms (*❤️ ya, [Ghost](../recipes/ghost.md) ! 👻*), I've given up and decided to move my technical blog entries here instead - I prefer the way [mkdocs-material](https://squidfunk.github.io/mkdocs-material/) lets me format documentation for technical consumption!
After years of trying to use alternate platforms (*I still ❤️ ya, [Ghost](/recipes/ghost/) ! 👻*), I've decided to move my technical blog entries here instead - I **far** prefer the way [mkdocs-material](https://squidfunk.github.io/mkdocs-material/) lets me format documentation for technical consumption!
--8<-- "common-links.md"

View File

@@ -8,14 +8,17 @@ links:
- Mastodon Review: review/mastodon.md
- Mastodon Kubernetes recipe: recipes/kubernetes/mastodon.md
- Mastodon Docker Swarm recipe: recipes/mastodon.md
description: New Docker Swarm Recipe - Mastodon - Federated social network. Think "like twitter but also like email"
---
# New Recipe: Mastodon - Federated social network. Think "like twitter but also like email"
# New Mastodon recipe (swarm)
New recipe - Mastodon, like Twitter on the Fediverse. Check out the [Docker Swarm recipe][mastodon]!
<!-- more -->
![Mastodon Screenshot](/images/mastodon.png){ loading=lazy }
Mastodon is an open-source, federated (*i.e., decentralized*) social network, inspired by Twitter's "microblogging" format, and used by upwards of 6.4M early-adopters, to share links, pictures, video and text.
--8<-- "common-links.md"
--8<-- "common-links.md"

View File

@@ -4,11 +4,10 @@ categories:
- CHANGELOG
tags:
- pixelfed
links:
- Get Support!: support.md
description: Pixelfed is like a self-hosted Instagram on the Fediverse. Here's a Docker Swarm recipe!
---
# New Recipe: Pixelfed - Federated image sharing. Think "looks like instagram, works like Mastodon"
# Added Pixelfed (swarm) Federated image sharing
New recipe - Pixelfed, like Instagram on the Fediverse. Check it out [here](/docs/recipes/pixelfed/)

View File

@@ -6,14 +6,18 @@ tags:
- kavita
links:
- Kavita recipe: recipes/kavita.md
description: New Recipe Added - Kavita - "Rocket-fueled" reader for manga/comics/ebooks, able to save reading position across devices/sessions
image: /images/kavita.png
---
# New Recipe: Kavita - "Rocket-fueled" reader for manga/comics/ebooks, able to save reading position across devices/sessions
# Added recipe for Kavita (swarm)
So you've just watched a bunch of superhero movies, and you're suddenly inspired to deep-dive into the weird world of comic books? You're already rocking AutoPirate with Mylar and NZBGet to grab content, but how to manage and enjoy your growing collection?
<!-- more -->
![Screenshot of application]({{ page.meta.image }}){ loading=lazy }
[Kavita Reader][kavita] is a "rocket fueled self-hosted digital library which supports a vast array of file formats". Primarily used for cosuming Manga (but quite capable of managing ebooks too), Kavita's killer feature is an OPDS server for integration with other mobile apps such as Chunky on iPad, and the ability to save your reading position across multiple devices.
--8<-- "common-links.md"

View File

@@ -8,14 +8,17 @@ links:
- Mastodon Review: review/mastodon.md
- Mastodon Kubernetes recipe: recipes/kubernetes/mastodon.md
- Mastodon Docker Swarm recipe: recipes/mastodon.md
description: New Kubernetes Recipe - Mastodon - Federated social network. Think "like twitter but also like email"
# image: /images/mastodon.png
---
# New Recipe: Mastodon - Federated social network. Think "like twitter but also like email"
New recipe - Mastodon, like Twitter on the Fediverse. Check out the [Kubernetes recipe][k8s/mastodon]!
<!-- more -->
![Mastodon Screenshot](/images/mastodon.png){ loading=lazy }
Mastodon is an open-source, federated (*i.e., decentralized*) social network, inspired by Twitter's "microblogging" format, and used by upwards of 6.4M early-adopters, to share links, pictures, video and text.
--8<-- "common-links.md"
--8<-- "common-links.md"

View File

@@ -1,21 +0,0 @@
---
date: 2022-11-10
categories:
- CHANGELOG
tags:
- immich
links:
- Get Support!: support.md
---
# New Review: Immich
New recipe - Pixelfed, like Instagram on the Fediverse. Check it out [here](/docs/recipes/pixelfed/)
<!-- more -->
[Pixelfed](https://pixelfed.org) is a free and ethical, open-source, federated (*i.e., decentralized*) social image sharing platform. As [Mastodon][mastodon] is to Twitter, so Pixelfed is to Instagram. Pixelfed uses the ActivityPub protocol, allowing users to interact with other users (*on other servers*) within the protocol, such as Mastodon, PeerTube, and Friendica, making Pixelfed a part of the Fediverse.
Much like Mastodon, Pixelfed implements chronological timelines with no implementation of content manipulation algorithms and is privacy-focused with no third party analytics or tracking. It only allows users over 16 years old to use.
--8<-- "common-links.md"

View File

@@ -1,24 +0,0 @@
---
date: 2022-11-10
categories:
- CHANGELOG
tags:
- mastodon
links:
- Mastodon Review: review/mastodon.md
- Mastodon Kubernetes recipe: recipes/kubernetes/mastodon.md
- Mastodon Docker Swarm recipe: recipes/mastodon.md
- Get Support!: support.md
---
# New Review: Mastodon
New recipe - Pixelfed, like Instagram on the Fediverse. Check it out [here](/docs/recipes/pixelfed.md)
<!-- more -->
[Pixelfed](https://pixelfed.org) is a free and ethical, open-source, federated (*i.e., decentralized*) social image sharing platform. As [Mastodon][mastodon] is to Twitter, so Pixelfed is to Instagram. Pixelfed uses the ActivityPub protocol, allowing users to interact with other users (*on other servers*) within the protocol, such as Mastodon, PeerTube, and Friendica, making Pixelfed a part of the Fediverse.
Much like Mastodon, Pixelfed implements chronological timelines with no implementation of content manipulation algorithms and is privacy-focused with no third party analytics or tracking. It only allows users over 16 years old to use.
--8<-- "common-links.md"

View File

@@ -3,9 +3,10 @@ date: 2023-01-16
categories:
- CHANGELOG
tags:
- kavita
- metallb
links:
- MetalLB recipe: /kubernetes/loadbalancer/metallb.md
description: Prior to v0.13, MetalLB was configured using a ConfigMap. This has all changed now, and CRDs are required to perform configuration (which improves syntax checking, abong other things)
---
# Updated MetalLB recipe for CRDs

View File

@@ -1,16 +1,28 @@
---
date: 2022-11-10
categories:
- Review
tags:
- immich
description: Immich is a promising self-hosted alternative to Google Photos. Here's a review!
title: Review / Immich - a self-hosted Google Photos alternative
description: Immich is a polished and functional replacement for Google Photos
upstream_version: v1.19.1
upstream_repo: https://github.com/immich-app/immich
review_latest_change: Initial review!
image: /images/immich.jpg
links:
- Immich Docker Swarm recipe: recipes/immich.md
---
# I'm defz going to replace Google Photos with Immich!
[Immich][review/immich] is a promising self-hosted alternative to Google Photos. Its UI and features are clearly heavily inspired by Google Photos, and like Photoprism, Immich uses tensorflow-based machine learning to auto-tag your photos!
<!-- more -->
| Review details | |
| ----------- | ------------------------------------ |
| :material-calendar-check: Last updated | *{{ git_revision_date_localized }}* |
| :octicons-number-24: Reviewed version | *[{{ page.meta.upstream_version }}]({{ page.meta.upstream_repo }})* |
Immich is a promising self-hosted alternative to Google Photos. Its UI and features are clearly heavily inspired by Google Photos, and like [Photoprism][photoprism], Immich uses tensorflow-based machine learning to auto-tag your photos!
@@ -155,7 +167,7 @@ Based on how the pre-production development has progressed, and the massive hung
Please [join me](/#sponsored-projects) in sponsoring [@alextran1502](https://github.com/sponsors/alextran1502), to support this exceptional product!
--8<-- "review-footer.md"
--8<-- "blog-footer.md"
[^1]: "wife-insurance": When the developer's wife is a primary user of the platform, you can bet he'll be writing quality code! :woman: :material-karate: :man: :bed: :cry:
[^2]: There's a [friendly Discord server](https://discord.com/invite/D8JsnBEuKb) for Immich too!

View File

@@ -1,21 +1,30 @@
---
title: Review / Mastodon - Self-hosted twitter alternative
description: Mastodon is a globally interconnected, federated, microblogging community / social network
date: 2022-11-10
categories:
- Review
tags:
- mastodon
links:
- Mastodon Kubernetes recipe: recipes/kubernetes/mastodon.md
- Mastodon Docker Swarm recipe: recipes/mastodon.md
description: Mastodon is like a self-hosted Twitter on the Fediverse. Here's a review!
image: /images/mastodon.png
upstream_version: v3.5.3
upstream_repo: https://github.com/mastodon/mastodon/
review_latest_change: Initial review!
---
# Mastodon - Open Source Twitter Alternative
| Review details | |
| ----------- | ------------------------------------ |
| :material-calendar-check: Last updated | *{{ git_revision_date_localized }}* |
| :octicons-number-24: Reviewed version | *[{{ page.meta.upstream_version }}]({{ page.meta.upstream_repo }})* |
# Review of Mastodon - Open, Federated microblogging platform
Mastodon is a twitter-inspired, federated, microblogging community ("social network"), which anybody can partricipate in by joining a public instance, or running their own instance.
![Mastodon 3.5 Hero](/images/reviews/mastodon.png){ loading=lazy }
<!-- more -->
![Mastodon Screenshot](/images/mastodon.png){ loading=lazy }
| Review details | |
| ----------- | ------------------------------------ |
| :octicons-number-24: Reviewed version | *[{{ page.meta.upstream_version }}]({{ page.meta.upstream_repo }})* |
Mastodon is a twitter-inspired, federated, microblogging community ("social network"), which anybody can partricipate in by joining a public instance, or running their own instance.
## Background
@@ -123,7 +132,7 @@ I want to "own" my content[^3], and I want to invest in the [Geek Cookbook commu
Whichever path you take into the "fediverse", [toot me up](https://so.fnky.nz/@funkypenguin) when you get here!
--8<-- "review-footer.md"
--8<-- "blog-footer.md"
[^1]: https://blog.joinmastodon.org/2019/07/statement-on-gabs-fork-of-mastodon/
[^2]: https://blog.joinmastodon.org/2021/10/trumps-new-social-media-platform-found-using-mastodon-code/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

View File

@@ -1,183 +0,0 @@
---
title: How to build an IPFS cluster in Docker
description: IPFS is a peer-to-peer distributed file system that seeks to connect all computing devices with the same system of files. In some ways, IPFS is similar to the World Wide Web, but IPFS could be seen as a single BitTorrent swarm, exchanging objects within one Git repository.
---
# IPFS
!!! danger "This recipe is a work in progress"
This recipe is **incomplete**, and remains a work in progress.
So... There may be errors and inaccuracies. Jump into [Discord](http://chat.funkypenguin.co.nz) if you're encountering issues 😁
The intention of this recipe is to provide a local IPFS cluster for the purpose of providing persistent storage for the various components of the recipes
![IPFS Screenshot](../images/ipfs.png){ loading=lazy }
IPFS is a peer-to-peer distributed file system that seeks to connect all computing devices with the same system of files. In some ways, IPFS is similar to the World Wide Web, but IPFS could be seen as a single BitTorrent swarm, exchanging objects within one Git repository.
## Ingredients
1. [Docker swarm cluster](/docker-swarm/design/)
## Preparation
### Setup data locations (per-node)
Since IPFS may _replace_ ceph or glusterfs as a shared-storage provider for the swarm, we can't use sharded storage to store its persistent data. (🐔, meet :egg:)
On _each_ node, therefore run the following, to create the persistent data storage for ipfs and ipfs-cluster:
```bash
mkdir -p {/var/ipfs/daemon,/var/ipfs/cluster}
```
### Setup environment
ipfs-cluster nodes require a common secret, a 32-bit hex-encoded string, in order to "trust" each other, so generate one, and add it to ipfs.env on your first node, by running ```od -vN 32 -An -tx1 /dev/urandom | tr -d ' \n'; echo```
Now on _each_ node, create ```/var/ipfs/cluster:/data/ipfs-cluster```, including both the secret, *and* the IP of docker0 interface on your hosts (_on my hosts, this is always 172.17.0.1_). We do this (_the trick with docker0)_ to allow ipfs-cluster to talk to the local ipfs daemon, per-node:
```bash
SECRET=<string generated above>
# Use docker0 to access daemon
IPFS_API=/ip4/172.17.0.1/tcp/5001
```
### Create docker-compose file
Yes, I know. It's not as snazzy as docker swarm. Maybe we'll get there. But this implementation uses docker-compose, so create the following (_identical_) docker-compose.yml on each node:
```yaml
version: "3"
services:
cluster:
image: ipfs/ipfs-cluster
volumes:
- /var/ipfs/cluster:/data/ipfs-cluster
env_file: /var/data/config/ipfs/ipfs.env
ports:
- 9095:9095
- 9096:9096
depends_on:
- daemon
daemon:
image: ipfs/go-ipfs
ports:
- 4001:4001
- 5001:5001
- 8080:8080
volumes:
- /var/ipfs/daemon:/data/ipfs
```
### Launch independent nodes
Launch all nodes independently with ```docker-compose -f ipfs.yml up```. At this point, the nodes are each running independently, unaware of each other. But we do this to ensure that service.json is populated on each node, using the IPFS_API environment variable we specified in ipfs.env. (_it's only used on the first run_)
The output looks something like this:
```bash
cluster_1 | 11:03:33.272 INFO restapi: REST API (libp2p-http): ENABLED. Listening on:
cluster_1 | /ip4/127.0.0.1/tcp/9096/ipfs/QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx
cluster_1 | /ip4/172.18.0.3/tcp/9096/ipfs/QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx
cluster_1 | /p2p-circuit/ipfs/QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx
daemon_1 | Swarm listening on /ip4/127.0.0.1/tcp/4001
daemon_1 | Swarm listening on /ip4/172.19.0.2/tcp/4001
daemon_1 | Swarm listening on /p2p-circuit
daemon_1 | Swarm announcing /ip4/127.0.0.1/tcp/4001
daemon_1 | Swarm announcing /ip4/172.19.0.2/tcp/4001
daemon_1 | Swarm announcing /ip4/202.170.161.77/tcp/4001
daemon_1 | API server listening on /ip4/0.0.0.0/tcp/5001
daemon_1 | Gateway (readonly) server listening on /ip4/0.0.0.0/tcp/8080
daemon_1 | Daemon is ready
cluster_1 | 10:49:19.720 INFO consensus: Current Raft Leader: QmaAiMDP7PY3CX1xqzgAoNQav5M29P5WPWVqqSBdNu1Nsp raft.go:293
cluster_1 | 10:49:19.721 INFO cluster: Cluster Peers (without including ourselves): cluster.go:403
cluster_1 | 10:49:19.721 INFO cluster: - No other peers cluster.go:405
cluster_1 | 10:49:19.722 INFO cluster: ** IPFS Cluster is READY ** cluster.go:418
```
### Pick a leader
Pick a node to be your primary node, and CTRL-C the others.
Look for a line like this in the output of the primary node:
```bash
/ip4/127.0.0.1/tcp/9096/ipfs/QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx
```
You'll note several addresses listed, all ending in the same hash. None of these addresses will be your docker node's actual IP address, however, since we exposed port 9096, we can substitute your docker node's IP.
### Bootstrap the followers
On each of the non-primary nodes, run the following, replacing **IP-OF-PRIMARY-NODE** with the actual IP of the primary node, and **HASHY-MC-HASHFACE** with your own hash from primary output above.
```bash
docker run --rm -it -v /var/ipfs/cluster:/data/ipfs-cluster \
--entrypoint ipfs-cluster-service ipfs/ipfs-cluster \
daemon --bootstrap \ /ip4/IP-OF-PRIMARY-NODE/tcp/9096/ipfs/HASHY-MC-HASHFACE
```
You'll see output like this:
```bash
10:55:26.121 INFO service: Bootstrapping to /ip4/192.168.31.13/tcp/9096/ipfs/QmPrmQvW5knXLBE94jzpxvdtLSwXZeFE5DSY3FuMxypDsT daemon.go:153
10:55:26.121 INFO ipfshttp: IPFS Proxy: /ip4/0.0.0.0/tcp/9095 -> /ip4/172.17.0.1/tcp/5001 ipfshttp.go:221
10:55:26.304 ERROR ipfshttp: error posting to IPFS: Post http://172.17.0.1:5001/api/v0/id: dial tcp 172.17.0.1:5001: connect: connection refused ipfshttp.go:708
10:55:26.622 INFO consensus: Current Raft Leader: QmPrmQvW5knXLBE94jzpxvdtLSwXZeFE5DSY3FuMxypDsT raft.go:293
10:55:26.623 INFO cluster: Cluster Peers (without including ourselves): cluster.go:403
10:55:26.623 INFO cluster: - QmPrmQvW5knXLBE94jzpxvdtLSwXZeFE5DSY3FuMxypDsT cluster.go:410
10:55:26.624 INFO cluster: - QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx cluster.go:410
10:55:26.625 INFO cluster: ** IPFS Cluster is READY ** cluster.go:418
```
!!! note
You can ignore the warnings about port 5001 refused - this is because we weren't running the ipfs daemon while bootstrapping the cluster. Its harmless.
I haven't worked out why yet, but running the bootstrap in docker-run format reset the permissions on /var/ipfs/cluster/, so look at /var/ipfs/daemon, and make the permissions of /var/ipfs/cluster the same.
You can now run ```docker-compose -f ipfs.yml up``` on the "follower" nodes, to bring your cluster online.
### Confirm cluster
docker-exec into one of the cluster containers (_it doesn't matter which one_), and run ```ipfs-cluster-ctl peers ls```
You should see output from each node member, indicating it can see its other peers. Here's my output from a 3-node cluster:
```bash
/ # ipfs-cluster-ctl peers ls
QmPrmQvW5knXLBE94jzpxvdtLSwXZeFE5DSY3FuMxypDsT | ef68b1437c56 | Sees 2 other peers
> Addresses:
- /ip4/127.0.0.1/tcp/9096/ipfs/QmPrmQvW5knXLBE94jzpxvdtLSwXZeFE5DSY3FuMxypDsT
- /ip4/172.19.0.3/tcp/9096/ipfs/QmPrmQvW5knXLBE94jzpxvdtLSwXZeFE5DSY3FuMxypDsT
- /p2p-circuit/ipfs/QmPrmQvW5knXLBE94jzpxvdtLSwXZeFE5DSY3FuMxypDsT
> IPFS: QmU6buucy4FX9XqPoj4ZEiJiu7xUq2dnth5puU1rswtrGg
- /ip4/127.0.0.1/tcp/4001/ipfs/QmU6buucy4FX9XqPoj4ZEiJiu7xUq2dnth5puU1rswtrGg
- /ip4/172.19.0.2/tcp/4001/ipfs/QmU6buucy4FX9XqPoj4ZEiJiu7xUq2dnth5puU1rswtrGg
- /ip4/202.170.161.75/tcp/4001/ipfs/QmU6buucy4FX9XqPoj4ZEiJiu7xUq2dnth5puU1rswtrGg
QmaAiMDP7PY3CX1xqzgAoNQav5M29P5WPWVqqSBdNu1Nsp | 6558e1bf32e2 | Sees 2 other peers
> Addresses:
- /ip4/127.0.0.1/tcp/9096/ipfs/QmaAiMDP7PY3CX1xqzgAoNQav5M29P5WPWVqqSBdNu1Nsp
- /ip4/172.19.0.3/tcp/9096/ipfs/QmaAiMDP7PY3CX1xqzgAoNQav5M29P5WPWVqqSBdNu1Nsp
- /p2p-circuit/ipfs/QmaAiMDP7PY3CX1xqzgAoNQav5M29P5WPWVqqSBdNu1Nsp
> IPFS: QmYMUwHHsaeP2H8D2G3iXKhs1fHm2gQV6SKWiRWxbZfxX7
- /ip4/127.0.0.1/tcp/4001/ipfs/QmYMUwHHsaeP2H8D2G3iXKhs1fHm2gQV6SKWiRWxbZfxX7
- /ip4/172.19.0.2/tcp/4001/ipfs/QmYMUwHHsaeP2H8D2G3iXKhs1fHm2gQV6SKWiRWxbZfxX7
- /ip4/202.170.161.77/tcp/4001/ipfs/QmYMUwHHsaeP2H8D2G3iXKhs1fHm2gQV6SKWiRWxbZfxX7
QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx | 28c13ec68f33 | Sees 2 other peers
> Addresses:
- /ip4/127.0.0.1/tcp/9096/ipfs/QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx
- /ip4/172.18.0.3/tcp/9096/ipfs/QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx
- /p2p-circuit/ipfs/QmbqPBLJNXWpbXEX6bVhYLo2ruEBE7mh1tfT9s6VXUzYYx
> IPFS: QmazkAuAPpWw913HKiGsr1ief2N8cLa6xcqeAZxqDMsWmE
- /ip4/127.0.0.1/tcp/4001/ipfs/QmazkAuAPpWw913HKiGsr1ief2N8cLa6xcqeAZxqDMsWmE
- /ip4/172.18.0.2/tcp/4001/ipfs/QmazkAuAPpWw913HKiGsr1ief2N8cLa6xcqeAZxqDMsWmE
- /ip4/202.170.161.96/tcp/4001/ipfs/QmazkAuAPpWw913HKiGsr1ief2N8cLa6xcqeAZxqDMsWmE
/ #
```
[^1]: I'm still trying to work out how to _mount_ the ipfs data in my filesystem in a usable way. Which is why this is still a WIP :)
--8<-- "recipe-footer.md"

View File

@@ -1,17 +0,0 @@
---
title: Awesome self-hosted app reviews
description: This list focuses on reviews of self-hosted apps themselves, rather than deployment strategies
---
# Reviews of self-hosted apps
Unlike the [Docker Swarm](/docker-swarm/) or [Kubernetes](/kubernetes/) sections, which focus on deployment of various applications, this section reviews the applications themselves, irrespective of the deployment methodology.
What you'll find here are opinions and notes about various self-hosted applications, which will be updated from time-to-time to keep them "fresh" :leafy_green:
App | Description | Date
---------|----------| ---------
[Immich][review/immich] | Google Photos replacement | 3 Aug 2022
[Mastodon][review/mastodon] | Federated microblogging social network | 9 Aug 2022
[Nextcloud][review/nextcloud] | Content collaboration platform | 25 Aug 2022
--8<-- "common-links.md"

View File

@@ -1,161 +0,0 @@
---
title: Review / Nextcloud 24 - Robust and mature content collaboration platform
description: Nextcloud is a robust, and (boringly) mature content collaboration platform
upstream_version: v24.0.4
upstream_repo: https://github.com/nextcloud/server
review_latest_change: Refresh for v24, long time no see!
---
# Boringly reliable
| Review details | |
| ----------- | ------------------------------------ |
| :material-calendar-check: Last updated | *{{ git_revision_date_localized }}* |
| :octicons-number-24: Reviewed version | *[{{ page.meta.upstream_version }}]({{ page.meta.upstream_repo }})* |
Immich is a promising self-hosted alternative to Google Photos. Its UI and features are clearly heavily inspired by Google Photos, and like [Photoprism][photoprism], Immich uses tensorflow-based machine learning to auto-tag your photos!
!!! warning "Pre-production warning"
The developer makes it abundantly clear that Immich is under heavy development (*although it's covered by "wife-insurance"[^1]*), features and APIs may change, and all your photos may be lost, or (worse) auto-shared with your :dragon_face: mother-in-law! Take due care :wink:
I'm personally excited about Immich because I've recently been debating how to migrate from Google Photos, in which I'm hitting my 15GB storage limit.
![Immich Screenshot](/images/immich.jpg){ loading=lazy }
Immich is a bit of an outlier in the self-hosted application space in terms of its maturity.. the [repository](https://github.com/immich-app/immich) currently states that it's **not** production-ready, but it's already got both an Android and iOS app available in the respective app stores.
Two things stand out to me here - first off, the developer actively tries to discourage users from relying on the app for anything other than testing, and secondly, by investing in the mobile apps / app stores (*which come with a cost*), they're clearly thinking long-term and are committed to the project.
## Immich Features
Here are the current Immich features, which I scraped directly from the repo. As you'll note, the mobile apps mostly have parity with the web app, other than administrative functions, and even have some extra features, like search..
| | Mobile | Web |
| - | - | - |
| Upload and view videos and photos | Yes | Yes
| Auto backup when app is opened | Yes | N/A
| Selective album(s) for backup | Yes | N/A
| Download photos and videos to local device | Yes | Yes
| Multi-user support | Yes | Yes
| Album | No | Yes
| Shared Albums | Yes | Yes
| Quick navigation with draggable scrollbar | Yes | Yes
| Support RAW (HEIC, HEIF, DNG, Apple ProRaw) | Yes | Yes
| Metadata view (EXIF, map) | Yes | Yes
| Search by metadata, objects and image tags | Yes | No
| Administrative functions (user management) | N/A | Yes
## Background
Primarily what I want Immich to do is to backup all my photos from both my mobile phone, and my wife's phone, so that we can have a consolidated photo backup for our family. (*We currently use a dedicated gmail account with Google Photos for this purpose, but it's run out of space and is a little convoluted*)
We're iOS users, and we have a 2TB family iCloud account to which all of our photos are synced. Since the advent of iCloud Photo Library, it's not possible to "combine" photo libraries, so the only way we can share photos of our family is to manually add them to an album which one of us shares with the other. This is waaay too much work, and what inevitably happens is that we each end up with separate photo albums, and regularly have to send each other photos of events and kids.
So what I'm looking for is a solution to replace Google Photos - a way for each user to upload *all* photos taken on their device, and have these photos combined into a "master album" which both parties can access, manage, and create albums from.
## Details
### Install
I've written a recipe to [install Immich in Docker Swarm][immich]. Immich can also be "automatically" installed using the ansible playbook in [Premix](/premix/) 🚀.
### Web UI
The setup process was straightforward. After deploying Immich, I was prompted to setup a username and password, which subsequently became my admin credentials. Using these credentials, I setup a second user, and shared an album with him. Here's a video I made to illustrate the process:
<iframe width="560" height="315" src="https://www.youtube.com/embed/L1V_P2NRhlE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
### Mobile app
The Mobile app seems very polished, and based on my testing, works better than the Synology "Moments" app I was previously trialling (*especially given the volume of photos I have!*)
<figure markdown>
![Immich Screenshot](/images/reviews/immich-mobile.gif){ loading=lazy }
<figcaption>Apparently this was 4000+ photos!</figcaption>
</figure>
### Other
Here's what the filesystem where photos are stored looks like:
```bash
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/34ce58c4-8100-49d4-a5a3-f13a74b478f9.webp
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/34ce58c4-8100-49d4-a5a3-f13a74b478f9.jpeg
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/7d8abe14-77c3-4214-804a-d35d68084a2c.webp
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/309228ef-0b21-4986-acc4-d0c0d10e43ac.webp
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/309228ef-0b21-4986-acc4-d0c0d10e43ac.jpeg
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/7d8abe14-77c3-4214-804a-d35d68084a2c.jpeg
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/8adff3fe-d0ac-4855-b0ca-12a1f6ef2caf.webp
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/8adff3fe-d0ac-4855-b0ca-12a1f6ef2caf.jpeg
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/30505706-520b-4eac-89ed-9f1227802306.jpeg
/var/data/immich/upload/49a82212-e1bb-48d9-8b8f-7076e54bd6aa/thumb/WEB/30505706-520b-4eac-89ed-9f1227802306.webp
/var/data/immich/upload/cae22784-474c-4527-825c-46d7f324e8e8
/var/data/immich/upload/cae22784-474c-4527-825c-46d7f324e8e8/original
/var/data/immich/upload/cae22784-474c-4527-825c-46d7f324e8e8/original/WEB
/var/data/immich/upload/cae22784-474c-4527-825c-46d7f324e8e8/original/WEB/2245d33b-fbc5-40ee-a50b-2a234f73e3d9.jpg
/var/data/immich/upload/cae22784-474c-4527-825c-46d7f324e8e8/thumb
/var/data/immich/upload/cae22784-474c-4527-825c-46d7f324e8e8/thumb/WEB
/var/data/immich/upload/cae22784-474c-4527-825c-46d7f324e8e8/thumb/WEB/2245d33b-fbc5-40ee-a50b-2a234f73e3d9.webp
/var/data/immich/upload/cae22784-474c-4527-825c-46d7f324e8e8/thumb/WEB/2245d33b-fbc5-40ee-a50b-2a234f73e3d9.jpeg
```
As you'll note, while it's true that files are stored locally, there's no filesystem-level metadata easily parsable, like yearly or album-based folders. While the files are stored locally, and *technically* you could move them elsewhere, it certainly wouldn't be easy.
It's also not easy to access the files via any sort of sharing (*NFS, SMB, etc*), other than using the Immich UI. Par for the course though, I expect, if we want to be able to rely on the database for metadata without requiring intensive filesystem interaction.
## Alternatives
### Photoprism
Until Immich, the only viable self-hosted Google Photos replacement I was aware of was [Photoprism][photoprism], which has a far wider featureset and several years of stable releases.
Given my goal of having a non-Apple secondary backup of my family photos, let's selfishly compare the features which matter (*to me*):
<figure markdown>
| Feature | Immich | Photoprism |
| ----- | ----------- | ------------------------------------ |
| :material-nas: Photos stored locally | Y | Y |
| :octicons-device-mobile-24: Automatic mobile uploads (automatic) | Y | [paid 3rd-party app](https://www.photosync-app.com/home.html) |
| :material-share-variant: Share albums with trusted users | Y | Y |
| :material-bomb-off: Stable release | haha | [2021](https://docs.photoprism.app/developer-guide/)
| :material-face-recognition: AI facial recognition | N | Y |
| :octicons-tag-24: AI tagging ("photo of dog") | Y | Y |
<figcaption>Immich vs Photoprism</figcaption>
</figure>
Conclusion: For my secondary-backup use-case, Immich (*even in its current pre-production buggy state*) is perfectly fine. The mobile app is beautiful (*if a little buggy*), and I do appreciate the cheeky "Google Photos" theming / styling. I think it'll appeal to a lot of Google Photos refugees for this reason alone.
### Google Photos
OK, obviously one is self-hosted, and the other is not. This massive difference aside, again for my use-case, the other feature differences are:
<figure markdown>
| Feature | Immich | Google Photos |
| ----- | ----------- | ------------------------------------ |
| :material-nas: Storage limit | :octicons-infinity-24: | 15GB :fontawesome-solid-hand-middle-finger: |
| :octicons-device-mobile-24: Automatic mobile uploads (automatic) | Y | Y (*but deletions sync with my phone, which is less-than-idea, for my secondary-backup plan*) |
| :material-share-variant: Share all photos with user | Y | Only with 1 partner :couple: |
| :material-bomb-off: Stable release | haha | Y
| :material-face-recognition: AI facial recognition | N | Y |
| :octicons-tag-24: AI tagging ("photo of dog") | Y | Y |
<figcaption>Immich vs Google Photos</figcaption>
</figure>
**Conclusion**: I setup my secondary-backup plan when Google first announced unlimited storage for Google Photos. Now that this is no longer possible, I'm out.
## Summary
### TL;DR
I'm in (*for a secondary backup to my iCloud Photo Library*)
Based on how the pre-production development has progressed, and the massive hunger in the self-hosted community for an alternative to Google Photos, I suspect that Immich will quickly gain traction and continue its rapid pace of development.
Please [join me](/#sponsored-projects) in sponsoring [@alextran1502](https://github.com/sponsors/alextran1502), to support this exceptional product!
--8<-- "review-footer.md"
[^1]: "wife-insurance": When the developer's wife is a primary user of the platform, you can bet he'll be writing quality code! :woman: :material-karate: :man: :bed: :cry:
[^2]: There's a [friendly Discord server](https://discord.com/invite/D8JsnBEuKb) for Immich too!