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

Fix chicken/egg problem in k8s cert-manager guide

Signed-off-by: David Young <davidy@funkypenguin.co.nz>
This commit is contained in:
David Young
2022-08-06 22:31:17 +12:00
parent 94157db270
commit c73ced5238
13 changed files with 276 additions and 14 deletions

1
.gitignore vendored
View File

@@ -46,3 +46,4 @@ ehthumbs.db
Thumbs.db
.venv
venv
docs_to_pdf

View File

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 KiB

View File

@@ -19,7 +19,7 @@ In order for Cert Manager to request/renew certificates, we have to tell it abou
### LetsEncrypt Staging
The ClusterIssuer resource below represents a certificate authority which is able to request certificates for any namespace within the cluster.
I save this in my flux repo as `cert-manager/cluster-issuer-letsencrypt-staging.yaml`. I've highlighted the areas you'll need to pay attention to:
I save this in my flux repo as `letsencrypt-wildcard-cert/cluster-issuer-letsencrypt-staging.yaml`. I've highlighted the areas you'll need to pay attention to:
???+ example "ClusterIssuer for LetsEncrypt Staging"
```yaml hl_lines="8 15 17-21"
@@ -52,7 +52,7 @@ Deploying this issuer YAML into the cluster would provide Cert Manager with the
### LetsEncrypt Prod
As you'd imagine, the "prod" version of the LetsEncrypt issues is very similar, and I save this in my flux repo as `cert-manager/cluster-issuer-letsencrypt-prod.yaml`
As you'd imagine, the "prod" version of the LetsEncrypt issues is very similar, and I save this in my flux repo as `letsencrypt-wildcard-cert/cluster-issuer-letsencrypt-prod.yaml`
???+ example "ClusterIssuer for LetsEncrypt Prod"
```yaml hl_lines="8 15 17-21"
@@ -85,7 +85,7 @@ As you'd imagine, the "prod" version of the LetsEncrypt issues is very similar,
### How do we know it works?
We're not quite ready to issue certificates yet, but we can now test whether the Issuers are configured correctly for LetsEncrypt. To check their status, **describe** the ClusterIssuers (i.e., `kubectl describe clusterissuer -n cert-manager letsencrypt-prod`), which (*truncated*) shows something like this:
We're not quite ready to issue certificates yet, but we can now test whether the Issuers are configured correctly for LetsEncrypt. To check their status, **describe** the ClusterIssuers (i.e., `kubectl describe clusterissuer letsencrypt-prod`), which (*truncated*) shows something like this:
```yaml
Status:

View File

@@ -16,7 +16,9 @@ This behaviour can be prohibitive, because (a) we don't want to have to request/
To take advantage of the various workarounds available, I find it best to put the certificates into a dedicated namespace, which I name.. `letsencrypt-wildcard-cert`.
!!! question "Why not the cert-manager namespace?"
Because cert-manager is a _controller_, whose job it is to act on resources. I should be able to remove cert-manager entirely (even its namespace) from my cluster, and re-add it, without impacting the resources it acts upon. If the certificates lived in the `cert-manager` namespace, then I wouldn't be able to remove the namespace without also destroying the certificates.
Because cert-manager is a _controller_, whose job it is to act on resources. I should be able to remove cert-manager entirely (even its namespace) from my cluster, and re-add it, without impacting the resources it acts upon. If the certificates lived in the `cert-manager` namespace, then I wouldn't be able to remove the namespace without also destroying the certificates.
Furthermore, we can't deploy ClusterIssuers (a CRD) in the same kustomization which deploys the helmrelease which creates those CRDs in the first place. Flux won't be able to apply the ClusterIssuers until the CRD is created, and so will fail to reconcile.
## Preparation

View File

@@ -0,0 +1,257 @@
---
title: Run Immich in Docker Swarm
description: How to install your own immich instance using Docker Swarm
---
# Immich in Docker Swarm
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:
![Immich Screenshot](/images/immich.jpg){ loading=lazy }
See my detailed review of Immich, as a Google Photos replacement, [here][review/immich]
## Immich requirements
!!! summary "Ingredients"
Already deployed:
* [X] [Docker swarm cluster](/docker-swarm/design/) with [persistent shared storage](/docker-swarm/shared-storage-ceph/)
* [X] [Traefik](/docker-swarm/traefik/) configured per design
New:
* [ ] DNS entry for your Immich instance, pointed to your [keepalived](/docker-swarm/keepalived/) IP
### Setup data locations
First, we create a directory to hold the immich docker-compose configuration:
```bash
mkdir /var/data/config/immich
```
Then we setup directories to hold all the various data:
```bash
mkdir -p /var/data/immich/database-dump
mkdir -p /var/data/immich/upload
mkdir -p /var/data/runtime/immich/database
```
### Setup Immich enviroment
Create `/var/data/config/immich/immich.env` something like the example below..
```yaml title="/var/data/config/immich/immich.env"
###################################################################################
# Database
###################################################################################
# These are for the Immich components
DB_HOSTNAME=db
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE_NAME=immich
# These are specific to how the postgres image likes to receive its ENV vars
POSTGRES_PASSWORD=postgres
#POSTGRES_USER=postgres
POSTGRES_DB=immich
###################################################################################
# Redis
###################################################################################
REDIS_HOSTNAME=redis
# Optional Redis settings:
# REDIS_PORT=6379
# REDIS_DBINDEX=0
# REDIS_PASSWORD=
# REDIS_SOCKET=
###################################################################################
# JWT SECRET
###################################################################################
JWT_SECRET=randomstringthatissolongandpowerfulthatnoonecanguess # (1)!
###################################################################################
# MAPBOX
####################################################################################
# ENABLE_MAPBOX is either true of false -> if true, you have to provide MAPBOX_KEY
ENABLE_MAPBOX=false
MAPBOX_KEY=
###################################################################################
# WEB - Required
###################################################################################
# This is the URL of your vm/server where you host Immich, so that the web frontend
# know where can it make the request to.
# For example: If your server IP address is 10.1.11.50, the environment variable will
# be VITE_SERVER_ENDPOINT=http://10.1.11.50:2283/api
# !CAUTION! THERE IS NO FORWARD SLASH AT THE END
VITE_SERVER_ENDPOINT=https://immich.example.com/api
####################################################################################
# WEB - Optional
####################################################################################
# Custom message on the login page, should be written in HTML form.
# For example VITE_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
VITE_LOGIN_PAGE_MESSAGE=
NODE_ENV=production
```
1. Yes, this has to be long. At least 20 characters.
### Immich Docker Swarm config
Create a docker swarm config file in docker-compose syntax (v3), something like this example:
--8<-- "premix-cta.md"
```yaml title="/var/data/config/immich/immich.yml"
version: "3.2"
services:
immich-server:
image: altran1502/immich-server:release
entrypoint: ["/bin/sh", "./start-server.sh"]
volumes:
- /var/data/immich/upload:/usr/src/app/upload
env_file: /var/data/config/immich/immich.env
networks:
- internal
immich-microservices:
image: altran1502/immich-server:release
entrypoint: ["/bin/sh", "./start-microservices.sh"]
volumes:
- /var/data/immich/upload:/usr/src/app/upload
env_file: /var/data/config/immich/immich.env
networks:
- internal
immich-machine-learning:
image: altran1502/immich-machine-learning:release
entrypoint: ["/bin/sh", "./entrypoint.sh"]
volumes:
- /var/data/immich/upload:/usr/src/app/upload
env_file: /var/data/config/immich/immich.env
networks:
- internal
immich-web:
image: altran1502/immich-web:release
entrypoint: ["/bin/sh", "./entrypoint.sh"]
env_file: /var/data/config/immich/immich.env
networks:
- internal
redis:
image: redis:6.2
networks:
- internal
db:
image: postgres:14
env_file: /var/data/config/immich/immich.env
volumes:
- /var/data/runtime/immich/database:/var/lib/postgresql/data
networks:
- internal
db-backup:
image: postgres:14
env_file: /var/data/config/immich/immich-db-backup.env
volumes:
- /var/data/immich/database-dump:/dump
entrypoint: |
bash -c 'bash -s <<EOF
trap "break;exit" SIGHUP SIGINT SIGTERM
sleep 2m
while /bin/true; do
pg_dump -Fc > /dump/dump_\`date +%d-%m-%Y"_"%H_%M_%S\`.psql
ls -tr /dump/dump_*.psql | head -n -"$$BACKUP_NUM_KEEP" | xargs -r rm
sleep $$BACKUP_FREQUENCY
done
EOF'
networks:
- internal
immich-proxy:
container_name: immich_proxy
image: altran1502/immich-proxy:release
ports:
- 2283:80
deploy:
replicas: 1
labels:
# traefik
- traefik.enable=true
- traefik.docker.network=traefik_public
# traefikv1
- traefik.frontend.rule=Host:immich.example.com
- traefik.port=80
# traefikv2
- "traefik.http.routers.immich.rule=Host(`immich.example.com`)"
- "traefik.http.routers.immich.entrypoints=https"
- "traefik.http.services.immich.loadbalancer.server.port=80"
networks:
- internal
- traefik_public
networks:
traefik_public:
external: true
internal:
driver: overlay
ipam:
config:
- subnet: 172.16.8.0/24
```
--8<-- "reference-networks.md"
## Launch Immich!
Launch the Immich stack by running
```bash
docker stack deploy immich -c /var/data/config/immich/immich.yml
```
Now hit the URL you defined in your config, and you should be prompted to create your first (admin) account, after which you can login (*with the details you just created*), and start admin-ing. Install a mobile app, connect using the same credentials, and start backing up all your photos!
## Summary
What have we achieved? We have an HTTPS-protected endpoint to target with the native mobile apps, allowing us to backup photos from mobile devices and have them become searchable, shareable, and browseable via a beautiful, Google Photos-esque interface!
!!! summary "Summary"
Created:
* [X] Photos can be synced from mobile device, or manually uploaded via web UI
## Setup Immich in < 60s
Sponsors have access to a [Premix](/premix/) playbook, which will set up Immich in under 60s (*see below*):
<iframe width="560" height="315" src="https://www.youtube.com/embed/s-NZjYrNOPg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
--8<-- "recipe-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

