Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 44e1fca7c4 | |||
| 99730bcd0f | |||
| 300dbe9857 | |||
| 8252e8664d | |||
| 9379a33afb | |||
| 92dd36c4f7 | |||
| 79c7ceeec1 | |||
| e1dfdf156d |
@@ -0,0 +1,41 @@
|
||||
name: Release Charts
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@v3
|
||||
with:
|
||||
version: v3.14.0
|
||||
|
||||
# https://github.com/helm/chart-releaser-action/issues/74
|
||||
- name: Add repositories
|
||||
run: |
|
||||
for dir in $(ls -d charts/*/); do
|
||||
helm dependency list $dir 2> /dev/null | tail +2 | head -n -1 | awk '{ print "helm repo add " $1 " " $3 }' | while read cmd; do $cmd; done
|
||||
done
|
||||
|
||||
- name: Run chart-releaser
|
||||
uses: helm/chart-releaser-action@v1.6.0
|
||||
env:
|
||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
with:
|
||||
charts_dir: charts
|
||||
skip_existing: true
|
||||
@@ -0,0 +1,46 @@
|
||||
name: Test setup script
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'docker-compose/**'
|
||||
- '.github/workflows/test.yml'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test setup script
|
||||
runs-on: [self-hosted, Linux]
|
||||
steps:
|
||||
- name: Login to GitHub container registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create working directory
|
||||
run: mkdir temp
|
||||
- name: Run setup script
|
||||
env:
|
||||
DEFGUARD_DOMAIN: "id.localhost"
|
||||
DEFGUARD_ENROLLMENT_DOMAIN: "enrollment.localhost"
|
||||
DEFGUARD_VPN_NAME: "test_location"
|
||||
DEFGUARD_VPN_IP: "10.0.60.1/24"
|
||||
DEFGUARD_VPN_GATEWAY_IP: "10.20.20.40"
|
||||
DEFGUARD_VPN_GATEWAY_PORT: "50050"
|
||||
CORE_IMAGE_TAG: latest
|
||||
PROXY_IMAGE_TAG: latest
|
||||
GATEWAY_IMAGE_TAG: latest
|
||||
working-directory: temp
|
||||
run: curl --proto '=https' --tlsv1.2 -sSf -L https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/setup.sh | bash -s - --non-interactive
|
||||
- name: Sleep for 10 seconds
|
||||
working-directory: temp
|
||||
run: sleep 10s
|
||||
- name: Test defguard is available
|
||||
working-directory: temp
|
||||
run: curl -f http://id.localhost/api/v1/health
|
||||
- name: Stop compose stack
|
||||
if: always()
|
||||
working-directory: temp
|
||||
run: docker-compose down
|
||||
@@ -0,0 +1,3 @@
|
||||
docker-compose/.env
|
||||
docker-compose/.volumes
|
||||
.idea
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright 2023 teonite ventures sp. z o.o. (teonite)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,16 @@
|
||||
<p align="center">
|
||||
<img src="docs/header.png" alt="defguard">
|
||||
</p>
|
||||
|
||||
# Defguard deployment
|
||||
|
||||
Check our [documentation](https://defguard.gitbook.io/defguard/features/setting-up-your-instance) for deployment
|
||||
instructions.
|
||||
|
||||
## Community and Support
|
||||
|
||||
Find us on Matrix: [#defguard:teonite.com](https://matrix.to/#/#defguard:teonite.com)
|
||||
|
||||
## Contribution
|
||||
|
||||
Please review the [Contributing guide](https://defguard.gitbook.io/defguard/for-developers/contributing) for information on how to get started contributing to the project. You might also find our [environment setup guide](https://defguard.gitbook.io/defguard/for-developers/dev-env-setup) handy.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: v2
|
||||
name: defguard-proxy
|
||||
description: Defguard proxy is a public-facing proxy for core defguard service
|
||||
|
||||
type: application
|
||||
version: 0.3.5
|
||||
appVersion: 0.5.0
|
||||
@@ -0,0 +1,20 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}/
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "defguard-proxy.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "defguard-proxy.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "defguard-proxy.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "defguard-proxy.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
@@ -0,0 +1,62 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "defguard-proxy.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "defguard-proxy.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "defguard-proxy.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "defguard-proxy.labels" -}}
|
||||
helm.sh/chart: {{ include "defguard-proxy.chart" . }}
|
||||
{{ include "defguard-proxy.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "defguard-proxy.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "defguard-proxy.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "defguard-proxy.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "defguard-proxy.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "defguard-proxy.fullname" . }}-config
|
||||
labels:
|
||||
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||
data:
|
||||
DEFGUARD_PROXY_HTTP_PORT: {{ .Values.service.ports.http | quote }}
|
||||
DEFGUARD_PROXY_GRPC_PORT: {{ .Values.service.ports.grpc | quote }}
|
||||
@@ -0,0 +1,67 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "defguard-proxy.fullname" . }}
|
||||
labels:
|
||||
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "defguard-proxy.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "defguard-proxy.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "defguard-proxy.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: {{ include "defguard-proxy.fullname" . }}-config
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.ports.http }}
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
containerPort: {{ .Values.service.ports.grpc }}
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/service.serversscheme: h2c
|
||||
name: {{ include "defguard-proxy.fullname" . }}-grpc
|
||||
labels:
|
||||
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.ports.grpc }}
|
||||
targetPort: grpc
|
||||
protocol: TCP
|
||||
name: grpc
|
||||
selector:
|
||||
{{- include "defguard-proxy.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,52 @@
|
||||
{{- if .Values.ingress.grpc.enabled -}}
|
||||
{{- $fullName := include "defguard-proxy.fullname" . -}}
|
||||
{{- if and .Values.ingress.grpc.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.grpc.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.grpc.annotations "kubernetes.io/ingress.class" .Values.ingress.grpc.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}-grpc
|
||||
labels:
|
||||
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.grpc.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.grpc.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.grpc.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.grpc.tls }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.ingress.grpc.host | quote }}
|
||||
secretName: {{ printf "%s-grpc-tls" .Values.ingress.grpc.host }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.grpc.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: ImplementationSpecific
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}-grpc
|
||||
port:
|
||||
number: {{ .Values.service.ports.grpc }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}-grpc
|
||||
servicePort: {{ .Values.service.ports.grpc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,52 @@
|
||||
{{- if .Values.ingress.web.enabled -}}
|
||||
{{- $fullName := include "defguard-proxy.fullname" . -}}
|
||||
{{- if and .Values.ingress.web.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.web.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.web.annotations "kubernetes.io/ingress.class" .Values.ingress.web.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}-web
|
||||
labels:
|
||||
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.web.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.web.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.web.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.web.tls }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.ingress.web.host | quote }}
|
||||
secretName: {{ printf "%s-web-tls" .Values.ingress.web.host }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.web.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: ImplementationSpecific
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}-web
|
||||
port:
|
||||
number: {{ .Values.service.ports.http }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}-web
|
||||
servicePort: {{ .Values.service.ports.http }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "defguard-proxy.fullname" . }}-web
|
||||
labels:
|
||||
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.ports.http }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "defguard-proxy.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "defguard-proxy.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "defguard-proxy.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,42 @@
|
||||
affinity: {}
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
fullnameOverride: ""
|
||||
image:
|
||||
pullPolicy: IfNotPresent
|
||||
repository: ghcr.io/defguard/defguard-proxy
|
||||
tag: ""
|
||||
imagePullSecrets: []
|
||||
ingress:
|
||||
grpc:
|
||||
annotations: {}
|
||||
className: ""
|
||||
enabled: true
|
||||
host: enrollment-grpc.local
|
||||
tls: false
|
||||
web:
|
||||
annotations: {}
|
||||
className: ""
|
||||
enabled: true
|
||||
host: enrollment.local
|
||||
tls: false
|
||||
nameOverride: ""
|
||||
nodeSelector: {}
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
podSecurityContext: {}
|
||||
publicUrl: "http://enrollment.local"
|
||||
replicaCount: 1
|
||||
resources: {}
|
||||
securityContext: {}
|
||||
service:
|
||||
ports:
|
||||
http: 8080
|
||||
grpc: 50051
|
||||
type: ClusterIP
|
||||
serviceAccount:
|
||||
annotations: {}
|
||||
create: true
|
||||
tolerations: []
|
||||
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
@@ -0,0 +1,9 @@
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 12.12.10
|
||||
- name: defguard-proxy
|
||||
repository: https://defguard.github.io/deployment
|
||||
version: 0.3.5
|
||||
digest: sha256:de930b480616cfa369caf7b1447c5b3e729fce3e17994717ab0f64aa02c027e7
|
||||
generated: "2024-07-26T09:00:54.309522115+02:00"
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v2
|
||||
name: defguard
|
||||
description: Defguard is an open-source enterprise wireGuard VPN with MFA and SSO
|
||||
|
||||
type: application
|
||||
version: 0.7.6
|
||||
appVersion: 0.11.0
|
||||
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
condition: postgresql.enabled
|
||||
version: 12.12.10
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
- name: defguard-proxy
|
||||
condition: defguard-proxy.enabled
|
||||
version: 0.3.5
|
||||
repository: https://defguard.github.io/deployment
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}/
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "defguard.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "defguard.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "defguard.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "defguard.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
@@ -0,0 +1,78 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "defguard.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "defguard.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "defguard.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "defguard.labels" -}}
|
||||
helm.sh/chart: {{ include "defguard.chart" . }}
|
||||
{{ include "defguard.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "defguard.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "defguard.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "defguard.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "defguard.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Define OpenID secret name
|
||||
*/}}
|
||||
{{- define "defguard.openidSecretName" -}}
|
||||
{{- $name := "openid-key" }}
|
||||
{{- $name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Define JWT secret name
|
||||
*/}}
|
||||
{{- define "defguard.jwtSecretName" -}}
|
||||
{{- $name := "jwt-secrets" }}
|
||||
{{- $name }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,30 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "defguard.fullname" . }}-config
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
data:
|
||||
{{- if .Values.cookie.domain }}
|
||||
DEFGUARD_COOKIE_DOMAIN: {{ .Values.cookie.domain }}
|
||||
{{- end }}
|
||||
DEFGUARD_COOKIE_INSECURE: {{ .Values.cookie.insecure | quote }}
|
||||
DEFGUARD_DB_HOST: {{ .Values.postgresql.host | default (printf "%s-postgresql" (include "defguard.fullname" .)) }}
|
||||
DEFGUARD_DB_PORT: {{ .Values.postgresql.port | quote}}
|
||||
DEFGUARD_DB_NAME: {{ .Values.postgresql.auth.database }}
|
||||
DEFGUARD_DB_USER: {{ .Values.postgresql.auth.username }}
|
||||
DEFGUARD_GRPC_PORT: {{ .Values.service.ports.grpc | quote }}
|
||||
DEFGUARD_ENROLLMENT_URL: {{ index .Values "defguard-proxy" "publicUrl" }}
|
||||
{{- if .Values.proxyUrl }}
|
||||
DEFGUARD_PROXY_URL: {{ .Values.proxyUrl }}
|
||||
{{- end }}
|
||||
DEFGUARD_URL: {{ .Values.publicUrl }}
|
||||
DEFGUARD_WEBAUTHN_RP_ID: {{ .Values.ingress.web.host }}
|
||||
{{- if .Values.ldap.enabled }}
|
||||
DEFGUARD_LDAP_ADMIN_GROUP: {{ .Values.ldap.admin_group | quote }}
|
||||
DEFGUARD_LDAP_BIND_PASSWORD: {{ .Values.ldap.bind_password | quote }}
|
||||
DEFGUARD_LDAP_BIND_USERNAME: {{ .Values.ldap.bind_username | quote }}
|
||||
DEFGUARD_LDAP_GROUP_SEARCH_BASE: {{ .Values.ldap.group_search_base | quote }}
|
||||
DEFGUARD_LDAP_USER_SEARCH_BASE: {{ .Values.ldap.user_search_base | quote }}
|
||||
DEFGUARD_LDAP_URL: {{ .Values.ldap.url | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,105 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "defguard.fullname" . }}
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "defguard.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "defguard.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "defguard.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
env:
|
||||
- name: DEFGUARD_DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.postgresql.auth.existingSecret }}
|
||||
key: {{ .Values.postgresql.auth.existingSecretPasswordKey | default "password" }}
|
||||
- name: DEFGUARD_AUTH_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.existingJwtSecret | default (include "defguard.jwtSecretName" .) }}
|
||||
key: auth
|
||||
- name: DEFGUARD_GATEWAY_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.existingJwtSecret | default (include "defguard.jwtSecretName" .) }}
|
||||
key: gateway
|
||||
- name: DEFGUARD_YUBIBRIDGE_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.existingJwtSecret | default (include "defguard.jwtSecretName" .) }}
|
||||
key: yubi-bridge
|
||||
- name: DEFGUARD_SECRET_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.existingJwtSecret | default (include "defguard.jwtSecretName" .) }}
|
||||
key: secret-key
|
||||
- name: DEFGUARD_OPENID_KEY
|
||||
value: "/etc/defguard-openid-key.pem"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: {{ include "defguard.fullname" . }}-config
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8000
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
containerPort: 50055
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: openid-key
|
||||
mountPath: "/etc/defguard-openid-key.pem"
|
||||
readOnly: true
|
||||
subPath: openid-key
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: openid-key
|
||||
secret:
|
||||
secretName: {{ .Values.existingOpenIdSecret | default (include "defguard.openidSecretName" .) }}
|
||||
optional: false
|
||||
@@ -0,0 +1,25 @@
|
||||
{{ if not .Values.existingJwtSecret }}
|
||||
{{- $auth := (randAlpha 16) | b64enc | quote }}
|
||||
{{- $gateway := (randAlpha 16) | b64enc | quote }}
|
||||
{{- $yubiBridge := (randAlpha 16) | b64enc | quote }}
|
||||
{{- $secretKey := (randAlpha 64) | b64enc | quote }}
|
||||
{{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "defguard.jwtSecretName" .)) }}
|
||||
{{- if $secret }}
|
||||
{{- $auth = index $secret.data "auth" }}
|
||||
{{- $gateway = index $secret.data "gateway" }}
|
||||
{{- $yubiBridge = index $secret.data "yubi-bridge" }}
|
||||
{{- $secretKey = index $secret.data "secret-key" }}
|
||||
{{- end }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "defguard.jwtSecretName" . }}
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
auth: {{ $auth }}
|
||||
gateway: {{ $gateway }}
|
||||
yubi-bridge: {{ $yubiBridge }}
|
||||
secret-key: {{ $secretKey }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "defguard.fullname" . }}-web
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.ports.http }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "defguard.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/service.serversscheme: h2c
|
||||
name: {{ include "defguard.fullname" . }}-grpc
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.ports.grpc }}
|
||||
targetPort: grpc
|
||||
protocol: TCP
|
||||
name: grpc
|
||||
selector:
|
||||
{{- include "defguard.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,52 @@
|
||||
{{- if .Values.ingress.grpc.enabled -}}
|
||||
{{- $fullName := include "defguard.fullname" . -}}
|
||||
{{- if and .Values.ingress.grpc.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.grpc.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.grpc.annotations "kubernetes.io/ingress.class" .Values.ingress.grpc.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}-grpc
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.grpc.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.grpc.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.grpc.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.grpc.tls }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.ingress.grpc.host | quote }}
|
||||
secretName: {{ printf "%s-grpc-tls" .Values.ingress.grpc.host }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.grpc.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: ImplementationSpecific
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}-grpc
|
||||
port:
|
||||
number: {{ .Values.service.ports.grpc }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}-grpc
|
||||
servicePort: {{ .Values.service.ports.grpc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,52 @@
|
||||
{{- if .Values.ingress.web.enabled -}}
|
||||
{{- $fullName := include "defguard.fullname" . -}}
|
||||
{{- if and .Values.ingress.web.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.web.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.web.annotations "kubernetes.io/ingress.class" .Values.ingress.web.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}-web
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.web.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.web.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.web.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.web.tls }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.ingress.web.host | quote }}
|
||||
secretName: {{ printf "%s-web-tls" .Values.ingress.web.host }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.web.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
{{- if semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: ImplementationSpecific
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}-web
|
||||
port:
|
||||
number: {{ .Values.service.ports.http }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}-web
|
||||
servicePort: {{ .Values.service.ports.http }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,16 @@
|
||||
{{ if not .Values.existingOpenIdSecret }}
|
||||
{{- $openIdKey := (genPrivateKey "rsa") | b64enc | quote }}
|
||||
{{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "defguard.openidSecretName" .)) }}
|
||||
{{- if $secret }}
|
||||
{{- $openIdKey = index $secret.data "openid-key" }}
|
||||
{{- end }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "defguard.openidSecretName" . }}
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
openid-key: {{ $openIdKey }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,19 @@
|
||||
{{ if .Values.postgresql.enabled }}
|
||||
{{- $password := (randAlpha 16) | b64enc | quote }}
|
||||
{{- $postgresPassword := (randAlpha 16) | b64enc | quote }}
|
||||
{{- $secret := (lookup "v1" "Secret" .Release.Namespace .Values.postgresql.auth.existingSecret) }}
|
||||
{{- if $secret }}
|
||||
{{- $password = index $secret.data "password" }}
|
||||
{{- $postgresPassword = index $secret.data "postgres-password" }}
|
||||
{{- end }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Values.postgresql.auth.existingSecret }}
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
password: {{ $password }}
|
||||
postgres-password: {{ $postgresPassword }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "defguard.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "defguard.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,75 @@
|
||||
affinity: {}
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
cookie:
|
||||
domain: ""
|
||||
insecure: false
|
||||
fullnameOverride: ""
|
||||
image:
|
||||
pullPolicy: IfNotPresent
|
||||
repository: ghcr.io/defguard/defguard
|
||||
tag: ""
|
||||
imagePullSecrets: []
|
||||
ingress:
|
||||
grpc:
|
||||
annotations: {}
|
||||
className: ""
|
||||
enabled: true
|
||||
host: defguard-grpc.local
|
||||
tls: false
|
||||
web:
|
||||
annotations: {}
|
||||
className: ""
|
||||
enabled: true
|
||||
host: defguard.local
|
||||
tls: false
|
||||
existingJwtSecret: ""
|
||||
ldap:
|
||||
admin_group: ""
|
||||
bind_password: ""
|
||||
bind_username: ""
|
||||
enabled: false
|
||||
group_search_base: ""
|
||||
url: ""
|
||||
user_search_base: ""
|
||||
nameOverride: ""
|
||||
nodeSelector: {}
|
||||
existingOpenIdSecret: ""
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
podSecurityContext: {}
|
||||
# sub-chart bitnami/postgresql
|
||||
postgresql:
|
||||
enabled: true
|
||||
host: "" # set if using external postgresql ~ enabled: false
|
||||
port: 5432
|
||||
auth:
|
||||
database: defguard
|
||||
existingSecret: postgres-password
|
||||
existingSecretPasswordKey: "" # set if using external postgresql ~ enabled: false
|
||||
username: defguard
|
||||
proxyUrl: ""
|
||||
publicUrl: "http://defguard.local"
|
||||
replicaCount: 1
|
||||
resources: {}
|
||||
securityContext: {}
|
||||
service:
|
||||
ports:
|
||||
grpc: 50055
|
||||
http: 80
|
||||
type: ClusterIP
|
||||
serviceAccount:
|
||||
annotations: {}
|
||||
create: true
|
||||
tolerations: []
|
||||
# sub-chart defguard-proxy
|
||||
defguard-proxy:
|
||||
enabled: false
|
||||
publicUrl: "http://enrollment.local"
|
||||
ingress:
|
||||
grpc:
|
||||
host: defguard-proxy-grpc.local
|
||||
web:
|
||||
host: enrollment.local
|
||||
@@ -0,0 +1,31 @@
|
||||
# The best way to define each secret is to generate random strings with e.g.:
|
||||
#
|
||||
# openssl rand -base64 48 #this will generate a 48chars random string
|
||||
#
|
||||
# Please provide secret strings (do not share them) for:
|
||||
#
|
||||
# Secret used for JWT cryptography
|
||||
DEFGUARD_AUTH_SECRET=<YOUR_AUTH_SECRET>
|
||||
# Secret used for JWT cryptography in YubiBridge GRPC communication
|
||||
DEFGUARD_YUBIBRIDGE_SECRET=<DEFGUARD_YUBIBRIDGE_SECRET>
|
||||
# Secret used for JWT cryptography in gateway GRPC communication
|
||||
DEFGUARD_GATEWAY_SECRET=<DEFGUARD_GATEWAY_SECRET>
|
||||
# Secret used for private cookies cryptography; must be at least 64 characters long
|
||||
DEFGUARD_SECRET_KEY=<DEFGUARD_SECRET_KEY>
|
||||
# Database password
|
||||
DEFGUARD_DB_PASSWORD=<YOUR_DB_PASSWORD>
|
||||
# Public URL of your Defguard instance
|
||||
# E.g.: https://defguard.mycompany.com
|
||||
DEFGUARD_URL=<YOUR_DEFGUARD_URL>
|
||||
# Webauthn RP ID (https://w3c.github.io/webauthn/#rp-id)
|
||||
# E.g.: defguard.mycompany.com (without http/https)
|
||||
DEFGUARD_WEBAUTHN_RP_ID=<YOUR_DEFGUARD_WEBAUTHN_RP_ID>
|
||||
# Public URL of your defguard proxy gRPC server
|
||||
# DEFGUARD_PROXY_URL=<YOUR_PROXY_GRPC_URL>
|
||||
# Public URL of your enrollment service
|
||||
# E.g.: https://enrollment.mycompany.com
|
||||
# DEFGUARD_ENROLLMENT_URL=<YOUR_PROXY_URL> # [ENROLLMENT]
|
||||
# Token used for VPN gateway authorization
|
||||
# DEFGUARD_TOKEN=<GATEWAY_TOKEN> # [VPN]
|
||||
# Enable insecure cookies when not using HTTPS
|
||||
# DEFGUARD_COOKIE_INSECURE=true # [HTTP]
|
||||
@@ -0,0 +1,110 @@
|
||||
services:
|
||||
db:
|
||||
image: postgres:15-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: defguard
|
||||
POSTGRES_USER: defguard
|
||||
POSTGRES_PASSWORD: ${DEFGUARD_DB_PASSWORD}
|
||||
volumes:
|
||||
- ${VOLUME_DIR:-./.volumes}/db:/var/lib/postgresql/data
|
||||
# ports:
|
||||
# - "5432:5432"
|
||||
|
||||
caddy: # [PROXY]
|
||||
image: caddy:2.7-alpine # [PROXY]
|
||||
restart: unless-stopped # [PROXY]
|
||||
volumes: # [PROXY]
|
||||
- ${VOLUME_DIR:-./.volumes}/caddy/data:/data # [PROXY]
|
||||
- ${VOLUME_DIR:-./.volumes}/caddy/config:/config # [PROXY]
|
||||
- ${VOLUME_DIR:-./.volumes}/caddy/Caddyfile:/etc/caddy/Caddyfile # [PROXY]
|
||||
ports: # [PROXY]
|
||||
#http
|
||||
- "8002:80" # [PROXY]
|
||||
#https
|
||||
- "6443:443" # [PROXY]
|
||||
|
||||
core:
|
||||
image: ghcr.io/defguard/defguard:${CORE_IMAGE_TAG:-latest}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
DEFGUARD_AUTH_SECRET: ${DEFGUARD_AUTH_SECRET}
|
||||
DEFGUARD_GATEWAY_SECRET: ${DEFGUARD_GATEWAY_SECRET}
|
||||
DEFGUARD_YUBIBRIDGE_SECRET: ${DEFGUARD_YUBIBRIDGE_SECRET}
|
||||
DEFGUARD_SECRET_KEY: ${DEFGUARD_SECRET_KEY}
|
||||
DEFGUARD_DEFAULT_ADMIN_PASSWORD: ${DEFGUARD_DEFAULT_ADMIN_PASSWORD}
|
||||
DEFGUARD_DB_HOST: db
|
||||
DEFGUARD_DB_PORT: 5432
|
||||
DEFGUARD_DB_USER: defguard
|
||||
DEFGUARD_DB_PASSWORD: ${DEFGUARD_DB_PASSWORD}
|
||||
DEFGUARD_DB_NAME: defguard
|
||||
DEFGUARD_URL: ${DEFGUARD_URL}
|
||||
DEFGUARD_LOG_LEVEL: info
|
||||
DEFGUARD_WEBAUTHN_RP_ID: ${DEFGUARD_WEBAUTHN_RP_ID}
|
||||
DEFGUARD_COOKIE_INSECURE: ${DEFGUARD_COOKIE_INSECURE:-false}
|
||||
DEFGUARD_ENROLLMENT_URL: ${DEFGUARD_ENROLLMENT_URL} # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_URL: https://proxy:50052 # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_GRPC_CA: /ssl/defguard-ca.pem # [ENROLLMENT]
|
||||
DEFGUARD_GRPC_CERT: /ssl/defguard-grpc.crt
|
||||
DEFGUARD_GRPC_KEY: /ssl/defguard-grpc.key
|
||||
## RSA setup guide: https://defguard.gitbook.io/defguard/community-features/setting-up-your-instance/docker-compose#openid-rsa-setup
|
||||
DEFGUARD_OPENID_KEY: /keys/rsakey.pem
|
||||
## LDAP setup guide: https://defguard.gitbook.io/defguard/features/ldap-synchronization-setup
|
||||
# DEFGUARD_LDAP_URL: ldap://localhost:389 # [LDAP]
|
||||
# DEFGUARD_LDAP_BIND_USERNAME: cn=admin,dc=example,dc=org # [LDAP]
|
||||
# DEFGUARD_LDAP_BIND_PASSWORD: password # [LDAP]
|
||||
ports:
|
||||
# web
|
||||
- "9876:8000"
|
||||
# grpc
|
||||
- "50055:50055"
|
||||
depends_on:
|
||||
- db
|
||||
volumes:
|
||||
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||
- ${VOLUME_DIR:-./.volumes}/ssl:/ssl
|
||||
## RSA setup guide: https://defguard.gitbook.io/defguard/community-features/setting-up-your-instance/docker-compose#openid-rsa-setup
|
||||
- ${VOLUME_DIR:-./.volumes}/core/rsakey.pem:/keys/rsakey.pem
|
||||
proxy: # [ENROLLMENT]
|
||||
image: ghcr.io/defguard/defguard-proxy:${PROXY_IMAGE_TAG:-latest} # [ENROLLMENT]
|
||||
restart: unless-stopped # [ENROLLMENT]
|
||||
environment: # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_GRPC_PORT: 50052 # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_GRPC_CERT: /ssl/defguard-proxy-grpc.crt # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_GRPC_KEY: /ssl/defguard-proxy-grpc.key # [ENROLLMENT]
|
||||
volumes: # [ENROLLMENT]
|
||||
#SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||
- ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [ENROLLMENT]
|
||||
ports:
|
||||
# web
|
||||
- "8588:8080"
|
||||
depends_on: # [ENROLLMENT]
|
||||
- core # [ENROLLMENT]
|
||||
|
||||
gateway: # [VPN]
|
||||
image: ghcr.io/defguard/gateway:${GATEWAY_IMAGE_TAG:-latest} # [VPN]
|
||||
restart: unless-stopped # [VPN]
|
||||
network_mode: "host" # [VPN]
|
||||
environment: # [VPN]
|
||||
DEFGUARD_GRPC_URL: https://localhost:50055 # [VPN]
|
||||
DEFGUARD_GRPC_CA: /ssl/defguard-ca.pem # [VPN]
|
||||
DEFGUARD_STATS_PERIOD: 30 # [VPN]
|
||||
DEFGUARD_TOKEN: ${DEFGUARD_TOKEN} # [VPN]
|
||||
volumes: # [VPN]
|
||||
- ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [VPN]
|
||||
cap_add: # [VPN]
|
||||
- NET_ADMIN # [VPN]
|
||||
|
||||
gateway-OpenVPN: # [VPN]
|
||||
image: ghcr.io/defguard/gateway:${GATEWAY_IMAGE_TAG:-latest} # [VPN]
|
||||
restart: unless-stopped # [VPN]
|
||||
network_mode: "host" # [VPN]
|
||||
environment: # [VPN]
|
||||
DEFGUARD_GRPC_URL: https://localhost:50055 # [VPN]
|
||||
DEFGUARD_GRPC_CA: /ssl/defguard-ca.pem # [VPN]
|
||||
DEFGUARD_STATS_PERIOD: 30 # [VPN]
|
||||
DEFGUARD_TOKEN: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJEZWZHdWFyZCIsInN1YiI6IkRFRkdVQVJELU5FVFdPUkstNSIsImNsaWVudF9pZCI6IjUiLCJleHAiOjYwMTkyNjE4NDMsIm5iZiI6MTcyNDI5NDU0OH0.cV9dgj0B7hjT7LaLqbZ0sp8u-Fl71X13mnDppFXaD4E
|
||||
volumes: # [VPN]
|
||||
- ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [VPN]
|
||||
cap_add: # [VPN]
|
||||
- NET_ADMIN # [VPN]
|
||||
+890
@@ -0,0 +1,890 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
# This is a script that sets up an entire defguard instance (including core,
|
||||
# gateway, enrollment proxy and reverse proxy). It's goal is to prepare
|
||||
# a working instance by running a single command.
|
||||
|
||||
set -o errexit # abort on nonzero exitstatus
|
||||
set -o pipefail # don't hide errors within pipes
|
||||
|
||||
# Global variables
|
||||
VERSION="1.0.2"
|
||||
SECRET_LENGTH=64
|
||||
PASSWORD_LENGTH=16
|
||||
|
||||
VOLUME_DIR=".volumes"
|
||||
SSL_DIR="${VOLUME_DIR}/ssl"
|
||||
RSA_DIR="${VOLUME_DIR}/core"
|
||||
|
||||
COMPOSE_FILE="docker-compose.yaml"
|
||||
ENV_FILE=".env"
|
||||
LOG_FILE=$(mktemp setup.log.XXXXXX)
|
||||
|
||||
BASE_COMPOSE_FILE_URL="https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/docker-compose.yaml"
|
||||
BASE_ENV_FILE_URL="https://raw.githubusercontent.com/DefGuard/deployment/main/docker-compose/.env.template"
|
||||
|
||||
CORE_IMAGE_TAG="${CORE_IMAGE_TAG:-latest}"
|
||||
GATEWAY_IMAGE_TAG="${GATEWAY_IMAGE_TAG:-latest}"
|
||||
PROXY_IMAGE_TAG="${PROXY_IMAGE_TAG:-latest}"
|
||||
|
||||
|
||||
#####################
|
||||
### MAIN FUNCTION ###
|
||||
#####################
|
||||
|
||||
main() {
|
||||
is_utf_term
|
||||
is_term_color
|
||||
tput reset
|
||||
print_header
|
||||
|
||||
# display help `--help` argument is found
|
||||
for i in $*; do
|
||||
test "$i" == "--help" && print_usage && exit 0
|
||||
|
||||
# run non interactive
|
||||
if [[ "$i" == "--non-interactive" ]]; then
|
||||
CFG_NON_INTERACTIVE=1
|
||||
# we need to remove this element from $* or getopt will return an error
|
||||
set -- $(remove_element "$i" $*)
|
||||
fi
|
||||
|
||||
# configure https
|
||||
if [[ "$i" == "--use-https" ]]; then
|
||||
CFG_USE_HTTPS=1
|
||||
# we need to remove this element from $* or getopt will return an error
|
||||
set -- $(remove_element "$i" $*)
|
||||
fi
|
||||
done
|
||||
|
||||
#
|
||||
# First let's gather the ENV/command line variables
|
||||
#
|
||||
|
||||
# load configuration from env variables
|
||||
load_configuration_from_env
|
||||
|
||||
# load configuration from CLI options
|
||||
load_configuration_from_cli "$@"
|
||||
|
||||
# load configuration from user inputs
|
||||
if [ X$CFG_VOLUME_DIR != X ]; then
|
||||
VOLUME_DIR=${CFG_VOLUME_DIR}
|
||||
SSL_DIR="${VOLUME_DIR}/ssl"
|
||||
RSA_DIR="${VOLUME_DIR}/core"
|
||||
fi
|
||||
|
||||
export VOLUME_DIR
|
||||
|
||||
# We have enough to check the enviromnent
|
||||
# so check if necessary tools are available
|
||||
check_environment
|
||||
|
||||
# load configuration from user inputs
|
||||
if ! [ $CFG_NON_INTERACTIVE ]; then
|
||||
load_configuration_from_input
|
||||
fi
|
||||
|
||||
# check that all required configuration options are set
|
||||
validate_required_variables
|
||||
|
||||
# generate external service URLs based on config
|
||||
generate_external_urls
|
||||
|
||||
# print out config
|
||||
print_config
|
||||
|
||||
# set current working directory
|
||||
WORK_DIR_PATH=$(pwd)
|
||||
|
||||
# setup RSA & SSL keys
|
||||
setup_keys
|
||||
|
||||
# generate caddyfile
|
||||
create_caddyfile
|
||||
|
||||
# generate `.env` file
|
||||
generate_env_file
|
||||
|
||||
# enable insecure cookies if not using HTTPS
|
||||
if ! [ "$CFG_USE_HTTPS" ]; then
|
||||
uncomment_feature "HTTP" "${PROD_ENV_FILE}"
|
||||
fi
|
||||
|
||||
# generate base docker-compose file
|
||||
PROD_COMPOSE_FILE="${WORK_DIR_PATH}/${COMPOSE_FILE}"
|
||||
if [ -f "$PROD_COMPOSE_FILE" ]; then
|
||||
echo -n " ${TXT_BEGIN} Using existing docker-compose file at ${PROD_COMPOSE_FILE}... "
|
||||
print_confirmation
|
||||
else
|
||||
fetch_base_compose_file
|
||||
fi
|
||||
|
||||
# enable reverse proxy in compose file
|
||||
uncomment_feature "PROXY" "${PROD_COMPOSE_FILE}"
|
||||
|
||||
# enable enrollment service in compose file
|
||||
if [ "$CFG_ENABLE_ENROLLMENT" ]; then
|
||||
enable_enrollment
|
||||
fi
|
||||
|
||||
# fetch latest images
|
||||
echo " ${TXT_BEGIN} Fetching latest Docker images: "
|
||||
$COMPOSE_CMD -f "${PROD_COMPOSE_FILE}" --env-file "${PROD_ENV_FILE}" pull
|
||||
|
||||
# enable and setup VPN gateway
|
||||
if [ "$CFG_ENABLE_VPN" ]; then
|
||||
enable_vpn_gateway
|
||||
fi
|
||||
|
||||
# start docker-compose stack
|
||||
echo " ${TXT_BEGIN} Starting docker-compose stack"
|
||||
$COMPOSE_CMD -f "${PROD_COMPOSE_FILE}" --env-file "${PROD_ENV_FILE}" up -d
|
||||
if [ $? -ne 0 ]; then
|
||||
echo >&2 "ERROR: failed to start docker-compose stack"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_instance_summary
|
||||
}
|
||||
|
||||
########################
|
||||
### HELPER FUNCTIONS ###
|
||||
########################
|
||||
|
||||
check_character_support() {
|
||||
local char="$1"
|
||||
echo -e "$char" | grep -q "$char"
|
||||
}
|
||||
|
||||
is_utf_term() {
|
||||
if check_character_support "√"; then
|
||||
TXT_CHECK="✓"
|
||||
TXT_BEGIN="▶"
|
||||
TXT_SUB="▷"
|
||||
TXT_STAR="★"
|
||||
TXT_X="✗"
|
||||
TXT_INPUT="✍"
|
||||
else
|
||||
TXT_CHECK="+"
|
||||
TXT_BEGIN=">>"
|
||||
TXT_SUB=">"
|
||||
TXT_STAR="*"
|
||||
TXT_X="x"
|
||||
TXT_INPUT=" ::"
|
||||
fi
|
||||
}
|
||||
|
||||
is_term_color() {
|
||||
|
||||
if [[ $TERM == *"256"* ]]; then
|
||||
C_RED="\033[31m"
|
||||
C_GREEN="\033[32m"
|
||||
C_YELLOW="\033[33m"
|
||||
C_BLUE="\033[34m"
|
||||
C_WHITE="\033[37m"
|
||||
C_GREY="\033[90m"
|
||||
|
||||
C_LRED="\033[91m"
|
||||
C_LGREEN="\033[92m"
|
||||
C_LYELLOW="\033[93m"
|
||||
C_LBLUE="\033[94m"
|
||||
|
||||
C_BOLD="\033[1m"
|
||||
C_ITALICS="\033[3m"
|
||||
C_BG_GREY="\033[100m"
|
||||
C_END="\033[0m"
|
||||
else
|
||||
C_RED=""
|
||||
C_GREEN=""
|
||||
C_YELLOW=""
|
||||
C_BLUE=""
|
||||
C_WHITE=""
|
||||
C_GREY=""
|
||||
|
||||
C_LRED=""
|
||||
C_LGREEN=""
|
||||
C_LYELLOW=""
|
||||
C_LBLUE=""
|
||||
|
||||
C_BOLD=""
|
||||
C_ITALICS=""
|
||||
C_BG_GREY=""
|
||||
C_END=""
|
||||
fi
|
||||
}
|
||||
|
||||
# remove array element
|
||||
remove_element() {
|
||||
local remove=$1
|
||||
local result=()
|
||||
for element in "$@"; do
|
||||
if [[ "$element" != "$remove" ]]; then
|
||||
result+=("$element")
|
||||
fi
|
||||
done
|
||||
echo "${result[@]}"
|
||||
}
|
||||
|
||||
# Function to convert relative path to absolute path
|
||||
to_absolute_path() {
|
||||
local path="$1"
|
||||
if [[ "${path:0:1}" != "/" ]]; then
|
||||
path="$(cd "$(dirname "$path")" && pwd)/$(basename "$path")"
|
||||
fi
|
||||
echo ${path}
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo -e "${C_LBLUE}"
|
||||
cat << _EOF_
|
||||
#
|
||||
## #
|
||||
## ## # # ## #
|
||||
## ## # # # #
|
||||
# ## # #### # #### ##### #### # # #### ### #### #
|
||||
# ## ## # ## # ## # # # # # # # # # ##
|
||||
## ## # # ######## # # # # # # # # #
|
||||
# ## ## # # # ## # ##### # # ###### # # #
|
||||
# ## # # ## # # # # # # # # # # ##
|
||||
## ## #### # ##### # ####### #### # #### # # #### #
|
||||
## ## # # #
|
||||
## # #######
|
||||
#
|
||||
_EOF_
|
||||
echo -e "${C_END}"
|
||||
echo
|
||||
echo "defguard docker-compose deployment setup script v${VERSION}"
|
||||
echo -e "Copyright (C) 2023-2024 ${C_BOLD}teonite${C_END} <${C_BG_GREY}${C_YELLOW}https://teonite.com${C_END}>"
|
||||
echo
|
||||
}
|
||||
|
||||
print_confirmation() {
|
||||
echo -e " ${C_LGREEN}${TXT_CHECK}${C_END} "
|
||||
}
|
||||
|
||||
print_usage() {
|
||||
|
||||
echo "Usage: ${BASENAME} [options]"
|
||||
echo
|
||||
echo 'Available options:'
|
||||
echo
|
||||
echo -e "\t--help this help message"
|
||||
echo -e "\t--non-interactive run in non-interactive mode - !REQUIRES SETTING all options/env vars"
|
||||
echo -e "\t--domain <domain> domain where defguard web UI will be available"
|
||||
echo -e "\t--enrollment-domain <domain> domain where enrollment service will be available"
|
||||
echo -e "\t--use-https configure reverse proxy to use HTTPS"
|
||||
echo -e "\t--volume <directory> Docker volumes directory - default: ${VOLUME_DIR}"
|
||||
echo -e "\t--vpn-name <name> VPN location name"
|
||||
echo -e "\t--vpn-ip <address> VPN server address & netmask (e.g. 10.0.50.1/24)"
|
||||
echo -e "\t--vpn-gateway-ip <ip> VPN gateway external IP (! NOT DOMAIN - IP)"
|
||||
echo -e "\t--vpn-gateway-port <port> VPN gateway external port (your clients connect here)"
|
||||
echo
|
||||
}
|
||||
|
||||
command_exists() {
|
||||
local command="$1"
|
||||
command -v "$command" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
command_exists_check() {
|
||||
local command="$1"
|
||||
if ! command_exists "$command"; then
|
||||
echo >&2 "ERROR: $command command not found"
|
||||
echo >&2 "ERROR: dependency failed, exiting..."
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
check_environment() {
|
||||
echo -n " ${TXT_BEGIN} Checking if all required tools are available..."
|
||||
# compose can be provided by newer docker versions or a separate docker-compose
|
||||
docker compose version >/dev/null 2>&1
|
||||
if [ $? = 0 ]; then
|
||||
COMPOSE_CMD="docker compose"
|
||||
else
|
||||
if command_exists docker-compose; then
|
||||
COMPOSE_CMD="docker-compose"
|
||||
else
|
||||
echo
|
||||
echo >&2 "ERROR: docker-compose or docker compose command not found"
|
||||
echo >&2 "ERROR: dependency failed, exiting..."
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
command_exists_check openssl
|
||||
command_exists_check curl
|
||||
command_exists_check grep
|
||||
|
||||
# Check if the volume dir is an absolute path since docker requires it
|
||||
VOLUME_DIR=$(to_absolute_path "${VOLUME_DIR}")
|
||||
|
||||
if [ -d ${VOLUME_DIR} ]; then
|
||||
echo
|
||||
echo >&2 "ERROR: volume directory: ${VOLUME_DIR} exists."
|
||||
echo >&2 "ERROR: this means, I would overwrite the configuration, database and certificates."
|
||||
echo >&2 "ERROR: please backup or remove the volume directory."
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# create all necessary directories
|
||||
for dir in ${VOLUME_DIR} ${SSL_DIR} ${RSA_DIR}; do
|
||||
mkdir ${dir}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo >&2 "ERROR: cloud not create volume directory: ${dir}"
|
||||
exit 3
|
||||
fi
|
||||
done
|
||||
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
load_configuration_from_env() {
|
||||
echo -n " ${TXT_BEGIN} Loading configuration from environment variables... "
|
||||
# required variables
|
||||
CFG_DOMAIN="$DEFGUARD_DOMAIN"
|
||||
|
||||
# optional variables
|
||||
CFG_VOLUME_DIR="$DEFGUARD_VOLUME_DIR"
|
||||
CFG_VPN_NAME="$DEFGUARD_VPN_NAME"
|
||||
CFG_VPN_IP="$DEFGUARD_VPN_IP"
|
||||
CFG_VPN_GATEWAY_IP="$DEFGUARD_VPN_GATEWAY_IP"
|
||||
CFG_VPN_GATEWAY_PORT="$DEFGUARD_VPN_GATEWAY_PORT"
|
||||
CFG_ENROLLMENT_DOMAIN="$DEFGUARD_ENROLLMENT_DOMAIN"
|
||||
if ! [ $CFG_USE_HTTPS ]; then
|
||||
CFG_USE_HTTPS="$DEFGUARD_USE_HTTPS"
|
||||
fi
|
||||
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
load_configuration_from_cli() {
|
||||
echo -n " ${TXT_BEGIN} Loading configuration from CLI arguments... "
|
||||
|
||||
ARGUMENT_LIST=(
|
||||
"domain"
|
||||
"enrollment-domain"
|
||||
"volume"
|
||||
"vpn-name"
|
||||
"vpn-ip"
|
||||
"vpn-gateway-ip"
|
||||
"vpn-gateway-port"
|
||||
)
|
||||
|
||||
# read arguments
|
||||
opts=$(
|
||||
getopt \
|
||||
--longoptions "$(printf "%s:," "${ARGUMENT_LIST[@]}")" \
|
||||
--name "$(basename "$0")" \
|
||||
--options "" \
|
||||
-- "$@"
|
||||
)
|
||||
|
||||
eval set --$opts
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--domain)
|
||||
CFG_DOMAIN=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--enrollment-domain)
|
||||
CFG_ENROLLMENT_DOMAIN=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--volume)
|
||||
CFG_VOLUME_DIR=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--vpn-name)
|
||||
CFG_VPN_NAME=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--vpn-ip)
|
||||
CFG_VPN_IP=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--vpn-gateway-ip)
|
||||
CFG_VPN_GATEWAY_IP=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--vpn-gateway-port)
|
||||
CFG_VPN_GATEWAY_PORT=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
load_configuration_from_input() {
|
||||
echo -ne "${C_ITALICS}${C_LBLUE}"
|
||||
cat << _EOF_
|
||||
|
||||
Please provide the values to configure your defguard instance. If you've
|
||||
already configured some options by setting environment variables or through
|
||||
CLI options, those will be used as defaults.
|
||||
|
||||
If you prefer to disable this user input section, please restart the script
|
||||
with --non-interactive CLI flag.
|
||||
|
||||
_EOF_
|
||||
|
||||
echo -ne "${C_GREY}"
|
||||
cat << _EOF_
|
||||
|
||||
Choose domains that will be used to expose your instance through Caddy
|
||||
reverse proxy. defguard uses a separate domain for the Web UI, and for
|
||||
the optional enrollment/desktop client configuration/password reset
|
||||
service.
|
||||
|
||||
If you don't provide any domain for the enrollment service, the service
|
||||
itself will not be deployed.
|
||||
|
||||
You can also enable HTTPS here (highly recommended), which will configure
|
||||
Caddy to automatically provision SSL certificates.
|
||||
_EOF_
|
||||
|
||||
echo -ne "${C_BOLD}"
|
||||
cat << _EOF_
|
||||
|
||||
Please note that this requires your server to have a public IP address
|
||||
and public DNS records for your chosen domains to be configured
|
||||
correctly (pointing to your server's IP address).
|
||||
|
||||
_EOF_
|
||||
|
||||
echo -ne "${C_END}"
|
||||
|
||||
echo -e " ${C_BOLD}${C_GREEN}${TXT_STAR} General config ${TXT_STAR}${C_END}\n"
|
||||
|
||||
while [ X${domain} = "X" ]; do
|
||||
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||
read -p "Enter defguard domain [default: ${CFG_DOMAIN}]: " domain
|
||||
if [ "$domain" ]; then
|
||||
CFG_DOMAIN="$domain"
|
||||
fi
|
||||
done
|
||||
|
||||
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||
read -p "Enter enrollment domain [default: ${CFG_ENROLLMENT_DOMAIN}]: " enroll
|
||||
if [ "$enroll" ]; then
|
||||
CFG_ENROLLMENT_DOMAIN="$enroll"
|
||||
fi
|
||||
|
||||
use_https_bool_value="false"
|
||||
if [ $CFG_USE_HTTPS ]; then use_https_bool_value="true"; fi
|
||||
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||
read -p "Use HTTPS [default: ${use_https_bool_value}]: " https
|
||||
if [ "$https" ]; then
|
||||
CFG_USE_HTTPS=1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -e " ${C_BOLD}${C_GREEN}${TXT_STAR} WireGuard VPN${TXT_STAR}${C_END}\n"
|
||||
|
||||
echo -ne "${C_ITALICS}${C_GREY}"
|
||||
cat << _EOF_
|
||||
|
||||
If you wish to configure and deploy WireGuard VPN gateway, please
|
||||
provide your VPN location name. To skip, just press enter and VPN will
|
||||
not be configured.
|
||||
_EOF_
|
||||
|
||||
echo -ne "${C_END}\n"
|
||||
|
||||
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||
read -p "Enter VPN location name [default: ${CFG_VPN_NAME}]: " vpn_name
|
||||
if [ "$vpn_name" ]; then
|
||||
CFG_VPN_NAME="$vpn_name"
|
||||
fi
|
||||
|
||||
if [ "$CFG_VPN_NAME" ]; then
|
||||
while [ X${vpn_ip} = "X" ]; do
|
||||
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||
read -p "Enter VPN server address and subnet (e.g. 10.0.60.1/24) [default: ${CFG_VPN_IP}]: " vpn_ip
|
||||
if [ "$vpn_ip" ]; then
|
||||
CFG_VPN_IP="$vpn_ip"
|
||||
fi
|
||||
done
|
||||
|
||||
echo -ne "${C_ITALICS}${C_GREY}"
|
||||
cat << _EOF_
|
||||
|
||||
Now we'll configure a public endpoint (IP + port) that your WireGuard
|
||||
client devices will use to safely connect to your gateway from the
|
||||
public internet.
|
||||
|
||||
Since we'll be starting the gateway on this server the IP address should
|
||||
be the same as your server's public IP address.
|
||||
_EOF_
|
||||
echo -ne "${C_BOLD}"
|
||||
cat << _EOF_
|
||||
Please also remember that your firewall should be configured
|
||||
to allow incoming UDP traffic on the chosen WireGuard port.
|
||||
_EOF_
|
||||
|
||||
echo -ne "${C_END}"
|
||||
|
||||
while [ X${public_ip} = "X" ]; do
|
||||
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||
read -p "Enter VPN gateway public IP (no domains!) [default: ${CFG_VPN_GATEWAY_IP}]: " public_ip
|
||||
if [ "$public_ip" ]; then
|
||||
CFG_VPN_GATEWAY_IP="$public_ip"
|
||||
fi
|
||||
done
|
||||
|
||||
while [ X${public_port} = "X" ]; do
|
||||
echo -ne "${C_YELLOW}${TXT_INPUT}${C_END} "
|
||||
read -p "Enter VPN gateway public port [default: ${CFG_VPN_GATEWAY_PORT}]: " public_port
|
||||
if [ "$public_port" ]; then
|
||||
CFG_VPN_GATEWAY_PORT="$public_port"
|
||||
fi
|
||||
done
|
||||
|
||||
else
|
||||
echo -e " ${C_BOLD}${C_RED}${TXT_X} ${C_GREY} WireGuard VPN skipped${C_END}\n"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -e "${C_BOLD}${C_GREEN}Thank you. We'll now proceed with the deployment using provided values.${C_END}"
|
||||
}
|
||||
|
||||
check_required_variable() {
|
||||
local var_name="$1"
|
||||
if [ -z "${!var_name}" ]; then
|
||||
echo >&2 "ERROR: ${var_name} configuration option not set"
|
||||
exit 4
|
||||
fi
|
||||
}
|
||||
|
||||
validate_required_variables() {
|
||||
echo -n " ${TXT_BEGIN} Validating configuration options..."
|
||||
check_required_variable "CFG_DOMAIN"
|
||||
|
||||
# if VPN name is given validate other VPN configurations are present
|
||||
if [ "$CFG_VPN_NAME" ]; then
|
||||
CFG_ENABLE_VPN=1
|
||||
check_required_variable "CFG_VPN_IP"
|
||||
check_required_variable "CFG_VPN_GATEWAY_IP"
|
||||
check_required_variable "CFG_VPN_GATEWAY_PORT"
|
||||
fi
|
||||
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
generate_external_urls() {
|
||||
# prepare full defguard URL
|
||||
if [ $CFG_USE_HTTPS ]; then
|
||||
CFG_DEFGUARD_URL="https://${CFG_DOMAIN}"
|
||||
else
|
||||
CFG_DEFGUARD_URL="http://${CFG_DOMAIN}"
|
||||
fi
|
||||
|
||||
# prepare full enrollment URL
|
||||
if [ "$CFG_ENROLLMENT_DOMAIN" ]; then
|
||||
CFG_ENABLE_ENROLLMENT=1
|
||||
if [ "$CFG_USE_HTTPS" ]; then
|
||||
CFG_ENROLLMENT_URL="https://${CFG_ENROLLMENT_DOMAIN}"
|
||||
else
|
||||
CFG_ENROLLMENT_URL="http://${CFG_ENROLLMENT_DOMAIN}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
print_config() {
|
||||
echo
|
||||
echo " ${TXT_BEGIN} Setting up your defguard instance with following config:"
|
||||
echo
|
||||
echo -e " ${TXT_SUB} data volume: ${C_BOLD}${VOLUME_DIR}${C_END}"
|
||||
echo
|
||||
echo -e " ${TXT_SUB} domain: ${C_BOLD}${CFG_DOMAIN}${C_END}"
|
||||
echo -e " ${TXT_SUB} web UI URL: ${C_BOLD}${CFG_DEFGUARD_URL}${C_END}"
|
||||
|
||||
if [ "$CFG_VPN_NAME" ]; then
|
||||
echo -e " ${TXT_SUB} VPN location name: ${C_BOLD}${CFG_VPN_NAME}${C_END}"
|
||||
echo -e " ${TXT_SUB} VPN address: ${C_BOLD}${CFG_VPN_IP}${C_END}"
|
||||
echo -e " ${TXT_SUB} VPN gateway IP: ${C_BOLD}${CFG_VPN_GATEWAY_IP}${C_END}"
|
||||
echo -e " ${TXT_SUB} VPN gateway port: ${C_BOLD}${CFG_VPN_GATEWAY_PORT}${C_END}"
|
||||
fi
|
||||
|
||||
if [ "$CFG_ENROLLMENT_DOMAIN" ]; then
|
||||
echo -e " ${TXT_SUB} Enrollment service domain: ${C_BOLD}${CFG_ENROLLMENT_DOMAIN}${C_END}"
|
||||
echo -e " ${TXT_SUB} Enrollment service URL: ${C_BOLD}${CFG_ENROLLMENT_URL}${C_END}"
|
||||
fi
|
||||
echo
|
||||
echo -e " ${TXT_BEGIN} All executed command's results are in log file: ${C_BOLD}${LOG_FILE}${C_END}"
|
||||
echo
|
||||
}
|
||||
|
||||
setup_keys() {
|
||||
echo " ${TXT_BEGIN} Setting up SSL certificates and RSA keys..."
|
||||
if [ -d ${SSL_DIR} -a "$(ls -A ${SSL_DIR})" ]; then
|
||||
echo " ${TXT_SUB} Using existing SSL certificates from ${SSL_DIR}"
|
||||
else
|
||||
generate_certs
|
||||
fi
|
||||
|
||||
if [ -d ${RSA_DIR} -a "$(ls -A ${RSA_DIR})" ]; then
|
||||
echo " ${TXT_SUB} Using existing RSA keys from ${RSA_DIR}."
|
||||
else
|
||||
generate_rsa
|
||||
fi
|
||||
}
|
||||
|
||||
generate_certs() {
|
||||
echo " ${TXT_BEGIN} Creating new SSL certificates in ${SSL_DIR}..."
|
||||
mkdir -p ${SSL_DIR}
|
||||
|
||||
PASSPHRASE=$(generate_secret)
|
||||
|
||||
echo "PEM passphrase for SSL certificates set to '${PASSPHRASE}'."
|
||||
|
||||
# generate private key for CA
|
||||
openssl genrsa -des3 -out ${SSL_DIR}/defguard-ca.key -passout pass:"${PASSPHRASE}" 2048 2>&1 >> ${LOG_FILE}
|
||||
# generate Root Certificate
|
||||
# TODO: allow configuring CA parameters
|
||||
openssl req -x509 -new -nodes -key ${SSL_DIR}/defguard-ca.key -sha256 -days 1825 -out ${SSL_DIR}/defguard-ca.pem -passin pass:"${PASSPHRASE}" -subj "/C=PL/ST=Zachodniopomorskie/L=Szczecin/O=Example/OU=IT Department/CN=${CFG_DOMAIN}" 2>&1 >> ${LOG_FILE}
|
||||
|
||||
# generate CA-signed certificate for defguard gRPC
|
||||
openssl genrsa -out ${SSL_DIR}/defguard-grpc.key 2048 2>&1 >> ${LOG_FILE}
|
||||
|
||||
openssl req -new -key ${SSL_DIR}/defguard-grpc.key -out ${SSL_DIR}/defguard-grpc.csr -subj "/C=PL/ST=Zachodniopomorskie/L=Szczecin/O=Example/OU=IT Department/CN=${CFG_DOMAIN}" 2>&1 >> ${LOG_FILE}
|
||||
cat >${SSL_DIR}/defguard-grpc.ext <<EOF
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
|
||||
subjectAltName = @alt_names
|
||||
[alt_names]
|
||||
DNS.1 = ${CFG_DOMAIN}
|
||||
DNS.2 = core
|
||||
DNS.3 = localhost
|
||||
EOF
|
||||
openssl x509 -req -in ${SSL_DIR}/defguard-grpc.csr -CA ${SSL_DIR}/defguard-ca.pem -CAkey ${SSL_DIR}/defguard-ca.key -passin pass:"${PASSPHRASE}" -CAcreateserial \
|
||||
-out ${SSL_DIR}/defguard-grpc.crt -days 1000 -sha256 -extfile ${SSL_DIR}/defguard-grpc.ext 2>&1 >> ${LOG_FILE}
|
||||
|
||||
# generate CA-signed certificate for defguard proxy gRPC
|
||||
openssl genrsa -out ${SSL_DIR}/defguard-proxy-grpc.key 2048 2>&1 >> ${LOG_FILE}
|
||||
|
||||
openssl req -new -key ${SSL_DIR}/defguard-proxy-grpc.key -out ${SSL_DIR}/defguard-proxy-grpc.csr -subj "/C=PL/ST=Zachodniopomorskie/L=Szczecin/O=Example/OU=IT Department/CN=${CFG_DOMAIN}" 2>&1 >> ${LOG_FILE}
|
||||
cat >${SSL_DIR}/defguard-proxy-grpc.ext <<EOF
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
|
||||
subjectAltName = @alt_names
|
||||
[alt_names]
|
||||
DNS.1 = proxy
|
||||
DNS.2 = localhost
|
||||
EOF
|
||||
openssl x509 -req -in ${SSL_DIR}/defguard-proxy-grpc.csr -CA ${SSL_DIR}/defguard-ca.pem -CAkey ${SSL_DIR}/defguard-ca.key -passin pass:"${PASSPHRASE}" -CAcreateserial \
|
||||
-out ${SSL_DIR}/defguard-proxy-grpc.crt -days 1000 -sha256 -extfile ${SSL_DIR}/defguard-proxy-grpc.ext 2>&1 >> ${LOG_FILE}
|
||||
}
|
||||
|
||||
generate_rsa() {
|
||||
echo "Generating RSA keys in ${RSA_DIR}..."
|
||||
mkdir -p ${RSA_DIR}
|
||||
openssl genpkey -out ${RSA_DIR}/rsakey.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048 2>&1 >> ${LOG_FILE}
|
||||
|
||||
}
|
||||
|
||||
generate_secret() {
|
||||
generate_secret_inner "${SECRET_LENGTH}"
|
||||
}
|
||||
|
||||
generate_password() {
|
||||
generate_secret_inner "${PASSWORD_LENGTH}"
|
||||
}
|
||||
|
||||
generate_secret_inner() {
|
||||
local length="$1"
|
||||
openssl rand -base64 ${length} | tr -d "=+/" | tr -d '\n' | cut -c1-${length-1}
|
||||
}
|
||||
|
||||
create_caddyfile() {
|
||||
caddy_volume_path="${VOLUME_DIR}/caddy"
|
||||
caddyfile_path="${caddy_volume_path}/Caddyfile"
|
||||
mkdir -p ${caddy_volume_path}
|
||||
|
||||
cat >${caddyfile_path} <<EOF
|
||||
${CFG_DEFGUARD_URL} {
|
||||
reverse_proxy core:8000
|
||||
}
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$CFG_ENABLE_ENROLLMENT" ]; then
|
||||
cat >>${caddyfile_path} <<EOF
|
||||
${CFG_ENROLLMENT_URL} {
|
||||
reverse_proxy proxy:8080
|
||||
}
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >>${caddyfile_path} <<EOF
|
||||
:80 {
|
||||
respond 404
|
||||
}
|
||||
:443 {
|
||||
respond 404
|
||||
}
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
fetch_base_compose_file() {
|
||||
echo -n " ${TXT_BEGIN} Fetching base compose file to ${PROD_COMPOSE_FILE}... "
|
||||
|
||||
curl --proto '=https' --tlsv1.2 -sSf "${BASE_COMPOSE_FILE_URL}" -o "${PROD_COMPOSE_FILE}" 2>&1 >> ${LOG_FILE}
|
||||
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
generate_env_file() {
|
||||
PROD_ENV_FILE="${WORK_DIR_PATH}/${ENV_FILE}"
|
||||
fetch_base_env_file
|
||||
update_env_file
|
||||
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
fetch_base_env_file() {
|
||||
echo -e " ${TXT_BEGIN} Fetching base ${ENV_FILE} file for compose stack..."
|
||||
|
||||
curl --proto '=https' --tlsv1.2 -sSf "${BASE_ENV_FILE_URL}" -o "${PROD_ENV_FILE}" 2>&1 >> ${LOG_FILE}
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
update_env_file() {
|
||||
echo -n " ${TXT_BEGIN} Setting environment variables in ${ENV_FILE} file for compose stack..."
|
||||
|
||||
# set image versions
|
||||
set_env_file_value "CORE_IMAGE_TAG" "${CORE_IMAGE_TAG}"
|
||||
set_env_file_value "PROXY_IMAGE_TAG" "${PROXY_IMAGE_TAG}"
|
||||
set_env_file_value "GATEWAY_IMAGE_TAG" "${GATEWAY_IMAGE_TAG}"
|
||||
|
||||
# fill in values
|
||||
set_env_file_secret "DEFGUARD_AUTH_SECRET"
|
||||
set_env_file_secret "DEFGUARD_YUBIBRIDGE_SECRET"
|
||||
set_env_file_secret "DEFGUARD_GATEWAY_SECRET"
|
||||
set_env_file_secret "DEFGUARD_SECRET_KEY"
|
||||
|
||||
# use existing password if set in env variable
|
||||
if [ "$DEFGUARD_DB_PASSWORD" ]; then
|
||||
set_env_file_value "DEFGUARD_DB_PASSWORD" "${DEFGUARD_DB_PASSWORD}"
|
||||
else
|
||||
set_env_file_password "DEFGUARD_DB_PASSWORD"
|
||||
fi
|
||||
|
||||
DEFGUARD_DEFAULT_ADMIN_PASSWORD="$(generate_password)"
|
||||
set_env_file_value "DEFGUARD_DEFAULT_ADMIN_PASSWORD" "${DEFGUARD_DEFAULT_ADMIN_PASSWORD}"
|
||||
|
||||
set_env_file_value "DEFGUARD_URL" "${CFG_DEFGUARD_URL}"
|
||||
set_env_file_value "DEFGUARD_WEBAUTHN_RP_ID" "${CFG_DOMAIN}"
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
set_env_file_value() {
|
||||
# make sure variable exists in file
|
||||
grep -qF "${1}=" "${PROD_ENV_FILE}" || echo "${1}=" >>"${PROD_ENV_FILE}"
|
||||
sed -i "s@\(${1}\)=.*@\1=${2}@" "${PROD_ENV_FILE}"
|
||||
}
|
||||
|
||||
set_env_file_secret() {
|
||||
set_env_file_value "${1}" "$(generate_secret)" "${PROD_ENV_FILE}"
|
||||
}
|
||||
|
||||
set_env_file_password() {
|
||||
set_env_file_value "${1}" "$(generate_password)" "${PROD_ENV_FILE}"
|
||||
}
|
||||
|
||||
uncomment_feature() {
|
||||
sed -i "s@# \(.*\) # \[${1}\]@\1@" "${2}"
|
||||
}
|
||||
|
||||
enable_enrollment() {
|
||||
echo -n " ${TXT_BEGIN} Enabling enrollment proxy service in compose file..."
|
||||
|
||||
# update .env file
|
||||
uncomment_feature "ENROLLMENT" "${PROD_ENV_FILE}"
|
||||
set_env_file_value "DEFGUARD_ENROLLMENT_URL" "${CFG_ENROLLMENT_URL}"
|
||||
|
||||
# update compose file
|
||||
uncomment_feature "ENROLLMENT" "${PROD_COMPOSE_FILE}"
|
||||
|
||||
print_confirmation
|
||||
}
|
||||
|
||||
enable_vpn_gateway() {
|
||||
echo " ${TXT_BEGIN} Enabling VPN gateway service..."
|
||||
|
||||
uncomment_feature "VPN" "${PROD_COMPOSE_FILE}"
|
||||
uncomment_feature "VPN" "${PROD_ENV_FILE}"
|
||||
|
||||
# fetch latest image
|
||||
echo " ${TXT_SUB} Fetching latest gateway image..."
|
||||
$COMPOSE_CMD -f "${PROD_COMPOSE_FILE}" --env-file "${PROD_ENV_FILE}" pull gateway
|
||||
|
||||
# create VPN location
|
||||
echo " ${TXT_BEGIN} Adding VPN to core & generating gateway token..."
|
||||
VPN_NETWORK=`echo ${CFG_VPN_IP} | awk -F'[./]' '{print $1"."$2"."$3".0/"$5}'`
|
||||
token=$($COMPOSE_CMD -f "${PROD_COMPOSE_FILE}" --env-file "${PROD_ENV_FILE}" run core init-vpn-location --name "${CFG_VPN_NAME}" --address "${CFG_VPN_IP}" --endpoint "${CFG_VPN_GATEWAY_IP}" --port "${CFG_VPN_GATEWAY_PORT}" --allowed-ips "${VPN_NETWORK}" | tail -n 1)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo >&2 "ERROR: failed to create VPN network"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# add gateway token to .env file
|
||||
set_env_file_value "DEFGUARD_TOKEN" "${token}"
|
||||
}
|
||||
|
||||
print_instance_summary() {
|
||||
echo
|
||||
echo -e "${C_LGREEN} ${TXT_CHECK} defguard setup finished successfully${C_END}"
|
||||
echo
|
||||
echo "If your DNS configuration is correct your defguard instance should be available at:"
|
||||
echo
|
||||
echo -e "\t${TXT_SUB} Web UI: ${C_BOLD}${CFG_DEFGUARD_URL}${C_END}"
|
||||
if [ "$CFG_ENABLE_ENROLLMENT" ]; then
|
||||
echo -e "\t${TXT_SUB} Enrollment service: ${C_BOLD}${CFG_ENROLLMENT_URL}${C_END}"
|
||||
fi
|
||||
echo
|
||||
echo -e " ${TXT_BEGIN} You can log into the UI using the default admin user:"
|
||||
echo
|
||||
echo -e "\t${TXT_SUB} username: ${C_BOLD}admin${C_END}"
|
||||
echo -e "\t${TXT_SUB} password: ${C_BOLD}${DEFGUARD_DEFAULT_ADMIN_PASSWORD}${C_END}"
|
||||
echo
|
||||
if [ "$CFG_ENABLE_VPN" ]; then
|
||||
echo -e "\t\tVPN server public endpoint is ${C_BOLD}${CFG_VPN_GATEWAY_IP}:${CFG_VPN_GATEWAY_PORT}${C_END}"
|
||||
echo -e "\t\tVPN network is ${C_BOLD}${VPN_NETWORK}${C_END}"
|
||||
echo -e "\t\t! Make sure your firewall allows external UDP traffic to port ${C_BOLD}${CFG_VPN_GATEWAY_PORT}${C_END} !"
|
||||
echo
|
||||
echo -e "\t\tTo test if the VPN is working: ping ${CFG_VPN_IP} (after connecting to VPN)"
|
||||
fi
|
||||
echo
|
||||
echo -e "Files used to deploy your instance are stored in:"
|
||||
echo -e "\t docker compose file: ${C_BOLD}${PROD_COMPOSE_FILE}${C_END}"
|
||||
echo -e "\t docker compose environment: ${C_BOLD}${PROD_ENV_FILE}${C_END}"
|
||||
echo
|
||||
echo -e "Persistent data (docker volumes) is stored in ${C_BOLD}${VOLUME_DIR}${C_END}"
|
||||
echo
|
||||
echo -e " ${C_YELLOW}${TXT_STAR} To support our work, please star us on GitHub! ${TXT_STAR}${C_END}"
|
||||
echo -e " ${C_YELLOW}${TXT_STAR} https://github.com/defguard/defguard ${TXT_STAR}${C_END}"
|
||||
echo
|
||||
}
|
||||
|
||||
# run main function
|
||||
main "$@" || exit 1
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,9 @@
|
||||
# Use userspace wireguard implementation, useful on systems without native wireguard support
|
||||
# Set to 0/1
|
||||
DEFGUARD_USERSPACE=0
|
||||
# Defguard GRPC URL, e.g.: defguard-grpc.mycompany.com
|
||||
DEFGUARD_GRPC_URL=<DEFGUARD_GRPC_URL>
|
||||
# Token from Defguard app to secure gRPC connection, available on network page.
|
||||
DEFGUARD_TOKEN=<DEFGUARD_TOKEN>
|
||||
# Defines how often (in seconds) should interface statistics be sent to Defguard server
|
||||
DEFGUARD_STATS_PERIOD=30
|
||||
@@ -0,0 +1,22 @@
|
||||
version: "3"
|
||||
services:
|
||||
gateway:
|
||||
image: ghcr.io/defguard/gateway:latest
|
||||
restart: unless-stopped
|
||||
network_mode: "host"
|
||||
environment:
|
||||
# load variables from .env file
|
||||
- DEFGUARD_GRPC_URL
|
||||
- DEFGUARD_TOKEN
|
||||
- DEFGUARD_STATS_PERIOD
|
||||
- RUST_LOG=debug
|
||||
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||
# - DEFGUARD_GRPC_CA: /ssl/defguard-ca.pem
|
||||
ports:
|
||||
# wireguard endpoint
|
||||
- "50051:50051/udp"
|
||||
#volumes:
|
||||
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||
#- ./.volumes/ssl:/ssl
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
@@ -9,20 +9,20 @@ services:
|
||||
volumes:
|
||||
- ${VOLUME_DIR:-./.volumes}/db:/var/lib/postgresql/data
|
||||
# ports:
|
||||
# - "5432:5432"
|
||||
# - "5432:5432"
|
||||
|
||||
# caddy: # [PROXY]
|
||||
# image: caddy:2.7-alpine # [PROXY]
|
||||
# restart: unless-stopped # [PROXY]
|
||||
# volumes: # [PROXY]
|
||||
# - ${VOLUME_DIR:-./.volumes}/caddy/data:/data # [PROXY]
|
||||
# - ${VOLUME_DIR:-./.volumes}/caddy/config:/config # [PROXY]
|
||||
# - ${VOLUME_DIR:-./.volumes}/caddy/Caddyfile:/etc/caddy/Caddyfile # [PROXY]
|
||||
# ports: # [PROXY]
|
||||
# # http # [PROXY]
|
||||
# - "80:80" # [PROXY]
|
||||
# # https # [PROXY]
|
||||
# - "443:443" # [PROXY]
|
||||
caddy: # [PROXY]
|
||||
image: caddy:2.7-alpine # [PROXY]
|
||||
restart: unless-stopped # [PROXY]
|
||||
volumes: # [PROXY]
|
||||
- ${VOLUME_DIR:-./.volumes}/caddy/data:/data # [PROXY]
|
||||
- ${VOLUME_DIR:-./.volumes}/caddy/config:/config # [PROXY]
|
||||
- ${VOLUME_DIR:-./.volumes}/caddy/Caddyfile:/etc/caddy/Caddyfile # [PROXY]
|
||||
ports: # [PROXY]
|
||||
#http
|
||||
- "8002:80" # [PROXY]
|
||||
#https
|
||||
- "6443:443" # [PROXY]
|
||||
|
||||
core:
|
||||
image: ghcr.io/defguard/defguard:${CORE_IMAGE_TAG:-latest}
|
||||
@@ -40,13 +40,13 @@ services:
|
||||
DEFGUARD_DB_NAME: defguard
|
||||
DEFGUARD_URL: ${DEFGUARD_URL}
|
||||
DEFGUARD_LOG_LEVEL: info
|
||||
# DEFGUARD_WEBAUTHN_RP_ID: ${DEFGUARD_WEBAUTHN_RP_ID}
|
||||
DEFGUARD_WEBAUTHN_RP_ID: ${DEFGUARD_WEBAUTHN_RP_ID}
|
||||
DEFGUARD_COOKIE_INSECURE: ${DEFGUARD_COOKIE_INSECURE:-false}
|
||||
DEFGUARD_ENROLLMENT_URL: ${DEFGUARD_ENROLLMENT_URL} # [ENROLLMENT]
|
||||
# DEFGUARD_PROXY_URL: https://proxy:50052 # [ENROLLMENT]
|
||||
# DEFGUARD_PROXY_GRPC_CA: /ssl/defguard-ca.pem # [ENROLLMENT]
|
||||
#DEFGUARD_GRPC_CERT: /ssl/defguard-grpc.crt
|
||||
#DEFGUARD_GRPC_KEY: /ssl/defguard-grpc.key
|
||||
DEFGUARD_PROXY_URL: https://proxy:50052 # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_GRPC_CA: /ssl/defguard-ca.pem # [ENROLLMENT]
|
||||
DEFGUARD_GRPC_CERT: /ssl/defguard-grpc.crt
|
||||
DEFGUARD_GRPC_KEY: /ssl/defguard-grpc.key
|
||||
## RSA setup guide: https://defguard.gitbook.io/defguard/community-features/setting-up-your-instance/docker-compose#openid-rsa-setup
|
||||
DEFGUARD_OPENID_KEY: /keys/rsakey.pem
|
||||
## LDAP setup guide: https://defguard.gitbook.io/defguard/features/ldap-synchronization-setup
|
||||
@@ -55,7 +55,7 @@ services:
|
||||
# DEFGUARD_LDAP_BIND_PASSWORD: password # [LDAP]
|
||||
ports:
|
||||
# web
|
||||
- "8850:8000"
|
||||
- "9876:8000"
|
||||
# grpc
|
||||
- "50055:50055"
|
||||
depends_on:
|
||||
@@ -65,34 +65,32 @@ services:
|
||||
- ${VOLUME_DIR:-./.volumes}/ssl:/ssl
|
||||
## RSA setup guide: https://defguard.gitbook.io/defguard/community-features/setting-up-your-instance/docker-compose#openid-rsa-setup
|
||||
- ${VOLUME_DIR:-./.volumes}/core/rsakey.pem:/keys/rsakey.pem
|
||||
proxy: # [ENROLLMENT]
|
||||
image: ghcr.io/defguard/defguard-proxy:${PROXY_IMAGE_TAG:-latest} # [ENROLLMENT]
|
||||
restart: unless-stopped # [ENROLLMENT]
|
||||
environment: # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_GRPC_PORT: 50052 # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_GRPC_CERT: /ssl/defguard-proxy-grpc.crt # [ENROLLMENT]
|
||||
DEFGUARD_PROXY_GRPC_KEY: /ssl/defguard-proxy-grpc.key # [ENROLLMENT]
|
||||
volumes: # [ENROLLMENT]
|
||||
#SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||
- ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [ENROLLMENT]
|
||||
ports:
|
||||
# web
|
||||
- "8588:8080"
|
||||
depends_on: # [ENROLLMENT]
|
||||
- core # [ENROLLMENT]
|
||||
|
||||
# proxy: # [ENROLLMENT]
|
||||
# image: ghcr.io/defguard/defguard-proxy:${PROXY_IMAGE_TAG:-latest} # [ENROLLMENT]
|
||||
# restart: unless-stopped # [ENROLLMENT]
|
||||
# environment: # [ENROLLMENT]
|
||||
# DEFGUARD_PROXY_GRPC_PORT: 50052 # [ENROLLMENT]
|
||||
# DEFGUARD_PROXY_GRPC_CERT: /ssl/defguard-proxy-grpc.crt # [ENROLLMENT]
|
||||
# DEFGUARD_PROXY_GRPC_KEY: /ssl/defguard-proxy-grpc.key # [ENROLLMENT]
|
||||
# volumes: # [ENROLLMENT]
|
||||
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||
# - ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [ENROLLMENT]
|
||||
# ports:
|
||||
# # web
|
||||
# - "8080:8080"
|
||||
# depends_on: # [ENROLLMENT]
|
||||
# - core # [ENROLLMENT]
|
||||
|
||||
# gateway: # [VPN]
|
||||
# image: ghcr.io/defguard/gateway:${GATEWAY_IMAGE_TAG:-latest} # [VPN]
|
||||
# restart: unless-stopped # [VPN]
|
||||
# network_mode: "host" # [VPN]
|
||||
# environment: # [VPN]
|
||||
# DEFGUARD_GRPC_URL: https://localhost:50055 # [VPN]
|
||||
# DEFGUARD_GRPC_CA: /ssl/defguard-ca.pem # [VPN]
|
||||
# DEFGUARD_STATS_PERIOD: 30 # [VPN]
|
||||
# DEFGUARD_TOKEN: ${DEFGUARD_TOKEN} # [VPN]
|
||||
# volumes: # [VPN]
|
||||
# SSL setup guide: https://defguard.gitbook.io/defguard/features/setting-up-your-instance/docker-compose#ssl-setup
|
||||
# - ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [VPN]
|
||||
# cap_add: # [VPN]
|
||||
# - NET_ADMIN # [VPN]
|
||||
gateway: # [VPN]
|
||||
image: ghcr.io/defguard/gateway:${GATEWAY_IMAGE_TAG:-latest} # [VPN]
|
||||
restart: unless-stopped # [VPN]
|
||||
network_mode: "host" # [VPN]
|
||||
environment: # [VPN]
|
||||
DEFGUARD_GRPC_URL: https://localhost:50055 # [VPN]
|
||||
DEFGUARD_GRPC_CA: /ssl/defguard-ca.pem # [VPN]
|
||||
DEFGUARD_STATS_PERIOD: 30 # [VPN]
|
||||
DEFGUARD_TOKEN: ${DEFGUARD_TOKEN} # [VPN]
|
||||
volumes: # [VPN]
|
||||
- ${VOLUME_DIR:-./.volumes}/ssl:/ssl # [VPN]
|
||||
cap_add: # [VPN]
|
||||
- NET_ADMIN # [VPN]
|
||||
|
||||
Submodule
+1
Submodule guacamole-docker-compose added at 1901755b0b
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -s https://raw.githubusercontent.com/tteck/Proxmox/main/misc/build.func)
|
||||
# Copyright (c) 2021-2024 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# License: MIT
|
||||
# https://github.com/tteck/Proxmox/raw/main/LICENSE
|
||||
|
||||
function header_info {
|
||||
clear
|
||||
cat <<"EOF"
|
||||
____ __
|
||||
/ __ \____ _____ ___ _____/ /__ __________ ____ ____ __ __
|
||||
/ /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/___/ __ \/ __ `/ |/_/
|
||||
/ ____/ /_/ / /_/ / __/ / / / __(__ |__ )___/ / / / /_/ /> <
|
||||
/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_|
|
||||
/_/ /____/
|
||||
|
||||
EOF
|
||||
}
|
||||
header_info
|
||||
echo -e "Loading..."
|
||||
APP="Paperless-ngx"
|
||||
var_disk="10"
|
||||
var_cpu="2"
|
||||
var_ram="2048"
|
||||
var_os="debian"
|
||||
var_version="12"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function default_settings() {
|
||||
CT_TYPE="1"
|
||||
PW=""
|
||||
CT_ID=$NEXTID
|
||||
HN=$NSAPP
|
||||
DISK_SIZE="$var_disk"
|
||||
CORE_COUNT="$var_cpu"
|
||||
RAM_SIZE="$var_ram"
|
||||
BRG="vmbr0"
|
||||
NET="dhcp"
|
||||
GATE=""
|
||||
APT_CACHER=""
|
||||
APT_CACHER_IP=""
|
||||
DISABLEIP6="no"
|
||||
MTU=""
|
||||
SD=""
|
||||
NS=""
|
||||
MAC=""
|
||||
VLAN=""
|
||||
SSH="no"
|
||||
VERB="no"
|
||||
echo_default
|
||||
}
|
||||
|
||||
function update_script() {
|
||||
if [[ ! -d /opt/paperless ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
RELEASE=$(curl -s https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
|
||||
|
||||
UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \
|
||||
"1" "Update Paperless-ngx to $RELEASE" ON \
|
||||
"2" "Paperless-ngx Credentials" OFF \
|
||||
3>&1 1>&2 2>&3)
|
||||
header_info
|
||||
if [ "$UPD" == "1" ]; then
|
||||
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
|
||||
msg_info "Stopping all Paperless-ngx Services"
|
||||
systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
|
||||
msg_ok "Stopped all Paperless-ngx Services"
|
||||
|
||||
msg_info "Updating to ${RELEASE}"
|
||||
cd ~
|
||||
wget -q https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz
|
||||
tar -xf paperless-ngx-$RELEASE.tar.xz
|
||||
cp -r /opt/paperless/paperless.conf paperless-ngx/
|
||||
cp -r paperless-ngx/* /opt/paperless/
|
||||
cd /opt/paperless
|
||||
pip install -r requirements.txt &>/dev/null
|
||||
cd /opt/paperless/src
|
||||
/usr/bin/python3 manage.py migrate &>/dev/null
|
||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||
msg_ok "Updated to ${RELEASE}"
|
||||
|
||||
msg_info "Cleaning up"
|
||||
cd ~
|
||||
rm paperless-ngx-$RELEASE.tar.xz
|
||||
rm -rf paperless-ngx
|
||||
msg_ok "Cleaned"
|
||||
|
||||
msg_info "Starting all Paperless-ngx Services"
|
||||
systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
|
||||
sleep 1
|
||||
msg_ok "Started all Paperless-ngx Services"
|
||||
msg_ok "Updated Successfully!\n"
|
||||
else
|
||||
msg_ok "No update required. ${APP} is already at ${RELEASE}"
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
if [ "$UPD" == "2" ]; then
|
||||
cat paperless.creds
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed Successfully!\n"
|
||||
echo -e "${APP} should be reachable by going to the following URL.
|
||||
${BL}http://${IP}:8008${CL} \n"
|
||||
@@ -0,0 +1,71 @@
|
||||
# Environment
|
||||
NODE_ENV=development
|
||||
|
||||
# Ports
|
||||
PORT=3000
|
||||
|
||||
# URLs
|
||||
# These URLs must reference a publicly accessible domain or IP address, not a docker container ID (depending on your compose setup)
|
||||
PUBLIC_URL=http://localhost:3000
|
||||
PUBLIC_SERVER_URL=http://localhost:3000/
|
||||
STORAGE_URL=http://localhost:9000/default # default is the bucket name specified in the STORAGE_BUCKET variable
|
||||
|
||||
# Database (Prisma/PostgreSQL)
|
||||
# This can be swapped out to use any other database, like MySQL
|
||||
# Note: This is used only in the compose.yml file
|
||||
POSTGRES_PORT=5437
|
||||
POSTGRES_DB=postgres
|
||||
POSTGRES_USER=Zakaria
|
||||
POSTGRES_PASSWORD=thamed-original
|
||||
|
||||
# Database (Prisma/PostgreSQL)
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5437/postgres?schema=public
|
||||
|
||||
# Authentication Secrets
|
||||
# generated with `openssl rand -base64 64`
|
||||
ACCESS_TOKEN_SECRET=2431754516ca6dfc7d512446237d429b40dc7f4a73208cbfb2d22c4cb6afbb98b49ebb2791e4a7c8955cdadc985568a281cdfe673d5e223568803039412fa725
|
||||
REFRESH_TOKEN_SECRET=c4fc4c102c3590e7017dbbd82e511d5bf3b48748bfb66ed31d1bf3ea3a675731c4fc4c102c3590e7017dbbd82e511d5bf3b48748bfb66ed31d1bf3ea3a675731
|
||||
|
||||
# Chrome Browser (for printing)
|
||||
# generated with `openssl rand -hex 32`
|
||||
CHROME_PORT=8180
|
||||
CHROME_TOKEN=c4fc4c102c3590e7017dbbd82e511d5bf3b48748bfb66ed31d1bf3ea3a675731
|
||||
CHROME_URL=wss://localhost:8180
|
||||
# Launch puppeteer with flag to ignore https errors
|
||||
CHROME_IGNORE_HTTPS_ERRORS=true
|
||||
|
||||
# Mail Server (for e-mails)
|
||||
# For testing, you can use https://ethereal.email/create
|
||||
MAIL_FROM=noreply@localhost
|
||||
# SMTP_URL=smtp://username:password@smtp.ethereal.email:587
|
||||
|
||||
# Storage
|
||||
STORAGE_ENDPOINT=localhost
|
||||
STORAGE_PORT=9050
|
||||
STORAGE_REGION=us-east-1
|
||||
STORAGE_BUCKET=default
|
||||
STORAGE_ACCESS_KEY=minioadmin
|
||||
STORAGE_SECRET_KEY=minioadmin
|
||||
STORAGE_USE_SSL=false
|
||||
STORAGE_SKIP_BUCKET_CHECK=false
|
||||
|
||||
# Nx Cloud (Optional)
|
||||
# NX_CLOUD_ACCESS_TOKEN=
|
||||
|
||||
# Crowdin (Optional)
|
||||
# CROWDIN_PROJECT_ID=
|
||||
# CROWDIN_PERSONAL_TOKEN=
|
||||
|
||||
# Feature Flags (Optional)
|
||||
# DISABLE_SIGNUPS=false
|
||||
# DISABLE_EMAIL_AUTH=false
|
||||
|
||||
# GitHub (OAuth, Optional)
|
||||
# GITHUB_CLIENT_ID=
|
||||
# GITHUB_CLIENT_SECRET=
|
||||
# GITHUB_CALLBACK_URL=http://localhost:5173/api/auth/github/callback
|
||||
|
||||
# Google (OAuth, Optional)
|
||||
# GOOGLE_CLIENT_ID=
|
||||
# GOOGLE_CLIENT_SECRET=
|
||||
# GOOGLE_CALLBACK_URL=http://localhost:5173/api/auth/google/callback
|
||||
@@ -0,0 +1,107 @@
|
||||
# In this Docker Compose example, it assumes that you maintain a reverse proxy externally (or chose not to).
|
||||
# The only two exposed ports here are from minio (:9000) and the app itself (:3000).
|
||||
# If these ports are changed, ensure that the env vars passed to the app are also changed accordingly.
|
||||
|
||||
services:
|
||||
# Database (Postgres)
|
||||
postgres:
|
||||
image: postgres:16.4-alpine3.20
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./postgres_data:/var/lib/postgresql/data
|
||||
environment:
|
||||
POSTGRES_DB: dataBase
|
||||
POSTGRES_USER: Zakaria
|
||||
POSTGRES_PASSWORD: thamed-cream-love
|
||||
|
||||
# Storage (for image uploads)
|
||||
minio:
|
||||
image: minio/minio
|
||||
restart: unless-stopped
|
||||
command: server /data
|
||||
ports:
|
||||
- "9000:9000"
|
||||
volumes:
|
||||
- minio_data:/data
|
||||
environment:
|
||||
MINIO_ROOT_USER: minioadmin
|
||||
MINIO_ROOT_PASSWORD: minioadmin
|
||||
|
||||
# Chrome Browser (for printing and previews)
|
||||
chrome:
|
||||
image: lscr.io/linuxserver/chromium:latest
|
||||
restart: unless-stopped
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
environment:
|
||||
TIMEOUT: 50000
|
||||
CONCURRENT: 10
|
||||
TOKEN: chrome_token
|
||||
EXIT_ON_HEALTH_FAILURE: true
|
||||
PRE_REQUEST_HEALTH_CHECK: true
|
||||
|
||||
app:
|
||||
image: amruthpillai/reactive-resume:latest
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
- postgres
|
||||
- minio
|
||||
- chrome
|
||||
environment:
|
||||
# -- Environment Variables --
|
||||
PORT: 3000
|
||||
NODE_ENV: production
|
||||
|
||||
# -- Database (Postgres) --
|
||||
DATABASE_URL: postgresql://Zakaria:thamed-cream-love@postgres:5432/dataBase?schema=public
|
||||
|
||||
# -- URLs --
|
||||
PUBLIC_URL: http://localhost:3000
|
||||
STORAGE_URL: http://localhost:9000/default
|
||||
|
||||
# -- Printer (Chrome) --
|
||||
CHROME_TOKEN: chrome_token
|
||||
CHROME_URL: ws://chrome:3000
|
||||
|
||||
# -- Auth --
|
||||
ACCESS_TOKEN_SECRET: 34dd5592342c3cb6f53e8f27cf805b1ff974a05e4bbae47b35cc79bcea268f3529e572635f36a305
|
||||
REFRESH_TOKEN_SECRET: 34dd5592342c3cb6f53e8f27cf805b1ff974a05e4bbae47b35cc79bcea268f3529e572635f36a305
|
||||
|
||||
# -- Emails --
|
||||
MAIL_FROM: noreply@localhost
|
||||
# SMTP_URL: smtp://user:pass@smtp:587 # Optional
|
||||
|
||||
# -- Storage (Minio) --
|
||||
STORAGE_ENDPOINT: minio
|
||||
STORAGE_PORT: 9000
|
||||
STORAGE_REGION: us-east-1 # Optional
|
||||
STORAGE_BUCKET: default
|
||||
STORAGE_ACCESS_KEY: minioadmin
|
||||
STORAGE_SECRET_KEY: minioadmin
|
||||
STORAGE_USE_SSL: false
|
||||
STORAGE_SKIP_BUCKET_CHECK: false
|
||||
|
||||
# -- Crowdin (Optional) --
|
||||
# CROWDIN_PROJECT_ID:
|
||||
# CROWDIN_PERSONAL_TOKEN:
|
||||
|
||||
# -- Email (Optional) --
|
||||
# DISABLE_SIGNUPS: false
|
||||
# DISABLE_EMAIL_AUTH: false
|
||||
|
||||
# -- GitHub (Optional) --
|
||||
# GITHUB_CLIENT_ID: github_client_id
|
||||
# GITHUB_CLIENT_SECRET: github_client_secret
|
||||
# GITHUB_CALLBACK_URL: http://localhost:3000/api/auth/github/callback
|
||||
|
||||
# -- Google (Optional) --
|
||||
# GOOGLE_CLIENT_ID: google_client_id
|
||||
# GOOGLE_CLIENT_SECRET: google_client_secret
|
||||
# GOOGLE_CALLBACK_URL: http://localhost:3000/api/auth/google/callback
|
||||
|
||||
volumes:
|
||||
minio_data:
|
||||
postgres_data:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
16
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user