Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ README is mirrored to `gh-pages`.
| Chart | Description | Source |
|-------|-------------|--------|
| [ipsec-vpn-server](charts/ipsec-vpn-server) | Deploy IPsec VPN server inside K8s with optional sealed-secrets | [taskmedia/helm](https://github.com/taskmedia/helm/tree/main/charts/ipsec-vpn-server) |
| [outprint](charts/outprint) | PDF export for self-hosted Outline: Gateway, network-less Worker and injector | [taskmedia/helm](https://github.com/taskmedia/helm/tree/main/charts/outprint) |
| [paperless-gpt](charts/paperless-gpt) | LLM-powered OCR and metadata assistant for paperless-ngx | [taskmedia/helm](https://github.com/taskmedia/helm/tree/main/charts/paperless-gpt) |
| [paperlessngx-backup](charts/paperlessngx-backup) | Backup paperless-ngx via K8s cronjob to FTP | [taskmedia/helm](https://github.com/taskmedia/helm/tree/main/charts/paperlessngx-backup) |
| [paperlessngx-ftp-bridge](charts/paperlessngx-ftp-bridge) | Embedded FTP/FTPS server that forwards scanner uploads to paperless-ngx | [taskmedia/helm](https://github.com/taskmedia/helm/tree/main/charts/paperlessngx-ftp-bridge) |
Expand Down
2 changes: 2 additions & 0 deletions charts/outprint/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
*.swp
36 changes: 36 additions & 0 deletions charts/outprint/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
apiVersion: v2
name: outprint
description: Outprint for Outline - Gateway, network-less Worker and injector
home: https://helm.task.media/outprint
keywords:
- outprint
- outline
- pdf
- latex
maintainers:
- name: fty4
url: https://github.com/fty4
sources:
- https://github.com/taskmedia/outprint
- https://github.com/taskmedia/helm
icon: https://media.task.media/images/logo.png
type: application
version: 1.0.0
# outprint release tag without the leading v
appVersion: "1.0.0"

annotations:
artifacthub.io/category: skip-prediction
artifacthub.io/links: |
- name: support
url: https://github.com/taskmedia/helm/issues
- name: source
url: https://github.com/taskmedia/helm/tree/main/charts/outprint
artifacthub.io/images: |
- name: outprint
image: ghcr.io/taskmedia/outprint:1.0.0
- name: outprint-injector
image: ghcr.io/taskmedia/outprint-injector:1.0.0
artifacthub.io/changes: |
- kind: added
description: Initial chart for the Gateway, the Worker and the injector
25 changes: 25 additions & 0 deletions charts/outprint/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# outprint

Helm chart for [Outprint](https://github.com/taskmedia/outprint), PDF export for a self-hosted
[Outline](https://www.getoutline.com/). It runs the Gateway, the network-less Worker and, optionally,
the injector for Outline's Export menu. Images: `ghcr.io/taskmedia/outprint` and
`ghcr.io/taskmedia/outprint-injector`; the tag defaults to the chart's `appVersion`.

Documentation (concepts, the Worker security baseline, scaling, routing):
[Helm and Kubernetes](https://github.com/taskmedia/outprint/blob/main/docs/deploy/helm-kubernetes.md).

## Usage

```bash
helm repo add taskmedia https://helm.task.media
helm install outprint taskmedia/outprint \
--namespace outprint --create-namespace \
--set outline.url=http://outline.outline.svc:3000
```

Then route your edge proxy to the Service `outprint-injector` instead of Outline. Do not expose the
Gateway or the Worker. For PDF by link only, set `injector.enabled=false`.

## Values

See [values.yaml](values.yaml); every option is commented. `outline.url` is required.
3 changes: 3 additions & 0 deletions charts/outprint/ci/ct-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Minimal overrides so `ct lint` and `ct install` can render the chart.
outline:
url: http://outline.example.invalid:3000
17 changes: 17 additions & 0 deletions charts/outprint/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Outprint {{ .Chart.AppVersion }} is installed.

Gateway, Worker{{ if .Values.injector.enabled }} and injector{{ end }} run in namespace {{ .Release.Namespace }}.
{{- if .Values.injector.enabled }}

Route your edge proxy to the Service {{ include "outprint.fullname" . }}-injector
(port {{ .Values.injector.service.port }}) instead of to Outline. The injector forwards everything
else to Outline and /pdf/* to the Gateway. Do not expose the Gateway or the Worker.
{{- else }}

The injector is disabled. Route /pdf on the address of Outline to the Service
{{ include "outprint.fullname" . }}-gateway (port 8080), with the /pdf prefix removed.
{{- end }}
{{- if not .Values.worker.networkPolicy.enabled }}

WARNING: worker.networkPolicy.enabled is false. The Worker is not cut off from the network.
{{- end }}
59 changes: 59 additions & 0 deletions charts/outprint/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{{- define "outprint.fullname" -}}
{{- if contains .Chart.Name .Release.Name -}}{{ .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else -}}{{ printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}{{- end -}}
{{- end -}}

{{- define "outprint.labels" -}}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
app.kubernetes.io/name: outprint
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

{{/* call with (dict "root" . "component" "worker") */}}
{{- define "outprint.selector" -}}
app.kubernetes.io/name: outprint
app.kubernetes.io/instance: {{ .root.Release.Name }}
app.kubernetes.io/component: {{ .component }}
{{- end -}}

{{- define "outprint.image" -}}
{{ .repository }}:{{ .tag | default .appVersion }}
{{- end -}}

{{- define "outprint.tokenSecretName" -}}
{{- default (printf "%s-worker-token" (include "outprint.fullname" .)) .Values.workerToken.existingSecret -}}
{{- end -}}

{{- define "outprint.tokenEnv" -}}
{{- if .Values.workerToken.enabled }}
- name: OUTPRINT_WORKER_TOKEN
valueFrom:
secretKeyRef:
name: {{ include "outprint.tokenSecretName" . }}
key: token
{{- end }}
{{- end -}}

{{- define "outprint.extraEnv" -}}
{{- range $k, $v := . }}
- name: {{ $k }}
value: {{ $v | quote }}
{{- end }}
{{- end -}}

{{- define "outprint.containerSecurity" -}}
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
{{- end -}}

{{- define "outprint.podSecurity" -}}
runAsNonRoot: true
runAsUser: {{ .uid }}
runAsGroup: {{ .uid }}
seccompProfile:
type: RuntimeDefault
{{- end -}}
11 changes: 11 additions & 0 deletions charts/outprint/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{- $cfg := deepCopy .Values.serviceConfig -}}
{{- $_ := set $cfg "admission" (merge (dict "slots" (int .Values.worker.replicas)) (default (dict) $cfg.admission)) -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "outprint.fullname" . }}-service
labels:
{{- include "outprint.labels" . | nindent 4 }}
data:
service.yaml: |
{{- toYaml $cfg | nindent 4 }}
105 changes: 105 additions & 0 deletions charts/outprint/templates/gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{{- $name := printf "%s-gateway" (include "outprint.fullname" .) -}}
{{- $sel := include "outprint.selector" (dict "root" . "component" "gateway") -}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $name }}
labels:
{{- include "outprint.labels" . | nindent 4 }}
app.kubernetes.io/component: gateway
spec:
replicas: {{ .Values.gateway.replicas }}
selector:
matchLabels:
{{- $sel | nindent 6 }}
template:
metadata:
labels:
{{- include "outprint.labels" . | nindent 8 }}
app.kubernetes.io/component: gateway
annotations:
checksum/service-config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
{{- with .Values.gateway.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
automountServiceAccountToken: false
enableServiceLinks: false
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- include "outprint.podSecurity" (dict "uid" 10001) | nindent 8 }}
containers:
- name: gateway
image: {{ include "outprint.image" (dict "repository" .Values.image.repository "tag" .Values.image.tag "appVersion" .Chart.AppVersion) | quote }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
args: ["gateway"]
securityContext:
{{- include "outprint.containerSecurity" . | nindent 12 }}
env:
- name: OUTPRINT_LISTEN
value: ":8080"
- name: OUTPRINT_WORKER_URL
value: {{ printf "http://%s-worker:8081" (include "outprint.fullname" .) | quote }}
- name: OUTPRINT_SERVICE_CONFIG
value: /etc/outprint/service.yaml
- name: OUTLINE_URL
value: {{ required "outline.url is required: the base URL of your Outline" .Values.outline.url | quote }}
{{- with .Values.outline.publicUrl }}
- name: OUTLINE_PUBLIC_URL
value: {{ . | quote }}
{{- end }}
{{- include "outprint.tokenEnv" . | nindent 12 }}
{{- include "outprint.extraEnv" .Values.gateway.env | nindent 12 }}
ports:
- name: http
containerPort: 8080
startupProbe:
httpGet: { path: /healthz, port: http }
periodSeconds: 2
failureThreshold: 30
readinessProbe:
httpGet: { path: /healthz, port: http }
periodSeconds: 10
livenessProbe:
httpGet: { path: /healthz, port: http }
periodSeconds: 10
failureThreshold: 3
resources:
{{- toYaml .Values.gateway.resources | nindent 12 }}
volumeMounts:
- { name: service-config, mountPath: /etc/outprint, readOnly: true }
volumes:
- name: service-config
configMap:
name: {{ include "outprint.fullname" . }}-service
{{- with .Values.gateway.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.gateway.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.gateway.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $name }}
labels:
{{- include "outprint.labels" . | nindent 4 }}
app.kubernetes.io/component: gateway
spec:
type: ClusterIP
selector:
{{- $sel | nindent 4 }}
ports:
- name: http
port: 8080
targetPort: http
Loading
Loading