@@ -20,7 +20,7 @@ Immich is a promising self-hosted alternative to Google Photos. Its UI and featu
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/reviews/immich-web.jpg){ loading=lazy }
![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.
@@ -57,7 +57,7 @@ So what I'm looking for is a solution to replace Google Photos - a way for each
### Install
Installation was... tricky, but that's because I wanted to install Immich using Docker Swarm, rather than the example docker-compose included with the repo. I'm working on a recipe, and will update this review when done.
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
@@ -156,11 +156,6 @@ 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!
### Setup Immich via premix
I'll have a recipe up for Immich in due course, but if you're wanting to use the pre-prod, development, dont-blame-me version, there's an ansible role in the [Premix](/premix/) playbook which will set it up in under 60s (*see below*):
<iframe width="560" height="315" src="https://www.youtube.com/embed/s-NZjYrNOPg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
--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:

View File

@@ -13,7 +13,7 @@ plugins:
back_cover: true
#cover_title: TITLE TEXT
#cover_subtitle: SUBTITLE TEXT
# custom_template_path: pdf_templates
custom_template_path: with_pdf_template
#toc_title: TOC TITLE TEXT
#heading_shift: true
toc_level: 3

View File

@@ -97,6 +97,7 @@ nav:
- GitLab: recipes/gitlab.md
- GitLab Runner: recipes/gitlab-runner.md
- Gollum: recipes/gollum.md
- Immich: recipes/immich.md
- InstaPy: recipes/instapy.md
- Jellyfin: recipes/jellyfin.md
- Keycloak:
@@ -240,7 +241,7 @@ nav:
- Design: premix/ansible/design.md
# - Swarm: premix/swarm.md
# - Kubernetes: premix/kubernetes.md
- Reviews:
- ☑️ Reviews:
- review/index.md
- Immich: review/immich.md
- CHANGELOG: recent-changes.md

View File

@@ -7,4 +7,7 @@ cp -rf manuscript docs_to_pdf
find docs_to_pdf -type f -exec gsed -i -e 's/recipe-footer.md/common-links.md/g' {} \;
# Build PDF from slimmed recipes
docker run --rm --name mkdocs-material -e ENABLE_PDF_EXPORT=1 -v ${PWD}/docs_to_pdf:/docs funkypenguin/mkdocs-material build -f mkdocs-pdf-print.yml
docker run --rm --name mkdocs-material-build-pdf -e ENABLE_PDF_EXPORT=1\
-v ${PWD}/docs_to_pdf:/docs\
-v ${PWD}/mkdocs-pdf-print.yml:/mkdocs-pdf-print.yml\
funkypenguin/mkdocs-material build -f mkdocs-pdf-print.yml

View File

@@ -0,0 +1,3 @@
* {
font-family: Verdana, Geneva, Tahoma, sans-serif !important;
}