Compare commits

...

31 Commits

Author SHA1 Message Date
83278f6e9e refactor(zabbixserver): Has moved into its own repo
See https://quico.space/quico-containers/zabbixserver
2023-07-25 04:09:08 +02:00
0a4f669d85 refactor(zabbixserver): Simplify Git mail patch apply 2023-05-22 20:33:04 +02:00
ae13fa5c9c refactor(zabbixserver): Harmonize Git tag search 2023-05-22 20:32:39 +02:00
f42f7168d2 refactor(zabbixserver): Update invocation to include upstream repo 2023-05-22 20:31:39 +02:00
3fa4c2240c fix(paperless-ngx): Fix long-form depends_on 2023-05-18 02:07:37 +02:00
327fabbfc0 refactor(paperless-ngx): Remove unnecessary Docker Compose file 2023-05-18 02:07:03 +02:00
1abecfa8dd feat(paperless-ngx): Add missing var and a health check to upstream repo patch 2023-05-18 02:06:33 +02:00
060434f3c2 Fix(paperless-ngx): Add missing var and a health check to upstream repo patch 2023-05-18 01:53:57 +02:00
b036c8669a refactor(paperless-ngx): Typos 2023-05-17 01:51:35 +02:00
df7e212c58 feat(paperless-ngx): Add config 2023-05-17 01:40:25 +02:00
0bb8bed579 refactor(snipeit): Harmonize example context 2023-05-15 00:07:44 +02:00
fbfe4b4a3d feat(snipeit): Add config 2023-05-15 00:05:20 +02:00
290c5c302b feat(haproxy): Add config 2023-05-02 03:17:30 +02:00
a62dcd794c refactor(zabbixserver): Detach containers 2023-05-02 03:12:23 +02:00
d7e7e4823c refactor(zabbixserver): Directly link to PostgreSQL initialization script 2023-04-29 03:02:16 +02:00
ffa40e7a0e fix(zabbixserver): Typo 2023-04-29 02:59:17 +02:00
e68541ffd6 refactor(zabbixserver): Replace file names with links 2023-04-29 02:58:14 +02:00
8b6f97259d fix(zabbixserver): Typo 2023-04-29 02:56:11 +02:00
bd0f3ea08b feat(zabbixserver): Add Zabbix setup instructions 2023-04-29 02:52:38 +02:00
b6a556a2e5 Merge pull request 'Fix MySQL container layout' (#7) from 6-vaultenv-with-mysql into master
Reviewed-on: #7
2023-01-13 01:50:45 +00:00
cf9cf07390 Fix MySQL container layout 2023-01-13 02:49:53 +01:00
161b4a92bc Merge pull request '2-add-mysql-instance-config' (#5) from 2-add-mysql-instance-config into master
Reviewed-on: #5
2023-01-12 15:03:10 +00:00
324b97ebb8 Add .gitignore files for production docker compose env files (#2) 2023-01-12 16:02:29 +01:00
c2ae0e92c3 Add MySQL config (#2) 2023-01-12 15:58:11 +01:00
ed7bd9c5f0 Merge pull request 'Add mediathekviewweb config (#1)' (#3) from 1-add-mediathekviewweb into master
Reviewed-on: #3
2023-01-12 14:20:01 +00:00
674ec0342c Add mediathekviewweb config (#1) 2023-01-12 15:17:15 +01:00
2e6703aa02 fix(mailcow): Following mailcow's example we'll use TZ as our timezone var env var instead of TIMEZONE 2022-07-17 02:18:24 +02:00
ff4b51f9b8 fix(mailcow): Move common-settings.yml into correct dir 2022-07-16 02:40:57 +02:00
0e054ce455 docs(mailcow): Add fully functional mailcow.conf 2022-07-14 03:43:55 +02:00
28b7427c7e docs(mailcow): Document env var changes we're making 2022-07-14 03:43:33 +02:00
58d2c7b0ac feat(mailcow): Add docker compose overrides 2022-07-14 03:42:48 +02:00
42 changed files with 1655 additions and 0 deletions

32
haproxy/README.md Normal file
View File

@@ -0,0 +1,32 @@
# Docker Compose
## Environment
Prepare an environment file following the example in [env/fqdn_context.env.example](env/fqdn_context.env.example):
```
CONTEXT=foodstuffs_hongkong
DOCKER_SUBNET=172.24.23.0/24
HAPROXY_VERSION=latest
```
Var `${DOCKER_SUBNET}` is optional and defaults to `${DOCKER_SUBNET-172.24.23.0/24}`. Treat `CONTEXT` as a team name, purpose or scope. If the same Docker application can run multiple times and serve different tenants then `CONTEXT` is what distinguishes one instance from the other. Here `foodstuffs_hongkong` indicates for example a Hong Kong-based foodstuffs team of some sort.
## Vars
Define Docker Compose variables, use the `COMPOSE_ENV_FILE` defined above in [Environment](#environment):
```
export COMPOSE_DIR='/opt/containers' # Or wherever this repo is checked out
export COMPOSE_FILE="${COMPOSE_DIR}"'/docker-compose.yml'
export COMPOSE_ENV_FILE=<add accordingly>
```
Run like so:
```
docker compose --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV_FILE}" up --detach
```
Log entries will just be something along the lines of:
```
haproxy-CONTEXT | [NOTICE] (1) : New worker (8) forked
haproxy-CONTEXT | [NOTICE] (1) : Loading success.
```

View File

@@ -0,0 +1,14 @@
# For the remainder of this Dockerfile EXAMPLE_ARG_FOR_DOCKERFILE will be
# available with a value of 'must_be_available_in_dockerfile', check out the env
# file at 'env/fully.qualified.domain.name.example' for reference.
# ARG EXAMPLE_ARG_FOR_DOCKERFILE
# Another env var, this one's needed in the example build step below:
# ARG HAPROXY_VERSION
# Example
# FROM "haproxy:${HAPROXY_VERSION}"
# RUN apt-get update && \
# apt-get -y install \
# somepackage-6.q16-6-extra && \
# rm -rf /var/lib/apt/lists/*

View File

View File

@@ -0,0 +1,11 @@
services:
common-settings:
environment:
TZ: "${TIMEZONE:-Etc/UTC}"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
compress: "true"
restart: "${RESTARTPOLICY:-unless-stopped}"

View File

@@ -0,0 +1,9 @@
services:
haproxy-build:
image: "haproxy:${HAPROXY_VERSION}"
profiles: ["build"]
build:
context: "build-context/haproxy"
dockerfile: Dockerfile
args:
HAPROXY_VERSION: "${HAPROXY_VERSION}"

View File

@@ -0,0 +1,25 @@
services:
haproxy:
image: "haproxy:${HAPROXY_VERSION}"
container_name: "haproxy-${CONTEXT}"
networks:
haproxy-default:
extends:
file: common-settings.yml
service: common-settings
ports:
- 80:80
- 443:443
volumes:
- /opt/docker-data/haproxy-${CONTEXT}/config/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
networks:
haproxy-default:
name: haproxy-${CONTEXT}
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: ${DOCKER_SUBNET-172.24.23.0/24}

6
haproxy/env/fqdn_context.env.example vendored Normal file
View File

@@ -0,0 +1,6 @@
# This file is maintained by remco and populated with data from HashiCorp
# Vault. Changes not done in Vault will be reverted when file gets rendered.
CONTEXT=
DOCKER_SUBNET=
HAPROXY_VERSION=

45
mailcow/README.md Normal file
View File

@@ -0,0 +1,45 @@
# Overrides for mailcow-dockerized
Provides files that are meant to be copied into your location of the [github.com/mailcow/mailcow-dockerized](https://github.com/mailcow/mailcow-dockerized) repo thereby customizing its behavior.
yq 'del( .services.[].environment.[] | select(. == "TZ=*") ) | del(.. | select( (tag == "!!map" or tag =="!!seq") and length == 0)) | del( .services.[].restart )' /opt/containers/mailcow-dockerized/docker-compose.yml | yq --indent 4 ea '. as $item ireduce ({}; . * $item )' - /opt/containers/mailcow-dockerized/docker-compose.override.yml > /opt/containers/mailcow-dockerized/docker-compose.final.yml
* Env variables
```
yq 'del( .services.[].environment.[] | select(. == "TZ=*") ) | del(.. | select( (tag == "!!map" or tag =="!!seq") and length == 0))' ...
```
From all `.services.[].environment.[]` lists remove items that match the expression `TZ=*`. Realistically this removes the `TZ` environment variable declaration and in some cases leaves the `environment` list empty. If the list now truly is empty delete it.
Given a file:
```
services:
unbound-mailcow:
image: mailcow/unbound:1.16
environment:
- TZ=${TZ}
volumes:
- ./data/hooks/unbound:/hooks:Z
```
Step one does:
```
services:
unbound-mailcow:
image: mailcow/unbound:1.16
---> environment:
volumes:
- ./data/hooks/unbound:/hooks:Z
```
We detect that `environment` is now empty and delete it:
```
services:
unbound-mailcow:
image: mailcow/unbound:1.16
---> volumes:
- ./data/hooks/unbound:/hooks:Z
```
* Restart policy
```
del( .services.[].restart ) ...
```
From all services delete restart policy declaration. We're defaulting to `unless-stopped` via the `extends:` directive.

View File

@@ -0,0 +1,11 @@
services:
common-settings:
environment:
TZ: "${TZ:-Etc/UTC}"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
compress: "true"
restart: "${RESTARTPOLICY:-unless-stopped}"

View File

@@ -0,0 +1,77 @@
services:
unbound-mailcow:
extends:
file: common-settings.yml
service: common-settings
mysql-mailcow:
extends:
file: common-settings.yml
service: common-settings
redis-mailcow:
extends:
file: common-settings.yml
service: common-settings
clamd-mailcow:
extends:
file: common-settings.yml
service: common-settings
rspamd-mailcow:
extends:
file: common-settings.yml
service: common-settings
php-fpm-mailcow:
extends:
file: common-settings.yml
service: common-settings
sogo-mailcow:
extends:
file: common-settings.yml
service: common-settings
dovecot-mailcow:
extends:
file: common-settings.yml
service: common-settings
postfix-mailcow:
extends:
file: common-settings.yml
service: common-settings
memcached-mailcow:
extends:
file: common-settings.yml
service: common-settings
nginx-mailcow:
extends:
file: common-settings.yml
service: common-settings
acme-mailcow:
extends:
file: common-settings.yml
service: common-settings
netfilter-mailcow:
extends:
file: common-settings.yml
service: common-settings
watchdog-mailcow:
extends:
file: common-settings.yml
service: common-settings
dockerapi-mailcow:
extends:
file: common-settings.yml
service: common-settings
solr-mailcow:
extends:
file: common-settings.yml
service: common-settings
olefy-mailcow:
extends:
file: common-settings.yml
service: common-settings
ofelia-mailcow:
extends:
file: common-settings.yml
service: common-settings
ipv6nat-mailcow:
extends:
file: common-settings.yml
service: common-settings

View File

@@ -0,0 +1,146 @@
# Feel free to leave defaults. They apply while these vars are commented out
# ---
# RESTARTPOLICY=unless-stopped
# TZ=Etc/UTC
TZ=<user_defined_value>
# Unbound, redis, clamd, rspamd, php-fpm, SOGo, dovecot, Postfix, Nginx, acme, netfilter, watchdog, dockerapi
IPV4_NETWORK=<user_defined_value>
# MySQL
SQL_PORT=127.0.0.1:3306
# MySQL, watchdog, dockerapi
DBROOT=<user_defined_value>
# MySQL, php-fpm, SOGo, dovecot, Postfix, acme, watchdog
DBNAME=<user_defined_value>
DBUSER=<user_defined_value>
DBPASS=<user_defined_value>
# Redis
REDIS_PORT=127.0.0.1:6379
# rspamd, php-fpm, netfilter, watchdog
# IPV6_NETWORK=fd4d:6169:6c63:6f77::/64
# rspamd, php-fpm, SOGo, dovecot, Postfix, acme, netfilter, watchdog
# REDIS_SLAVEOF_IP=
# REDIS_SLAVEOF_PORT=
# php-fpm
# API_KEY=invalid
# API_KEY_READ_ONLY=invalid
# API_ALLOW_FROM=invalid
# SKIP_SOGO=n
# DEV_MODE=n
# WEBAUTHN_ONLY_TRUSTED_VENDORS=n
# php-fpm, clamd, watchdog
# SKIP_CLAMD=n
# php-fpm, dovecot
# IMAP_PORT=143
# IMAPS_PORT=993
# POP_PORT=110
# POPS_PORT=995
# SIEVE_PORT=4190
SKIP_SOLR=n
# php-fpm, dovecot, acme, watchdog
# COMPOSE_PROJECT_NAME=mailcow-dockerized
# php-fpm, Postfix
# SUBMISSION_PORT=587
# SMTPS_PORT=465
# SMTP_PORT=25
# php-fpm, SOGo, dovecot
# MAILCOW_PASS_SCHEME=BLF-CRYPT
# MASTER=y
# php-fpm, SOGo, dovecot, Nginx
# ALLOW_ADMIN_EMAIL_LOGIN=n
# php-fpm, SOGo, dovecot, Postfix, Nginx, acme, watchdog
MAILCOW_HOSTNAME=<user_defined_value>
# php-fpm, SOGo, dovecot, Postfix, acme, watchdog
# LOG_LINES=9999
# SOGo
# SOGO_EXPIRE_SESSION=480
# SOGo, Nginx, watchdog
# SKIP_SOGO=n
# SOGo, dovecot
# ACL_ANYONE=disallow
# dovecot
DOVECOT_MASTER_USER=<user_defined_value>
DOVECOT_MASTER_PASS=<user_defined_value>
# MAILDIR_GC_TIME=7200
MAILDIR_SUB=Maildir
DOVEADM_PORT=127.0.0.1:9091
# Nginx
# HTTP_PORT=80
# ADDITIONAL_SERVER_NAMES=
# HTTPS_BIND=
# HTTP_BIND=
# Nginx, watchdog
# HTTPS_PORT=443
# acme
# ACME_CONTACT=
# ADDITIONAL_SAN
# DIRECTORY_URL=
# ENABLE_SSL_SNI=n
# SKIP_IP_CHECK=n
# SKIP_HTTP_VERIFICATION=n
# ONLY_MAILCOW_HOSTNAME=n
# LE_STAGING=n
# acme, watchdog
SKIP_LETS_ENCRYPT=y
# acme, netfilter
# SNAT_TO_SOURCE=n
# SNAT6_TO_SOURCE=n
# watchdog
# USE_WATCHDOG=n
# WATCHDOG_NOTIFY_EMAIL=
# WATCHDOG_NOTIFY_BAN=y
# WATCHDOG_SUBJECT=Watchdog ALERT
# WATCHDOG_EXTERNAL_CHECKS=n
# WATCHDOG_MYSQL_REPLICATION_CHECKS=n
# WATCHDOG_VERBOSE=n
# IP_BY_DOCKER_API=0
# CHECK_UNBOUND=1
# EXTERNAL_CHECKS_THRESHOLD=1
# NGINX_THRESHOLD=5
# UNBOUND_THRESHOLD=5
# REDIS_THRESHOLD=5
# MYSQL_THRESHOLD=5
# MYSQL_REPLICATION_THRESHOLD=1
# SOGO_THRESHOLD=3
# POSTFIX_THRESHOLD=8
# CLAMD_THRESHOLD=15
# DOVECOT_THRESHOLD=12
# DOVECOT_REPL_THRESHOLD=20
# PHPFPM_THRESHOLD=5
# RATELIMIT_THRESHOLD=1
# FAIL2BAN_THRESHOLD=1
# ACME_THRESHOLD=1
# RSPAMD_THRESHOLD=5
# OLEFY_THRESHOLD=5
# MAILQ_THRESHOLD=20
# MAILQ_CRIT=30
# solr
SOLR_PORT=127.0.0.1:8983
# SOLR_HEAP=1024
SKIP_SOLR=n

View File

@@ -0,0 +1,63 @@
version: "3.7"
services:
application:
container_name: mediathekviewweb
image: mediathekview/mediathekviewweb:latest
restart: always
depends_on:
- elasticsearch
- redis
environment:
DATA_DIRECTORY: /data
WEBSERVER_PORT: 8000
INDEX: 'true'
WORKER_COUNT:
WORKER_ARGS:
REDIS_HOST: redis
REDIS_PORT:
REDIS_PASSWORD:
REDIS_DB:
ELASTICSEARCH_HOST: elasticsearch
ELASTICSEARCH_PORT: 9200
MATOMO_ENABLED:
MATOMO_URL:
MATOMO_SITE_URL:
MATOMO_AUTH_TOKEN:
MATOMO_SITE_ID:
CONTACT_NAME:
CONTACT_STREET:
CONTACT_POSTCODE:
CONTACT_CITY:
CONTACT_MAIL:
volumes:
- "/opt/docker-data/mediathekviewweb/mediathekviewweb/data:/data"
ports:
- "8000:8000"
networks:
- elasticsearch
- redis
elasticsearch:
container_name: elasticsearch
image: "docker.elastic.co/elasticsearch/elasticsearch:6.8.14"
restart: always
environment:
- ES_JAVA_OPTS=-Xms2G -Xmx2G
volumes:
- "/opt/docker-data/mediathekviewweb/elasticsearch/data:/usr/share/elasticsearch/data"
networks:
- elasticsearch
redis:
container_name: redis
image: "redis:6-alpine"
restart: always
volumes:
- "/opt/docker-data/mediathekviewweb/redis/data:/data"
networks:
- redis
networks:
elasticsearch:
redis:

View File

@@ -0,0 +1,14 @@
# For the remainder of this Dockerfile EXAMPLE_ARG_FOR_DOCKERFILE will be
# available with a value of 'must_be_available_in_dockerfile', check out the env
# file at 'env/fully.qualified.domain.name.example' for reference.
# ARG EXAMPLE_ARG_FOR_DOCKERFILE
# Another env var, this one's needed in the example build step below:
# ARG MYSQL_VERSION
# Example
# FROM "mysql:${MYSQL_VERSION}"
# RUN apt-get update && \
# apt-get -y install \
# somepackage-6.q16-6-extra && \
# rm -rf /var/lib/apt/lists/*

View File

View File

11
mysql/common-settings.yml Normal file
View File

@@ -0,0 +1,11 @@
services:
common-settings:
environment:
TZ: "${TIMEZONE:-Etc/UTC}"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
compress: "true"
restart: "${RESTARTPOLICY:-unless-stopped}"

View File

@@ -0,0 +1,9 @@
services:
mysql-build:
image: "mysql:${MYSQL_VERSION}"
profiles: ["build"]
build:
context: "build-context"
dockerfile: Dockerfile
args:
MYSQL_VERSION: "${MYSQL_VERSION}"

27
mysql/docker-compose.yml Normal file
View File

@@ -0,0 +1,27 @@
services:
mysql:
image: "mysql:${MYSQL_VERSION}"
container_name: "mysql-${CONTEXT}"
networks:
mysql-default:
extends:
file: common-settings.yml
service: common-settings
ports:
- 3306:3306
volumes:
- /opt/docker-data/mysql-${CONTEXT}/data:/var/lib/mysql
- /opt/docker-data/mysql-${CONTEXT}/config/my.cnf:/etc/my.cnf
environment:
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
networks:
mysql-default:
name: mysql-${CONTEXT}
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: ${SUBNET}

1
mysql/env/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.env

View File

@@ -0,0 +1,33 @@
CONTEXT=loft_ent
# Set something sensible here and uncomment
# ---
# MYSQL_VERSION=x.y.z
# A ${LOCATION} var is usually not needed. It may be helpful when a ${CONTEXT}
# extends over more than one location e.g. to bind-mount location-specific
# config files or certificates into a container.
# ---
# LOCATION=
# Feel free to leave defaults. They apply while these vars are commented out
# ---
# RESTARTPOLICY=unless-stopped
# TIMEZONE=Etc/UTC
# See 'docker-compose.override.yml' for how to make a variable available in
# a Dockerfile
# ---
# EXAMPLE_ARG_FROM_ENV_FILE=must_be_available_in_dockerfile
SUBNET=10.10.10.10/24

157
paperless_ngx/README.md Normal file
View File

@@ -0,0 +1,157 @@
# Spin it up
## Defaults
We use the [upstream github.com/paperless-ngx/paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) repo assuming you have this checked out at `/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev`. The `COMPOSE_CTX` (`CTX` as in context) is a unique identifier to differentiate one instance from another. This can be for example `hr_juba` to indicate that this particular instance runs on behalf of the Human Resources department based in Juba in South Sudan in Africa.
Examples assume we're using the `docker-compose.postgres-tika.yml` file which spins up PostgreSQL as its database and also provides [Apache Tika](https://tika.apache.org/) and [Gotenberg PDF API](https://gotenberg.dev/docs/about).
## Environment variables
* Set env vars
```
export UPSTREAM_REPO_DIR='/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev'
export UPSTREAM_COMPOSE_DIR="${UPSTREAM_REPO_DIR%/}"'/docker/compose'
export UPSTREAM_COMPOSE_FILE="${UPSTREAM_COMPOSE_DIR%/}"'/docker-compose.postgres-tika.yml'
export COMPOSE_CTX='hr_juba'
export COMPOSE_PROJECT_NAME='paperless_ngx-'"${COMPOSE_CTX}"
export COMPOSE_PROJECT_DIR='/opt/containers/paperless_ngx'
export COMPOSE_OVERRIDE_FILE="${COMPOSE_PROJECT_DIR%/}"'/docker-compose.override.yml'
export COMPOSE_ENV_FILE=<set accordingly>
```
Also check out the example env file at [env/fully.qualified.domain.name_ctx.env.example](env/fully.qualified.domain.name_ctx.env.example).
* Build
```
docker compose --project-directory "${COMPOSE_PROJECT_DIR}" --file "${UPSTREAM_COMPOSE_FILE}" --file "${COMPOSE_OVERRIDE_FILE}" --env-file "${COMPOSE_ENV_FILE}" --profile 'build' build
```
We're building a custom PostgreSQL image with `ping` installed. We're using that to do a health check on our virtual IP (VIP) address. We've added a dependency to the main `paperless-ngx` web server container so that it only starts after the PostgreSQL container with its health check confirms that the VIP is reachable.
* Start containers
```
docker compose --project-name "${COMPOSE_PROJECT_NAME}" --file "${UPSTREAM_COMPOSE_FILE}" --env-file "${COMPOSE_ENV_FILE}" up --detach
```
# Prep work
## Data sets
To get started from scratch create your ZFS datasets and set permissions as needed for `paperless-ngx`.
* Parent dateset
```
zfs create -o mountpoint=/opt/docker-data 'zpool/docker-data'
```
* Container-specific datasets
```
zfs create -p 'zpool/docker-data/paperless_ngx-'"${COMPOSE_CTX}"'/broker/data'
zfs create -p 'zpool/docker-data/paperless_ngx-'"${COMPOSE_CTX}"'/db/data'
zfs create -p 'zpool/docker-data/paperless_ngx-'"${COMPOSE_CTX}"'/webserver/data'
zfs create -p 'zpool/docker-data/paperless_ngx-'"${COMPOSE_CTX}"'/webserver/media'
zfs create -p 'zpool/docker-data/paperless_ngx-'"${COMPOSE_CTX}"'/webserver/export'
zfs create -p 'zpool/docker-data/paperless_ngx-'"${COMPOSE_CTX}"'/webserver/consume'
```
* Change ownership for all webserver-related dirs
```
chown -R 1000:1000 'zpool/docker-data/paperless_ngx-'"${COMPOSE_CTX}"'/webserver'
```
## Apply patch
Identify yourself to the local `paperless-ngx` repo. Obviously substitute your own name. An e-mail address is optional here. You don't want to contribute upstream, you just want to locally apply a patch file.
```
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' config user.name "hygienic-books"
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' config user.email ""
```
Apply `paperless_ngx.patch` to Docker Compose file. We use the `docker-compose.postgres-tika.yml` Compose file. Assuming this repo lives at `/opt/containers/paperless_ngx`:
```
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' am '/opt/containers/paperless_ngx/paperless_ngx.patch'
# Output will be:
Applying: refactor(compose): 4 spaces indentation
Applying: refactor(compose): Harmonize restart and logging settigs
Applying: refactor(compose): Replace static exposed port with environment variable
Applying: refactor(compose): Harmonize container names
Applying: refactor(compose): Replace named volumes with bind mounts
...
```
And then back up to [Environment variables](#environment-variables).
# Upgrade an existing repo
Check [Prep work](#prep-work) for first time steps. On consecutive upgrades proceed as follows.
## Revert unpushed local changes
Return repo state to exactly the upstream repo's original branch state throwing away the commits you added.
```
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' reset --hard origin
```
Switch to `main` branch, get newest commits from upstream
```
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' checkout dev
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' pull
```
Pick and checkout new tag
```
while IFS= read -r; do commitDate=$(grep -Pio '^.+?(?=[[:space:]])' <<< "${REPLY}"); commitDate=$(date --date='@'"${commitDate}" +%F-%H%M%S); tagRef="$(cut -d $'\t' -f2 <<< "${REPLY}")"; tagName="$(grep -Pio '(?<=refs/tags/)[^\r\n\f]+' <<<"${tagRef}")"; commitHash="$(git rev-list -n 1 "${tagRef}")"; echo "${commitDate} ${commitHash} ${tagName}"; done < <(git for-each-ref --sort=v:refname --format='%(*creatordate:raw)%00%(creatordate:raw)%00%(refname)' refs/tags | awk -F"\0" 'BEGIN {ORS=""} $1 == "" {print $2} $1 != "" {print $1} {print "\t"$3"\n"}')
# Output goes like:
...
2023-04-27-161244 864e242ed9c454585e236b0c20ccae0927b4c9b2 v1.14.1
2023-04-27-195703 356c26ce848ca5301156a33e9ea75a10255f404b v1.14.2
2023-05-03-155437 4353646b3ac5805f7c582599b784a2fc246b3700 v1.14.3
2023-05-04-164855 ec4814a76e88efa81387316d8c42afc7e220fcbe v1.14.4
2023-05-15-170859 3e129763c799a7141e5ecd04862c0160caeeef5b v1.14.5
...
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' checkout 'tags/vx.y.z'
```
Lastly [apply patch](#apply-patch). If patch does not apply cleanly read on in the next section [Create new patch](#create-new-patch) to find out how to fix your patch.
# Create new patch
## Add your changes as commits
With `paperless-ngx` repo checked out at `/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev` get the it into a state with which you're happy then
```
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' format-patch 31b7e26f6c4d7111f4f4957996efb9f7a5d06cb9^..64beae08ffe8f9a65208e2567919fd75564b95c6 --stdout > '/opt/containers/paperless_ngx/paperless_ngx.patch'
```
Where the first commit hash is our first commit and the other commit hash is our last commit. Note the caret (`^`) right after the first commit hash.
## Investigation
You may have to try and find out how a known good base commit differs from a newer one in case the newer one does no longer cleanly accept the patch.
Get commit hashes from both affected tags, e.g.
```
while IFS= read -r; do commitDate=$(grep -Pio '^.+?(?=[[:space:]])' <<< "${REPLY}"); commitDate=$(date --date='@'"${commitDate}" +%F-%H%M%S); tagRef="$(cut -d $'\t' -f2 <<< "${REPLY}")"; tagName="$(grep -Pio '(?<=refs/tags/)[^\r\n\f]+' <<<"${tagRef}")"; commitHash="$(git rev-list -n 1 "${tagRef}")"; echo "${commitDate} ${commitHash} ${tagName}"; done < <(git for-each-ref --sort=v:refname --format='%(*creatordate:raw)%00%(creatordate:raw)%00%(refname)' refs/tags | awk -F"\0" 'BEGIN {ORS=""} $1 == "" {print $2} $1 != "" {print $1} {print "\t"$3"\n"}')
# Output goes like:
...
2023-04-27-161244 864e242ed9c454585e236b0c20ccae0927b4c9b2 v1.14.1
2023-04-27-195703 356c26ce848ca5301156a33e9ea75a10255f404b v1.14.2
2023-05-03-155437 4353646b3ac5805f7c582599b784a2fc246b3700 v1.14.3
2023-05-04-164855 ec4814a76e88efa81387316d8c42afc7e220fcbe v1.14.4
2023-05-15-170859 3e129763c799a7141e5ecd04862c0160caeeef5b v1.14.5
...
```
Diff them
```
git -C '/opt/git/github.com/paperless-ngx/paperless-ngx/branches/dev' diff ec4814a76e88efa81387316d8c42afc7e220fcbe 3e129763c799a7141e5ecd04862c0160caeeef5b 'docker/compose/docker-compose.postgres-tika.yml'
```
Output will be empty in case no difference exists in `docker/compose/docker-compose.postgres-tika.yml` between both commit hashes.
Commit your updated patch file into _this_ repo. With a new working patch in hand head back up to [Upgrade an existing repo](#upgrade-an-existing-repo).

View File

@@ -0,0 +1,6 @@
ARG PGSQL_VERSION
FROM "docker.io/library/postgres:${PGSQL_VERSION}"
RUN apt-get update && \
apt-get -y install iputils-ping && \
rm -rf /var/lib/apt/lists/*

View File

@@ -0,0 +1,11 @@
services:
common-settings:
environment:
TZ: "${TIMEZONE:-Etc/UTC}"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
compress: "true"
restart: "${RESTARTPOLICY:-unless-stopped}"

View File

@@ -0,0 +1,9 @@
services:
paperless_ngx-build:
image: "docker.io/library/postgres:${PGSQL_VERSION}"
profiles: ["build"]
build:
context: "build-context"
dockerfile: Dockerfile
args:
PGSQL_VERSION: "${PGSQL_VERSION}"

3
paperless_ngx/env/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*
!.gitignore
!fully.qualified.domain.name_ctx.env.example

View File

@@ -0,0 +1,21 @@
# This file is maintained by remco and populated with data from HashiCorp
# Vault. Changes not done in Vault will be reverted when file gets rendered.
CONTEXT=hr_juba
PAPERLESS_OCR_CLEAN=clean-final
PAPERLESS_OCR_LANGUAGE=eng
PAPERLESS_OCR_LANGUAGES=bos
PAPERLESS_SECRET_KEY=face-roll-your-keyboard-here
PAPERLESS_TIME_ZONE=Africa/Juba
PAPERLESS_URL=https://fully.qualified.domain.name
PGSQL_VERSION=13
SUBNET=172.22.17.0/24
TIMEZONE=Africa/Juba
WEBSERVER_PORT=8080
WEBSERVER_VIP=192.168.29.103
# Other available defaults
# USERMAP_UID=1000
# USERMAP_GID=1000
# PAPERLESS_FORCE_SCRIPT_NAME=/PATHPREFIX
# PAPERLESS_STATIC_URL=/PATHPREFIX/static/ # trailing slash required

View File

@@ -0,0 +1,641 @@
From 42c196c2c0dcbed0101d653e0ed67a3dfc3f1808 Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 22:17:21 +0200
Subject: [PATCH 01/12] refactor(compose): 4 spaces indentation
---
.../compose/docker-compose.postgres-tika.yml | 114 +++++++++---------
1 file changed, 57 insertions(+), 57 deletions(-)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index a451b00d..7423be72 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -32,67 +32,67 @@
version: "3.4"
services:
- broker:
- image: docker.io/library/redis:7
- restart: unless-stopped
- volumes:
- - redisdata:/data
+ broker:
+ image: docker.io/library/redis:7
+ restart: unless-stopped
+ volumes:
+ - redisdata:/data
- db:
- image: docker.io/library/postgres:13
- restart: unless-stopped
- volumes:
- - pgdata:/var/lib/postgresql/data
- environment:
- POSTGRES_DB: paperless
- POSTGRES_USER: paperless
- POSTGRES_PASSWORD: paperless
+ db:
+ image: docker.io/library/postgres:13
+ restart: unless-stopped
+ volumes:
+ - pgdata:/var/lib/postgresql/data
+ environment:
+ POSTGRES_DB: paperless
+ POSTGRES_USER: paperless
+ POSTGRES_PASSWORD: paperless
- webserver:
- image: ghcr.io/paperless-ngx/paperless-ngx:latest
- restart: unless-stopped
- depends_on:
- - db
- - broker
- - gotenberg
- - tika
- ports:
- - "8000:8000"
- healthcheck:
- test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
- interval: 30s
- timeout: 10s
- retries: 5
- volumes:
- - data:/usr/src/paperless/data
- - media:/usr/src/paperless/media
- - ./export:/usr/src/paperless/export
- - ./consume:/usr/src/paperless/consume
- env_file: docker-compose.env
- environment:
- PAPERLESS_REDIS: redis://broker:6379
- PAPERLESS_DBHOST: db
- PAPERLESS_TIKA_ENABLED: 1
- PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
- PAPERLESS_TIKA_ENDPOINT: http://tika:9998
+ webserver:
+ image: ghcr.io/paperless-ngx/paperless-ngx:latest
+ restart: unless-stopped
+ depends_on:
+ - db
+ - broker
+ - gotenberg
+ - tika
+ ports:
+ - "8000:8000"
+ healthcheck:
+ test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ volumes:
+ - data:/usr/src/paperless/data
+ - media:/usr/src/paperless/media
+ - ./export:/usr/src/paperless/export
+ - ./consume:/usr/src/paperless/consume
+ env_file: docker-compose.env
+ environment:
+ PAPERLESS_REDIS: redis://broker:6379
+ PAPERLESS_DBHOST: db
+ PAPERLESS_TIKA_ENABLED: 1
+ PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
+ PAPERLESS_TIKA_ENDPOINT: http://tika:9998
- gotenberg:
- image: docker.io/gotenberg/gotenberg:7.8
- restart: unless-stopped
+ gotenberg:
+ image: docker.io/gotenberg/gotenberg:7.8
+ restart: unless-stopped
- # The gotenberg chromium route is used to convert .eml files. We do not
- # want to allow external content like tracking pixels or even javascript.
- command:
- - "gotenberg"
- - "--chromium-disable-javascript=true"
- - "--chromium-allow-list=file:///tmp/.*"
+ # The gotenberg chromium route is used to convert .eml files. We do not
+ # want to allow external content like tracking pixels or even javascript.
+ command:
+ - "gotenberg"
+ - "--chromium-disable-javascript=true"
+ - "--chromium-allow-list=file:///tmp/.*"
- tika:
- image: ghcr.io/paperless-ngx/tika:latest
- restart: unless-stopped
+ tika:
+ image: ghcr.io/paperless-ngx/tika:latest
+ restart: unless-stopped
volumes:
- data:
- media:
- pgdata:
- redisdata:
+ data:
+ media:
+ pgdata:
+ redisdata:
--
2.39.1
From 6bf9b93ebe48036d67d94a49162c1f6c17eb80de Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 22:22:06 +0200
Subject: [PATCH 02/12] refactor(compose): Harmonize restart and logging
settigs
---
docker/compose/common-settings.yml | 11 ++++++++++
.../compose/docker-compose.postgres-tika.yml | 20 ++++++++++++++-----
2 files changed, 26 insertions(+), 5 deletions(-)
create mode 100644 docker/compose/common-settings.yml
diff --git a/docker/compose/common-settings.yml b/docker/compose/common-settings.yml
new file mode 100644
index 00000000..9fd26d75
--- /dev/null
+++ b/docker/compose/common-settings.yml
@@ -0,0 +1,11 @@
+services:
+ common-settings:
+ environment:
+ TZ: "${TIMEZONE:-Etc/UTC}"
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "10m"
+ max-file: "10"
+ compress: "true"
+ restart: "${RESTARTPOLICY:-unless-stopped}"
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index 7423be72..d19c22d7 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -34,13 +34,17 @@ version: "3.4"
services:
broker:
image: docker.io/library/redis:7
- restart: unless-stopped
+ extends:
+ file: common-settings.yml
+ service: common-settings
volumes:
- redisdata:/data
db:
image: docker.io/library/postgres:13
- restart: unless-stopped
+ extends:
+ file: common-settings.yml
+ service: common-settings
volumes:
- pgdata:/var/lib/postgresql/data
environment:
@@ -50,7 +54,9 @@ services:
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
- restart: unless-stopped
+ extends:
+ file: common-settings.yml
+ service: common-settings
depends_on:
- db
- broker
@@ -78,7 +84,9 @@ services:
gotenberg:
image: docker.io/gotenberg/gotenberg:7.8
- restart: unless-stopped
+ extends:
+ file: common-settings.yml
+ service: common-settings
# The gotenberg chromium route is used to convert .eml files. We do not
# want to allow external content like tracking pixels or even javascript.
@@ -89,7 +97,9 @@ services:
tika:
image: ghcr.io/paperless-ngx/tika:latest
- restart: unless-stopped
+ extends:
+ file: common-settings.yml
+ service: common-settings
volumes:
data:
--
2.39.1
From 9b7dd19f5c6f410594f35dd233d1d32c9d118dbf Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 22:28:02 +0200
Subject: [PATCH 03/12] refactor(compose): Replace static exposed port with
environment variable
---
docker/compose/docker-compose.postgres-tika.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index d19c22d7..554d9735 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -63,7 +63,7 @@ services:
- gotenberg
- tika
ports:
- - "8000:8000"
+ - "${WEBSERVER_PORT}":8000
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s
--
2.39.1
From aee7de3b1adfb30e7f0f2737d567cfc8190d8302 Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 22:30:47 +0200
Subject: [PATCH 04/12] refactor(compose): Harmonize container names
---
docker/compose/docker-compose.postgres-tika.yml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index 554d9735..10316fc2 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -34,6 +34,7 @@ version: "3.4"
services:
broker:
image: docker.io/library/redis:7
+ container_name: "paperless_ngx-broker-${CONTEXT}"
extends:
file: common-settings.yml
service: common-settings
@@ -42,6 +43,7 @@ services:
db:
image: docker.io/library/postgres:13
+ container_name: "paperless_ngx-db-${CONTEXT}"
extends:
file: common-settings.yml
service: common-settings
@@ -54,6 +56,7 @@ services:
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
+ container_name: "paperless_ngx-webserver-${CONTEXT}"
extends:
file: common-settings.yml
service: common-settings
@@ -84,6 +87,7 @@ services:
gotenberg:
image: docker.io/gotenberg/gotenberg:7.8
+ container_name: "paperless_ngx-gotenberg-${CONTEXT}"
extends:
file: common-settings.yml
service: common-settings
@@ -97,6 +101,7 @@ services:
tika:
image: ghcr.io/paperless-ngx/tika:latest
+ container_name: "paperless_ngx-tika-${CONTEXT}"
extends:
file: common-settings.yml
service: common-settings
--
2.39.1
From e600e84d5c6e6c8938498f8cfa8bef32c1aea180 Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 22:36:29 +0200
Subject: [PATCH 05/12] refactor(compose): Replace named volumes with bind
mounts
---
.../compose/docker-compose.postgres-tika.yml | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index 10316fc2..eacb76c8 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -39,7 +39,7 @@ services:
file: common-settings.yml
service: common-settings
volumes:
- - redisdata:/data
+ - /opt/docker-data/paperless_ngx-${CONTEXT}/broker/data:/data
db:
image: docker.io/library/postgres:13
@@ -48,7 +48,7 @@ services:
file: common-settings.yml
service: common-settings
volumes:
- - pgdata:/var/lib/postgresql/data
+ - /opt/docker-data/paperless_ngx-${CONTEXT}/db/data:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
@@ -73,10 +73,10 @@ services:
timeout: 10s
retries: 5
volumes:
- - data:/usr/src/paperless/data
- - media:/usr/src/paperless/media
- - ./export:/usr/src/paperless/export
- - ./consume:/usr/src/paperless/consume
+ - /opt/docker-data/paperless_ngx-${CONTEXT}/webserver/data:/usr/src/paperless/data
+ - /opt/docker-data/paperless_ngx-${CONTEXT}/webserver/media:/usr/src/paperless/media
+ - /opt/docker-data/paperless_ngx-${CONTEXT}/webserver/export:/usr/src/paperless/export
+ - /opt/docker-data/paperless_ngx-${CONTEXT}/webserver/consume:/usr/src/paperless/consume
env_file: docker-compose.env
environment:
PAPERLESS_REDIS: redis://broker:6379
@@ -105,9 +105,3 @@ services:
extends:
file: common-settings.yml
service: common-settings
-
-volumes:
- data:
- media:
- pgdata:
- redisdata:
--
2.39.1
From a1ff3cdfd84a45e0a383168470a5028246577a7d Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 22:37:44 +0200
Subject: [PATCH 06/12] refactor(compose): Introduce dedicated network
---
.../compose/docker-compose.postgres-tika.yml | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index eacb76c8..05885149 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -35,6 +35,8 @@ services:
broker:
image: docker.io/library/redis:7
container_name: "paperless_ngx-broker-${CONTEXT}"
+ networks:
+ paperless_ngx-default:
extends:
file: common-settings.yml
service: common-settings
@@ -44,6 +46,8 @@ services:
db:
image: docker.io/library/postgres:13
container_name: "paperless_ngx-db-${CONTEXT}"
+ networks:
+ paperless_ngx-default:
extends:
file: common-settings.yml
service: common-settings
@@ -57,6 +61,8 @@ services:
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
container_name: "paperless_ngx-webserver-${CONTEXT}"
+ networks:
+ paperless_ngx-default:
extends:
file: common-settings.yml
service: common-settings
@@ -88,6 +94,8 @@ services:
gotenberg:
image: docker.io/gotenberg/gotenberg:7.8
container_name: "paperless_ngx-gotenberg-${CONTEXT}"
+ networks:
+ paperless_ngx-default:
extends:
file: common-settings.yml
service: common-settings
@@ -102,6 +110,19 @@ services:
tika:
image: ghcr.io/paperless-ngx/tika:latest
container_name: "paperless_ngx-tika-${CONTEXT}"
+ networks:
+ paperless_ngx-default:
extends:
file: common-settings.yml
service: common-settings
+
+networks:
+ paperless_ngx-default:
+ name: paperless_ngx-${CONTEXT}
+ driver: bridge
+ driver_opts:
+ com.docker.network.enable_ipv6: "false"
+ ipam:
+ driver: default
+ config:
+ - subnet: ${SUBNET}
--
2.39.1
From fd35306130b35d9c4d77a3ca6849e96222a244cb Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 22:39:23 +0200
Subject: [PATCH 07/12] refactor(compose): No double quotes for port variable
needed
---
docker/compose/docker-compose.postgres-tika.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index 05885149..f1dd4913 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -72,7 +72,7 @@ services:
- gotenberg
- tika
ports:
- - "${WEBSERVER_PORT}":8000
+ - ${WEBSERVER_PORT}:8000
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s
--
2.39.1
From 0defc3f29d607e8c81c655b15fb9e92cf3921fdb Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 22:53:20 +0200
Subject: [PATCH 08/12] refactor(compose): Replace hard-linked env file with
variables
---
docker/compose/docker-compose.postgres-tika.yml | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index f1dd4913..1a5abbb8 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -83,13 +83,17 @@ services:
- /opt/docker-data/paperless_ngx-${CONTEXT}/webserver/media:/usr/src/paperless/media
- /opt/docker-data/paperless_ngx-${CONTEXT}/webserver/export:/usr/src/paperless/export
- /opt/docker-data/paperless_ngx-${CONTEXT}/webserver/consume:/usr/src/paperless/consume
- env_file: docker-compose.env
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
+ PAPERLESS_OCR_LANGUAGE: ${PAPERLESS_OCR_LANGUAGE}
+ PAPERLESS_OCR_LANGUAGES: ${PAPERLESS_OCR_LANGUAGES}
+ PAPERLESS_SECRET_KEY: ${PAPERLESS_SECRET_KEY}
+ PAPERLESS_TIME_ZONE: ${PAPERLESS_TIME_ZONE}
+ PAPERLESS_URL: ${PAPERLESS_URL}
gotenberg:
image: docker.io/gotenberg/gotenberg:7.8
--
2.39.1
From c044e323b9d09a95c782b0a216c02874be52611c Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Tue, 16 May 2023 23:15:26 +0200
Subject: [PATCH 09/12] feat(compose): Bind to a virtual IP address
---
docker/compose/docker-compose.postgres-tika.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index 1a5abbb8..3cb20287 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -72,7 +72,7 @@ services:
- gotenberg
- tika
ports:
- - ${WEBSERVER_PORT}:8000
+ - ${WEBSERVER_VIP}:${WEBSERVER_PORT}:8000
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s
--
2.39.1
From 51744302beb94ff44d348f3abf834e5222aca675 Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Wed, 17 May 2023 23:33:44 +0200
Subject: [PATCH 10/12] fix(compose): Apply unpaper, use cleaned images to
build output file
---
docker/compose/docker-compose.postgres-tika.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index 3cb20287..ed60ce40 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -89,6 +89,7 @@ services:
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
+ PAPERLESS_OCR_CLEAN: ${PAPERLESS_OCR_CLEAN}
PAPERLESS_OCR_LANGUAGE: ${PAPERLESS_OCR_LANGUAGE}
PAPERLESS_OCR_LANGUAGES: ${PAPERLESS_OCR_LANGUAGES}
PAPERLESS_SECRET_KEY: ${PAPERLESS_SECRET_KEY}
--
2.39.1
From 516c326ba44243c768b94b604d627616c580386c Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Wed, 17 May 2023 23:37:44 +0200
Subject: [PATCH 11/12] fix(compose): Let ping tell us when our virtual IP
address is bound
---
docker/compose/docker-compose.postgres-tika.yml | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index ed60ce40..e4e2b895 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -51,6 +51,12 @@ services:
extends:
file: common-settings.yml
service: common-settings
+ healthcheck:
+ test: ["CMD", "ping", "-qnc", "1", "-W", "0.2", "${WEBSERVER_VIP}"]
+ interval: 2s
+ timeout: 2s
+ retries: 3
+ start_period: 10s
volumes:
- /opt/docker-data/paperless_ngx-${CONTEXT}/db/data:/var/lib/postgresql/data
environment:
@@ -67,10 +73,11 @@ services:
file: common-settings.yml
service: common-settings
depends_on:
- - db
- - broker
- - gotenberg
- - tika
+ db:
+ condition: service_healthy
+ broker:
+ gotenberg:
+ tika:
ports:
- ${WEBSERVER_VIP}:${WEBSERVER_PORT}:8000
healthcheck:
--
2.39.1
From 249e2190fba5abd4a13c1311fe089936c3affe87 Mon Sep 17 00:00:00 2001
From: hygienic-books <>
Date: Wed, 17 May 2023 23:51:15 +0200
Subject: [PATCH 12/12] fix(compose): Unify depends_on
---
docker/compose/docker-compose.postgres-tika.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/docker/compose/docker-compose.postgres-tika.yml b/docker/compose/docker-compose.postgres-tika.yml
index e4e2b895..d3ec434d 100644
--- a/docker/compose/docker-compose.postgres-tika.yml
+++ b/docker/compose/docker-compose.postgres-tika.yml
@@ -76,8 +76,11 @@ services:
db:
condition: service_healthy
broker:
+ condition: service_started
gotenberg:
+ condition: service_started
tika:
+ condition: service_started
ports:
- ${WEBSERVER_VIP}:${WEBSERVER_PORT}:8000
healthcheck:
--
2.39.1

113
snipeit/README.md Normal file
View File

@@ -0,0 +1,113 @@
# How to
Add a `COMPOSE_ENV_FILE` and export it along with the location where this repo subdirectory lives, here for example `/opt/containers/snipeit` plus all other variables. At [env/fully.qualified.domain.name_ctx.example](env/fully.qualified.domain.name_ctx.example) you'll find an example file. For parameters that aren't self-explanatory check out [Environment variables](#environment-variables) below. The `COMPOSE_CTX` here will be equal to whatever's in your `CONTEXT` down in [Environment variables](#environment-variables).
## Prep
```
export COMPOSE_DIR='/opt/containers/snipeit'
export COMPOSE_CTX='ux_edmonton'
export COMPOSE_PROJECT_NAME='snipeit-'"${COMPOSE_CTX}"
export COMPOSE_FILE="${COMPOSE_DIR}"'/docker-compose.yml'
export COMPOSE_ENV_FILE=
```
## Start
```
docker compose --project-name "${COMPOSE_PROJECT_NAME}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV_FILE}" --profile full up --detach
```
## MySQL
At the time of writing the manual ([https://snipe-it.readme.io/docs/docker](https://snipe-it.readme.io/docs/docker)) recommends that for MySQL versions newer than 5.6 you should at first run MySQL without `STRICT_TRANS_TABLES` mode, quote:
> Newer MySQL containers (5.7 and later, or MariaDB) may run in strict-mode by default, and the initial migrations and application setup will fail in strict mode. If you want to use one of those versions, you need to disable strict mode first!
Tests show that this was not needed on an example MySQL 8.0.33 instance. If you want to be sure to not mess anything up in [docker-compose.yml](docker-compose.yml) remove the comment in front of `command: mysqld --sql_mode=""` so that this overrides the default `command: mysqld` thereby removing all enabled modes. Once initial database setup is done comment this line out again for subsequent starts.
By default the following modes are active:
1. `ONLY_FULL_GROUP_BY`
1. `STRICT_TRANS_TABLES`
1. `NO_ZERO_IN_DATE`
1. `NO_ZERO_DATE`
1. `ERROR_FOR_DIVISION_BY_ZERO`
1. `NO_ENGINE_SUBSTITUTION`
# Environment variables
Some non-standard env vars and some that can benefit from a short explanation are listed here. Whenever we're referring to the manual this was at the time of writing located at [https://snipe-it.readme.io/docs/docker](https://snipe-it.readme.io/docs/docker).
-
```
APP_KEY=base64:...
```
Run `docker run --rm snipe/snipe-it` to have the Snipe-IT container generate a random `APP_KEY`, print it out and terminate. You can put that randomly generated `APP_KEY` here along with the `base64:` prefix that's part of the string.
-
```
APP_TRUSTED_PROXIES=172.16.0.0/12
```
This comes from the manual for operation behind a reverse proxy. We're running Snipe-IT behind a reverse proxy on a Docker host with default network configs. Docker by default uses the address prefix `172.16.0.0/12` for itself. To the Snipe-IT container a reverse proxy container will always send its traffic from this subnet.
-
```
APP_URL=https://fully.qualified.domain.name
```
Do not add a trailing slash nor a port number.
-
```
CONTEXT=ux_edmonton
```
Whatever context you're using to deploy any given Snipe-IT instance. The `CONTEXT` var is used for example in named volume paths on your file system. This example is intended to run for a User Experience team based in Edmonton, Alberta, Canada.
-
```
MYSQL_PORT=33006
```
We want our database exposed on the Docker host itelf to easily manage it with external SQL management tools.
-
```
MYSQL_PORT_3306_TCP_ADDR=mysql
```
For reasons not entirely understood (by us) the Docker Compose service name `mysql` remained unresolvable to the Snipe-IT containers unless this hostname was given.
-
```
MYSQL_ROOT_HOST=172.21.97.1
```
In addition to the default user `'root'@'localhost'` we want MySQL to also generate `'root'@'172.21.97.1'` to easily remote-manage this database instance for example by SSH-tunneling to the Docker host and the connecting to the MySQL daemon with SQL management tools.
-
```
SECURE_COOKIES=true
```
This also comes straight from the manual for operation behind a reverse proxy.
# Reverse proxy
A reverse proxy server should send the `X-Forwarded-Host` header and `X-Forwarded-Proto` header. With an other wise standard Nginx config for example you'll want to add these settings.
Details for a complete Nginx (or other) reverse proxy config are beyond the scope of this document.
```
server {
listen ...
location / {
proxy_pass http://...;
...
proxy_set_header X-Forwarded-Proto $scheme; <---
proxy_set_header X-Forwarded-Host $http_host; <---
}
}
```

View File

@@ -0,0 +1,14 @@
# For the remainder of this Dockerfile EXAMPLE_ARG_FOR_DOCKERFILE will be
# available with a value of 'must_be_available_in_dockerfile', check out the env
# file at 'env/fully.qualified.domain.name.example' for reference.
# ARG EXAMPLE_ARG_FOR_DOCKERFILE
# Another env var, this one's needed in the example build step below:
# ARG MYSQL_VERSION
# Example
# FROM "mysql:${MYSQL_VERSION}"
# RUN apt-get update && \
# apt-get -y install \
# somepackage-6.q16-6-extra && \
# rm -rf /var/lib/apt/lists/*

View File

@@ -0,0 +1,14 @@
# For the remainder of this Dockerfile EXAMPLE_ARG_FOR_DOCKERFILE will be
# available with a value of 'must_be_available_in_dockerfile', check out the env
# file at 'env/fully.qualified.domain.name.example' for reference.
# ARG EXAMPLE_ARG_FOR_DOCKERFILE
# Another env var, this one's needed in the example build step below:
# ARG SNIPEIT_VERSION
# Example
# FROM "snipeit:${SNIPEIT_VERSION}"
# RUN apt-get update && \
# apt-get -y install \
# somepackage-6.q16-6-extra && \
# rm -rf /var/lib/apt/lists/*

View File

@@ -0,0 +1,11 @@
services:
common-settings:
environment:
TZ: "${TIMEZONE:-Etc/UTC}"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
compress: "true"
restart: "${RESTARTPOLICY:-unless-stopped}"

View File

@@ -0,0 +1,19 @@
services:
snipeit-build:
image: "snipe/snipe-it:${SNIPEIT_VERSION}"
profiles: ["build", "build-snipeit"]
build:
context: "build-context/snipeit"
dockerfile: Dockerfile
args:
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
SNIPEIT_VERSION: "${SNIPEIT_VERSION}"
mysql-build:
image: "mysql:${MYSQL_VERSION}"
profiles: ["build", "build-mysql"]
build:
context: "build-context/mysql"
dockerfile: Dockerfile
args:
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
MYSQL_VERSION: "${MYSQL_VERSION}"

View File

@@ -0,0 +1,74 @@
services:
snipeit:
image: "snipe/snipe-it:${SNIPEIT_VERSION}"
container_name: "snipeit-snipeit-${CONTEXT}"
networks:
snipeit-default:
profiles: ["full", "snipeit"]
depends_on:
mysql:
condition: service_healthy
extends:
file: common-settings.yml
service: common-settings
ports:
- ${SNIPEIT_PORT}:80
volumes:
- /opt/docker-data/snipeit-${CONTEXT}/snipeit/data:/var/lib/snipeit
environment:
APP_ENV: ${APP_ENV}
APP_KEY: ${APP_KEY}
APP_LOCALE: ${APP_LOCALE}
APP_TIMEZONE: ${APP_TIMEZONE}
APP_TRUSTED_PROXIES: ${APP_TRUSTED_PROXIES}
APP_URL: ${APP_URL}
MAIL_ENV_ENCRYPTION: ${MAIL_ENV_ENCRYPTION}
MAIL_ENV_FROM_ADDR: ${MAIL_ENV_FROM_ADDR}
MAIL_ENV_FROM_NAME: ${MAIL_ENV_FROM_NAME}
MAIL_ENV_PASSWORD: ${MAIL_ENV_PASSWORD}
MAIL_ENV_USERNAME: ${MAIL_ENV_USERNAME}
MAIL_PORT_587_TCP_ADDR: ${MAIL_PORT_587_TCP_ADDR}
MAIL_PORT_587_TCP_PORT: ${MAIL_PORT_587_TCP_PORT}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_PORT_3306_TCP_ADDR: ${MYSQL_PORT_3306_TCP_ADDR}
MYSQL_USER: ${MYSQL_USER}
PHP_UPLOAD_LIMIT: ${PHP_UPLOAD_LIMIT}
SECURE_COOKIES: ${SECURE_COOKIES}
APP_DEBUG: ${APP_DEBUG}
mysql:
image: "mysql:${MYSQL_VERSION}"
container_name: "snipeit-mysql-${CONTEXT}"
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "--protocol", "tcp", "-h", "127.0.0.1"]
interval: 3s
timeout: 1s
retries: 20
start_period: 2s
networks:
snipeit-default:
profiles: ["full", "mysql"]
extends:
file: common-settings.yml
service: common-settings
ports:
- ${MYSQL_PORT}:3306
volumes:
- /opt/docker-data/snipeit-${CONTEXT}/mysql/data:/var/lib/mysql
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_HOST: ${MYSQL_ROOT_HOST}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_USER}
# command: mysqld --sql_mode=""
networks:
snipeit-default:
name: snipeit-${CONTEXT}
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: ${SUBNET}

View File

@@ -0,0 +1,28 @@
APP_ENV=production
APP_KEY=base64:...
APP_LOCALE=en
APP_TIMEZONE=America/Edmonton
APP_TRUSTED_PROXIES=172.16.0.0/12
APP_URL=https://fully.qualified.domain.name
CONTEXT=ux_edmonton
MAIL_ENV_ENCRYPTION=tls
MAIL_ENV_FROM_ADDR=assets@fully.qualified.domain.name
MAIL_ENV_FROM_NAME=Asset Management
MAIL_ENV_PASSWORD=t0psecr3t-one
MAIL_ENV_USERNAME=assets@fully.qualified.domain.name
MAIL_PORT_587_TCP_ADDR=smtp.fully.qualified.domain.name
MAIL_PORT_587_TCP_PORT=587
MYSQL_DATABASE=snipeit
MYSQL_PASSWORD=t0psecr3t-two
MYSQL_PORT=33006
MYSQL_PORT_3306_TCP_ADDR=mysql
MYSQL_ROOT_HOST=172.21.97.1
MYSQL_ROOT_PASSWORD=t0psecr3t-three
MYSQL_USER=snipeit
MYSQL_VERSION=latest
PHP_UPLOAD_LIMIT=100
SECURE_COOKIES=true
SNIPEIT_PORT=8080
SNIPEIT_VERSION=latest
SUBNET=172.21.97.0/24
APP_DEBUG=false