invoice-ninja: Deploy Invoice Ninja
Invoice Ninja is a small business management tool. Tabitha wants to use it for HLC. I am a bit concerned about the code quality of this application, and definitely alarmed at the data it send upstream, so I have tried to be extra careful with it. All privileges are revoked, including access to the Internet.etcd
parent
a5d186b461
commit
4e15a9d71d
|
@ -0,0 +1,13 @@
|
|||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: invoice-ninja
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: invoice-ninja
|
||||
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
|
||||
targetRevision: master
|
|
@ -0,0 +1,72 @@
|
|||
# Invoice Ninja
|
||||
|
||||
[Invoice Ninja][0] is a free invoice and customer management system. Tabitha
|
||||
uses it to manage her tutoring and learning center billing and payments.
|
||||
|
||||
[0]: https://www.invoiceninja.org/
|
||||
|
||||
|
||||
## Components
|
||||
|
||||
*Invoice Ninja* is a web-based application, written in PHP. The official
|
||||
container image only includes the application itself and PHP-FPM, but no HTTP
|
||||
server, so a separate *nginx* container is necessary. The image is also of
|
||||
dubious quality, doing weird things like copying "backup" files to persistent
|
||||
storage at startup, then deleting them from the container filesystem. To
|
||||
work around this, an init container is necessary to copy the application into
|
||||
writable ephemeral storage.
|
||||
|
||||
Persistent storage is handled in a somewhat ad-hoc way. There are three paths
|
||||
that are expected to be persistent:
|
||||
|
||||
* `/var/www/app/public`
|
||||
* `/var/www/app/storage`
|
||||
* `/var/www/app/public/storage`
|
||||
|
||||
The distinction between these is not really clear. Both "public" directories
|
||||
have to be served by the web server, as well.
|
||||
|
||||
In addition to the main process, a "cron" process is required. This has to
|
||||
run every minute, apparently.
|
||||
|
||||
*Invoice Ninja* also requires a MySQL or MariaDB database. Supposedly,
|
||||
PostgreSQL can be used as well, but it is not supported by upstream and
|
||||
apparently requires patching some PHP code.
|
||||
|
||||
|
||||
## Phone Home
|
||||
|
||||
Although *Invoice Ninja* can be self hosed, it relies on some cloud services
|
||||
for some features. Notably, generating PDF invoices makes a few connections to
|
||||
external services:
|
||||
|
||||
* *fonts.googleapis.com*: Fetches CSS resources
|
||||
* *invoicing.io*: Fetches the *Invoice Ninja* logo to print at the bottom
|
||||
|
||||
Both of these remote resources are hard-coded into the HTML document template
|
||||
that is used to render the PDF. The former is probably innocent, but I suspect
|
||||
the latter is some kind of "phone home," informing upstream of field deployments.
|
||||
Additionally, when certain actions are performed in the web UI, the backend
|
||||
makes requests to *www.google-analytics.com*, obviously for telemetry.
|
||||
Further, the *Invoice Ninja* documentation lists some "terms of service" for
|
||||
self-hosting, which include sending personally identifiable information to
|
||||
the *Invoice Ninja*, including company name and contact information, email
|
||||
addresses, etc.
|
||||
|
||||
The point of self-hosting applications is not to avoid paying for them (in
|
||||
fact, I pay for some cloud services offered by open source developers, even
|
||||
though I self-host their software), but to avoid dependencies on cloud
|
||||
services. For *Invoice Ninja*, that means we should be able to make invoices
|
||||
any time, even if upstream ceases offering their cloud service. Including a
|
||||
"phone home" in the invoice generation that can prevent the feature from
|
||||
working, even if it is by accident, is unacceptable.
|
||||
|
||||
To that end, I have neutered *Invoice Ninja*'s phone-home capabilities. First,
|
||||
a script runs before the main container starts that replaces the hard-coded
|
||||
URL of the *Invoice Ninja* logo with the URL to the same logo in the local
|
||||
installation. Next, I have blocked all outbound communication from *Invoice
|
||||
Ninja* pods using a NetworkPolicy, except for Kubernetes services and the
|
||||
forward proxy on the firewall. Finally, I have configured the forward proxy
|
||||
(Squid) on the firewall to *only* allow access to *fonts.googleapis.com*, so
|
||||
that invoices render correctly, blocking all telemetry and other phone-home
|
||||
communication.
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: invoice-ninja
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
spec:
|
||||
rules:
|
||||
- host: invoiceninja.pyrocufflink.blue
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: invoice-ninja
|
||||
port:
|
||||
name: http
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cp -r /var/www/app/. /app
|
||||
|
||||
# The Invoice Ninja logo on PDF invoices is always loaded from upstream's
|
||||
# server, despite the APP_URL setting.
|
||||
sed -i \
|
||||
-e 's@invoicing.co/images/new_logo.png@invoiceninja.pyrocufflink.blue/images/logo.png@' \
|
||||
/app/app/Utils/HtmlEngine.php
|
||||
|
||||
chown -R invoiceninja:invoiceninja /app
|
||||
|
||||
if [ "$(stat -c %u /storage)" -ne "$(id -u invoiceninja)" ]; then
|
||||
chown -R invoiceninja:invoiceninja /storage
|
||||
chmod -R u=rwx,go= /storage
|
||||
fi
|
|
@ -0,0 +1,16 @@
|
|||
APP_LOGO=https://invoiceninja.pyrocufflink.blue/images/logo.png
|
||||
APP_URL=https://invoiceninja.pyrocufflink.blue
|
||||
TRUSTED_PROXIES=172.30.0.171,172.30.0.172,172.30.0.173
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mail.pyrocufflink.blue
|
||||
MAIL_PORT=25
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS=invoice-ninja@pyrocufflink.net
|
||||
MAIL_FROM_NAME='Invoice Ninja'
|
||||
|
||||
EXPANDED_LOGGING=true
|
||||
|
||||
http_proxy=http://172.30.0.1:3128
|
||||
https_proxy=http://172.30.0.1:3128
|
||||
NO_PROXY=local,pyrocufflink.blue,localhost
|
|
@ -0,0 +1,218 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: invoice-ninja
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteMany
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: invoice-ninja
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
ports:
|
||||
- port: 8000
|
||||
targetPort: http
|
||||
selector:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
type: ClusterIP
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: invoice-ninja
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
initContainers:
|
||||
- name: init
|
||||
image: &image docker.io/invoiceninja/invoiceninja:5.8.16
|
||||
command:
|
||||
- /init.sh
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- CHOWN
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 0
|
||||
runAsNonRoot: false
|
||||
runAsUser: 0
|
||||
volumeMounts:
|
||||
- mountPath: /app
|
||||
name: app
|
||||
- mountPath: /init.sh
|
||||
name: init
|
||||
subPath: init.sh
|
||||
- mountPath: /storage
|
||||
name: data
|
||||
subPath: storage
|
||||
containers:
|
||||
- name: invoice-ninja
|
||||
image: *image
|
||||
env: &env
|
||||
- name: DB_HOST
|
||||
value: invoice-ninja-db
|
||||
- name: DB_DATABASE
|
||||
value: ninja
|
||||
- name: DB_USERNAME
|
||||
value: ninja
|
||||
- name: DB_PASSWORD_FILE
|
||||
value: /run/secrets/invoiceninja/db.password
|
||||
- name: APP_KEY_FILE
|
||||
value: /run/secrets/invoiceninja/app.key
|
||||
- name: APP_CIPHER
|
||||
value: AES-256-GCM
|
||||
- name: TRUSTED_PROXIES
|
||||
value: '*'
|
||||
envFrom: &envFrom
|
||||
- configMapRef:
|
||||
name: invoice-ninja
|
||||
readinessProbe: &probe
|
||||
tcpSocket:
|
||||
port: 9000
|
||||
periodSeconds: 60
|
||||
startupProbe:
|
||||
<<: *probe
|
||||
periodSeconds: 1
|
||||
failureThreshold: 60
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
volumeMounts: &mounts
|
||||
- mountPath: /run/secrets/invoiceninja
|
||||
name: secrets
|
||||
readOnly: true
|
||||
- mountPath: /tmp
|
||||
name: tmp
|
||||
subPath: tmp
|
||||
- mountPath: /var/www/app
|
||||
name: app
|
||||
- mountPath: /var/www/app/public/storage
|
||||
name: data
|
||||
subPath: storage-public
|
||||
- mountPath: /var/www/app/storage
|
||||
name: data
|
||||
subPath: storage
|
||||
- mountPath: /var/www/app/storage/logs
|
||||
name: tmp
|
||||
subPath: logs
|
||||
- name: nginx
|
||||
image: docker.io/library/nginx:1
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
name: http
|
||||
readinessProbe: &probe
|
||||
httpGet:
|
||||
port: 8000
|
||||
path: /health
|
||||
periodSeconds: 60
|
||||
startupProbe:
|
||||
<<: *probe
|
||||
periodSeconds: 1
|
||||
failureThreshold: 30
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
runAsUser: 101
|
||||
runAsGroup: 101
|
||||
volumeMounts:
|
||||
- mountPath: /etc/nginx/nginx.conf
|
||||
name: nginx-conf
|
||||
subPath: nginx.conf
|
||||
readOnly: true
|
||||
- mountPath: /run/nginx
|
||||
name: run
|
||||
subPath: nginx
|
||||
- mountPath: /var/cache/nginx
|
||||
name: nginx-cache
|
||||
- mountPath: /var/www/app/public
|
||||
name: app
|
||||
subPath: public
|
||||
readOnly: true
|
||||
- mountPath: /var/www/app/public/storage
|
||||
name: data
|
||||
subPath: storage-public
|
||||
readOnly: true
|
||||
- name: cron
|
||||
image: *image
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
cleanup() { kill -TERM $!; exit; }
|
||||
trap cleanup TERM
|
||||
while sleep 60; do php artisan schedule:run; done
|
||||
env: *env
|
||||
envFrom: *envFrom
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
volumeMounts: *mounts
|
||||
enableServiceLinks: false
|
||||
affinity:
|
||||
podAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 1
|
||||
podAffinityTerm:
|
||||
topologyKey: kubernetes.io/hostname
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app.kubernetes.io/name
|
||||
operator: In
|
||||
values:
|
||||
- invoice-ninja-db
|
||||
securityContext:
|
||||
runAsNonRoot: True
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
volumes:
|
||||
- name: app
|
||||
emptyDir: {}
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: invoice-ninja
|
||||
- name: init
|
||||
configMap:
|
||||
name: invoice-ninja-init
|
||||
defaultMode: 0755
|
||||
- name: nginx-cache
|
||||
emptyDir: {}
|
||||
- name: nginx-conf
|
||||
configMap:
|
||||
name: nginx
|
||||
- name: run
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
- name: secrets
|
||||
secret:
|
||||
secretName: invoice-ninja
|
||||
- name: tmp
|
||||
emptyDir: {}
|
|
@ -0,0 +1,30 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
namespace: invoice-ninja
|
||||
|
||||
labels:
|
||||
- pairs:
|
||||
app.kubernetes.io/instance: invoice-ninja
|
||||
includeSelectors: false
|
||||
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- secrets.yaml
|
||||
- network-policy.yaml
|
||||
- mariadb.yaml
|
||||
- invoice-ninja.yaml
|
||||
- ingress.yaml
|
||||
|
||||
configMapGenerator:
|
||||
- name: invoice-ninja-init
|
||||
files:
|
||||
- init.sh
|
||||
|
||||
- name: invoice-ninja
|
||||
envs:
|
||||
- invoice-ninja.env
|
||||
|
||||
- name: nginx
|
||||
files:
|
||||
- nginx.conf
|
|
@ -0,0 +1,111 @@
|
|||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: invoice-ninja-db
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja-db
|
||||
app.kubernetes.io/component: mysql
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: invoice-ninja-db
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja-db
|
||||
app.kubernetes.io/component: mysql
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
targetPort: mysql
|
||||
selector:
|
||||
app.kubernetes.io/name: invoice-ninja-db
|
||||
app.kubernetes.io/component: mysql
|
||||
type: ClusterIP
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: invoice-ninja-db
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja-db
|
||||
app.kubernetes.io/component: mysql
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
serviceName: invoice-ninja-db
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: invoice-ninja-db
|
||||
app.kubernetes.io/component: mysql
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja-db
|
||||
app.kubernetes.io/component: mysql
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
containers:
|
||||
- name: mariadb
|
||||
image: docker.io/library/mariadb:10.11.6
|
||||
env:
|
||||
- name: MARIADB_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysql-root
|
||||
key: password
|
||||
- name: MARIADB_DATABASE
|
||||
value: ninja
|
||||
- name: MARIADB_USER
|
||||
value: ninja
|
||||
- name: MARIADB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: invoice-ninja
|
||||
key: db.password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
name: mysql
|
||||
readinessProbe: &probe
|
||||
tcpSocket:
|
||||
port: mysql
|
||||
periodSeconds: 60
|
||||
startupProbe:
|
||||
<<: *probe
|
||||
periodSeconds: 1
|
||||
failureThreshold: 60
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
volumeMounts:
|
||||
- mountPath: /run/mysqld
|
||||
name: run
|
||||
subPath: mysqld
|
||||
- mountPath: /tmp
|
||||
name: tmp
|
||||
subPath: tmp
|
||||
- mountPath: /var/lib/mysql
|
||||
name: data
|
||||
subPath: mysql
|
||||
enableServiceLinks: false
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 3306
|
||||
runAsGroup: 3306
|
||||
fsGroup: 3306
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: invoice-ninja-db
|
||||
- name: run
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
- name: tmp
|
||||
emptyDir: {}
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: invoice-ninja
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
|
@ -0,0 +1,46 @@
|
|||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: invoice-ninja
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
spec:
|
||||
egress:
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
k8s-app: kube-dns
|
||||
ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
- port: 53
|
||||
protocol: TCP
|
||||
- to:
|
||||
- ipBlock:
|
||||
cidr: 172.30.0.12/32
|
||||
ports:
|
||||
- port: 25
|
||||
- to:
|
||||
- ipBlock:
|
||||
cidr: 172.30.0.160/28
|
||||
ports:
|
||||
- port: 80
|
||||
- port: 443
|
||||
- to:
|
||||
- ipBlock:
|
||||
cidr: 172.30.0.1/32
|
||||
ports:
|
||||
- port: 3128
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
policyTypes:
|
||||
- Egress
|
|
@ -0,0 +1,68 @@
|
|||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
|
||||
pid /run/nginx/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
|
||||
gzip on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
upstream backend {
|
||||
server 127.0.0.1:9000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 8000 default;
|
||||
server_name _;
|
||||
|
||||
root /var/www/app/public;
|
||||
|
||||
index index.php;
|
||||
|
||||
charset utf-8;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location /health {
|
||||
return 200 'UP';
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass backend;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_buffer_size 16k;
|
||||
fastcgi_buffers 4 16k;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
apiVersion: bitnami.com/v1alpha1
|
||||
kind: SealedSecret
|
||||
metadata:
|
||||
name: mysql-root
|
||||
namespace: invoice-ninja
|
||||
labels:
|
||||
app.kubernetes.io/name: mysql-root
|
||||
app.kubernetes.io/component: mysql
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
encryptedData:
|
||||
password: AgCWJhpMd/GmSzYZv+lofE9vQrTBewpeUO7rPnZGy5n9lvwwSin3DSzqeUCh37byCQ086VjIA1AqcJAXkur8dcZWXRAXY3H26rDoEMjGIyfrUEByCLhSNhL3sK7AcE14QWOuoxtUSbGk5RmYc+qvIw8b4l/dNpEnatLCRUeF9CefMgnTk2phVMlzkasvXjxAvxcBIvDg7DLcBOsenGg1xNG8j8wQ8flGsX6bWHmlt1+EBhyp+8PS+GyOT1BmjnVyQeo2mKwXm+FY9WHlEswypKTVQAsV6F0fUh9gIFoAdklOMwxbaW8321xLfQQvB4Qkbx8N0YJYy1jFNMF6plwcZhE7KwxXoNjW3GQhyGqTq/iFDi/oLJmAjxH9Vz8RPGT5IyOLRIkrQjCDhWrIHAEh1TUVF2BorrV8gIQOLV2xP2Lxa20KIjVZdosntWPc8bp8Br4RiP0JIK/ktRIMt+cCOwwrux8FhJe8WklujnaiZ1HX7G8dgidtjmUXYBxyNOZ9FMs2+c7D3bgqNQsTQ/NMlyP02l5oXUNzQpIVNbY4t+AT0ISn8NP9xDmLVwFw0Y3lJbx5rDtqaSFivkMOsp20l/JVUkeyig3Trm6OLh9FzI6Qr4Qo6fPBSrqKu1ieQPF76C80phrTWwtiK67i2LSmtb2zAvm3Hwj4X4Ag7HIi8F7zF7HjgOcmmS+6fIgyaIufE6IeQtwFwekbWGTHWDFddias9qHBuM1QcnQP/SJZkZrR/A==
|
||||
template:
|
||||
metadata:
|
||||
name: mysql-root
|
||||
namespace: invoice-ninja
|
||||
|
||||
---
|
||||
apiVersion: bitnami.com/v1alpha1
|
||||
kind: SealedSecret
|
||||
metadata:
|
||||
name: invoice-ninja
|
||||
namespace: invoice-ninja
|
||||
labels:
|
||||
app.kubernetes.io/name: invoice-ninja
|
||||
app.kubernetes.io/component: invoice-ninja
|
||||
app.kubernetes.io/part-of: invoice-ninja
|
||||
spec:
|
||||
encryptedData:
|
||||
app.key: AgA1p4ay2avNqkFYzLIB5VXxIjFBoZ8YZksf89Q81vCXrUs9mxd2/PuaRFeVu9WZwYXElT/esF2TV8P0JfXI3OJrRqDTSDnPwphTTxDYokFTvK01kCMwjaGWnINX02aFL+N5rCpETBw2Ptojq3SRltbIG5xe9e1sfe0ltWU2YiwQ7Zp9ekQKV2A5TZjZ55rtjO6C3HqBYWz/AnxiizWGgBAIxHuM4D0mPHOK4u/7tnfC3CIaD8UqINE1Dz3qfeDDgf0rzgVq+b6pbaoEquCkvvbng2rFfY/MVq3tb3gFGR6G1qWA+XKPJwBm9ODWcHxAliqzMsvja26izwtK8ci3VBmaL6mWcyuaWcfA4Wbjo2sb7srcS9COjUvuZf6NiTqehBpplUHkqoyFq9+QO2zfVUZ0PMltEEuTmoG6K0PSnzROUjim5FavnVCzKlvLv8ChG/GE3sYMWxBFfJCpnXhfPkNyghok+WGiTqc4pBIy3KnqbCs1xxZhfJ3UVvd1Rkq1xEW3VnEJSg76EDerj5J526Q6V6i4dbXHnxeeoHLUfIGapIa4Pv63DwxSaH72gJXrtrT4X6XgQjEuZofLvm2q8QToTxSezT4Fc76ojVOJF3ssPJMwC7mx8hcYDjy1cWkw5pNvLgj5QDAspAgKSMuoe0YQU2ES7oOtTHZ7peSAGz+8zoJNoy1gQCGH95uztt/tkCyYPl3JaYF0A9j8oOWxAfJJMVBcxszt9EqD+j246JofJM5Gnn5SpgrIyWngpiK3G2xiM68=
|
||||
db.password: AgCtaz+QGcnKsKonIsAmT9oiZHd9cmj4ntKZ2vhH4cwDzCw0mHu3s1NKGTFxqVkrxyn0S2PbM+6gSXFyz6FtxI+nhb1gP6+QbSLmbJk35+sdC90WYj51r+k1tjugGaw8RpdAACxHSe7Vf8S0fPS5JFqrLR5HzmthoqNwzChcXjALCkArSXEG2kuQj0Dx72NTStYOQCPth0pPFytako3gHlSHFgGrjQ/g/hOnrP/booIFl4GMAZnJ5CgwI4XQKP4VvyK8msF93T278pyFr7fFFVSLrYrzpqFYfpKrHdiwirooed52Xlwpy6tfFsD64kZ0hDd5xbzXStNxDBkPOOgEu+KSbqUuGu5s/TmqOhxD394RU3AcwiFiQ5nASldeTmzVqC1et5Wx2IuD1b0hVcqGTNh/6uaZRSSchM7enja1v++nd9W7eYkCLdzxUjMC5+GDC/MwNYrrPoIOZAjOLii2UTH0WmvvTu8R79wRmgqCzLykS2VQWaBcMlVQsbyj/IjBbAhTwZ1bu0HKwDQbWckCFQTixR1k612U3gK8P/TsqspSkip9WtlaR3eSwrjqImTe4fhdLI8B6oEYm/D6h4ciXthkl2uYtyd3gwMf3TsHlrev+aOV0K98oaAPkV4EkbDTSQfZDEvAlFwoLScPHBIUahWKPADES7O37cFwkYPo8JOC2yLjYGOlWh997EUsnB/rk2cIdlbVaS8HIWwO1QdPWHelOgBYo1lcWesxRswB1SM7bQ==
|
Loading…
Reference in New Issue