[add] librephotos
This commit is contained in:
parent
ebc53109d4
commit
a23428dec3
44 changed files with 2123 additions and 0 deletions
27
librephotos-docker/k8s/README.md
Normal file
27
librephotos-docker/k8s/README.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Kubernetes Installation
|
||||
|
||||
1. Clone this repo and change to this directory.
|
||||
1. Check the values in `kustomization.yaml`, in the `images` section, to make sure they're pointing to the latest
|
||||
release.
|
||||
1. Consider changing the sizes of the volumes in `pvcs.yaml`.
|
||||
1. Edit the hostnames in `ingress.yaml`. Consider installing [cert-manager](https://cert-manager.io/) and uncommenting
|
||||
the relevant portions of `ingress.yaml`.
|
||||
1. Edit the values in `config/backend.env` to suit your configuration.
|
||||
1. Install these manifests to your cluster with `kubectl apply -k .`.
|
||||
1. Create a secret for PostgreSQL authentication.
|
||||
```
|
||||
kubectl create secret generic database -n librephotos DB_PASS=$(openssl rand -hex 16) DB_USER=librephotos
|
||||
```
|
||||
1. Create a secret for the backend's key, admin password, and optional MapBox API key.
|
||||
```
|
||||
kubectl create secret generic backend -n librephotos SECRET_KEY=$key ADMIN_PASSWORD=$password MAPBOX_API_KEY=$apikey
|
||||
```
|
||||
Substitute values for `$key`, `$password`, and `$apikey`. Make sure you remember the `$password` so you can log in.
|
||||
|
||||
If you want, you can watch the Pods get ready with `kubectl get pod -n librephotos -w`. Once they're all running,
|
||||
point your browser at the hostname from `ingress.yaml`, and log in as `admin`.
|
||||
|
||||
# Upgrading
|
||||
|
||||
Change the values in `kustomization.yaml`, in the `images` section, to point to the latest versions. Then just rerun
|
||||
the `kubectl apply -k .` command.
|
||||
107
librephotos-docker/k8s/backend.yaml
Normal file
107
librephotos-docker/k8s/backend.yaml
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: backend
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: backend
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: backend
|
||||
image: backend-placeholder
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: backend
|
||||
- secretRef:
|
||||
name: backend
|
||||
- secretRef:
|
||||
name: database
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
ports:
|
||||
- name: backend
|
||||
containerPort: 8001
|
||||
volumeMounts:
|
||||
- name: photos
|
||||
mountPath: /data
|
||||
- name: protected-media
|
||||
mountPath: /protected_media
|
||||
- name: logs
|
||||
mountPath: /logs
|
||||
- name: cache
|
||||
mountPath: /root/.cache
|
||||
- name: backend-tmp
|
||||
mountPath: /tmp
|
||||
- name: proxy
|
||||
image: proxy-placeholder
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
ports:
|
||||
- name: proxy
|
||||
containerPort: 80
|
||||
volumeMounts:
|
||||
- name: photos
|
||||
mountPath: /data
|
||||
- name: protected-media
|
||||
mountPath: /protected_media
|
||||
- name: nginx-cache
|
||||
mountPath: /var/cache/nginx
|
||||
- name: proxy-var-run
|
||||
mountPath: /var/run
|
||||
securityContext:
|
||||
runAsUser: 65534
|
||||
runAsGroup: 65534
|
||||
fsGroup: 65534
|
||||
volumes:
|
||||
- name: photos
|
||||
persistentVolumeClaim:
|
||||
claimName: photos
|
||||
- name: protected-media
|
||||
persistentVolumeClaim:
|
||||
claimName: protected
|
||||
- name: logs
|
||||
emptyDir: {}
|
||||
- name: cache
|
||||
emptyDir: {}
|
||||
- name: backend-tmp
|
||||
emptyDir: {}
|
||||
- name: nginx-cache
|
||||
emptyDir: {}
|
||||
- name: proxy-var-run
|
||||
emptyDir: {}
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: backend
|
||||
spec:
|
||||
selector:
|
||||
app: backend
|
||||
ports:
|
||||
- name: http
|
||||
port: 8001
|
||||
targetPort: backend
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: proxy
|
||||
spec:
|
||||
selector:
|
||||
app: backend
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: proxy
|
||||
10
librephotos-docker/k8s/config/backend.env
Normal file
10
librephotos-docker/k8s/config/backend.env
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
BACKEND_HOST=backend
|
||||
ADMIN_EMAIL=somebody@example.com
|
||||
ADMIN_USERNAME=admin
|
||||
DB_BACKEND=postgresql
|
||||
DB_NAME=librephotos
|
||||
DB_HOST=postgres
|
||||
DB_PORT=5432
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
WEB_CONCURRENCY=2
|
||||
69
librephotos-docker/k8s/db.yaml
Normal file
69
librephotos-docker/k8s/db.yaml
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: postgres
|
||||
spec:
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 0
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgresql-placeholder
|
||||
env:
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: DB_PASS
|
||||
name: database
|
||||
- name: POSTGRES_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: DB_USER
|
||||
name: database
|
||||
- name: POSTGRES_DB
|
||||
value: librephotos
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- pg_isready
|
||||
- -h
|
||||
- localhost
|
||||
- -U
|
||||
- librephotos
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
name: psql
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/postgresql/data
|
||||
name: data
|
||||
securityContext:
|
||||
runAsUser: 999
|
||||
runAsGroup: 999
|
||||
fsGroup: 999
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: postgres
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgres
|
||||
spec:
|
||||
ports:
|
||||
- port: 5432
|
||||
name: psql
|
||||
selector:
|
||||
app: postgres
|
||||
38
librephotos-docker/k8s/frontend.yaml
Normal file
38
librephotos-docker/k8s/frontend.yaml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: frontend
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: frontend
|
||||
image: frontend-placeholder
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 3000
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
securityContext:
|
||||
runAsUser: 65534
|
||||
runAsGroup: 65534
|
||||
fsGroup: 65534
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: frontend
|
||||
spec:
|
||||
ports:
|
||||
- port: 3000
|
||||
name: http
|
||||
selector:
|
||||
app: frontend
|
||||
44
librephotos-docker/k8s/ingress.yaml
Normal file
44
librephotos-docker/k8s/ingress.yaml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# This ingress will make your photo site available to web browsers. For this to work, you'll need an ingress controller
|
||||
# already installed in your cluster: https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
|
||||
# You should use TLS/SSL to protect the site. Either use cert-manager (https://cert-manager.io/) or something else.
|
||||
# If TLS/SSL is available, uncomment the annotation below, and the tls section.
|
||||
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: photos.example.com
|
||||
# annotations:
|
||||
# ingress.kubernetes.io/ssl-redirect: "true"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: photos.example.com
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: "/"
|
||||
backend:
|
||||
service:
|
||||
name: proxy
|
||||
port:
|
||||
name: http
|
||||
# tls:
|
||||
# - hosts:
|
||||
# - photos.example.com
|
||||
# secretName: photos.example.com
|
||||
|
||||
---
|
||||
|
||||
# If you're using cert-manager, uncomment this to request a certificate that will be used by the ingress above.
|
||||
|
||||
# apiVersion: cert-manager.io/v1
|
||||
# kind: Certificate
|
||||
# metadata:
|
||||
# name: photos.example.com
|
||||
# spec:
|
||||
# secretName: photos.example.com
|
||||
# dnsNames:
|
||||
# - photos.example.com
|
||||
# issuerRef:
|
||||
# kind: ClusterIssuer
|
||||
# name: letsencrypt
|
||||
35
librephotos-docker/k8s/kustomization.yaml
Normal file
35
librephotos-docker/k8s/kustomization.yaml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
namespace: librephotos
|
||||
|
||||
resources:
|
||||
- backend.yaml
|
||||
- db.yaml
|
||||
- frontend.yaml
|
||||
- ingress.yaml
|
||||
- ns.yaml
|
||||
- pvcs.yaml
|
||||
- redis.yaml
|
||||
|
||||
configMapGenerator:
|
||||
- name: backend
|
||||
envs:
|
||||
- config/backend.env
|
||||
|
||||
images:
|
||||
- name: backend-placeholder
|
||||
newName: reallibrephotos/librephotos
|
||||
newTag: 2022w12
|
||||
- name: frontend-placeholder
|
||||
newName: reallibrephotos/librephotos-frontend
|
||||
newTag: 2022w12
|
||||
- name: proxy-placeholder
|
||||
newName: reallibrephotos/librephotos-proxy
|
||||
newTag: 2022w10
|
||||
- name: postgresql-placeholder
|
||||
newName: postgres
|
||||
newTag: "13"
|
||||
- name: redis-placeholder
|
||||
newName: redis
|
||||
newTag: "6"
|
||||
4
librephotos-docker/k8s/ns.yaml
Normal file
4
librephotos-docker/k8s/ns.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: librephotos
|
||||
42
librephotos-docker/k8s/pvcs.yaml
Normal file
42
librephotos-docker/k8s/pvcs.yaml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# This volume holds your photos.
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: photos
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 30Gi
|
||||
volumeMode: Filesystem
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
|
||||
---
|
||||
|
||||
# This volume contains thumbnails. Setting it to 10-15% the size of "photos" is probably reasonable.
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: protected
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 3Gi
|
||||
volumeMode: Filesystem
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
|
||||
---
|
||||
|
||||
# The postgres volume holds all the metadata. If it's 1% the size of "photos," you're probably fine.
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: postgres
|
||||
spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
volumeMode: Filesystem
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
39
librephotos-docker/k8s/redis.yaml
Normal file
39
librephotos-docker/k8s/redis.yaml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis-placeholder
|
||||
ports:
|
||||
- name: redis
|
||||
containerPort: 6379
|
||||
securityContext:
|
||||
runAsUser: 999
|
||||
runAsGroup: 999
|
||||
fsGroup: 999
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
ports:
|
||||
- port: 6379
|
||||
name: redis
|
||||
selector:
|
||||
app: redis
|
||||
Loading…
Add table
Add a link
Reference in a new issue