mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Compare commits
	
		
			129 Commits
		
	
	
		
			v2.14.3
			...
			feature-ma
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 7d74177c55 | ||
|   | a548c32c1f | ||
|   | ea911e73c6 | ||
|   | 6b7fb286f7 | ||
|   | b40479632b | ||
|   | c122c60d3f | ||
|   | 4f08b5fa20 | ||
|   | 3bf64ae7da | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 822c2d2d56 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 98e0a934ac | ||
|   | ceffcd6360 | ||
|   | 37442ff829 | ||
|   | de5f66b3a0 | ||
|   | e37096f66f | ||
|   | e49ecd4dfe | ||
|   | 4718df271f | ||
|   | 17bb3ebbf5 | ||
|   | 5e00c1c676 | ||
|   | a9ef7ff58e | ||
|   | 518091f856 | ||
|   | feb30f36df | ||
|   | bbad36717f | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 329ef7aef3 | ||
|   | 2b2115e5f0 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | ba5705a54f | ||
|   | ea94626b82 | ||
|   | fdfea68576 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 4e61c2b2e6 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 7c959754a0 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | fed16974dd | ||
|   | ea3303aa76 | ||
|   | 1dc80f04cb | ||
|   | c316ae369b | ||
|   | d94b284815 | ||
|   | 63bb3644f6 | ||
|   | 880f08599a | ||
|   | 71472a6a82 | ||
|   | 7f36163c3b | ||
|   | e560fa3be0 | ||
|   | b274665e21 | ||
|   | a499905605 | ||
|   | b8bdc10f25 | ||
|   | e08606af6e | ||
|   | 52ab07c673 | ||
|   | 046d8456e2 | ||
|   | 3314c59828 | ||
|   | 2103a499eb | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 7ab779e78a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 49390c9427 | ||
|   | 6f29d64325 | ||
|   | 065724befb | ||
|   | e877beea4e | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 3e848e6e0f | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 2e5656e1ce | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 438650bf17 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 7df0b621a5 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 4cd755f641 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 8597911d85 | ||
|   | befb80bddf | ||
|   | 7af6983cab | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 16d6bb7334 | ||
|   | 49b658a944 | ||
|   | e1d8680698 | ||
|   | ee72e2d1fd | ||
|   | e0ea4a4625 | ||
|   | c2a9ac332a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | bf368aadd0 | ||
|   | 54e72d5b60 | ||
|   | cf7422346a | ||
|   | 5b8c9ef5fc | ||
|   | f56974f158 | ||
|   | 427508edf1 | ||
|   | 311b259cff | ||
|   | fce7b03324 | ||
|   | 79956d6a7b | ||
|   | 978b072bff | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 9c6f695dbf | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 0100fcbb23 | ||
|   | 1745da0d60 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | e4e906ce2b | ||
|   | 80c7b97fec | ||
|   | 270e70a958 | ||
|   | 082bf6fb8e | ||
|   | 38296d9426 | ||
|   | 8311313e6e | ||
|   | ac292999ef | ||
|   | f3cda54cd1 | ||
|   | 8f9a294529 | ||
|   | 702de0cac3 | ||
|   | ca42762841 | ||
|   | 13cfd6f904 | ||
|   | 18c4e6029f | ||
|   | 6c34e37838 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 2c28348b56 | ||
|   | 79e541244e | ||
|   | 74afad5976 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | c694c9791b | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 11ceb8bde5 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 20ec8cb57b | ||
|   | bfc11a545b | ||
|   | 4866af31cb | ||
|   | 0ea4da03a7 | ||
|   | 41bcc12cc2 | ||
|   | 475c231c6f | ||
|   | e00dd46b22 | ||
|   | fd425aa618 | ||
|   | e1dde85c59 | ||
|   | 01207a284d | ||
|   | 0f863ab378 | ||
|   | 258064b339 | ||
|   | 2bcb37f3e9 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 81f8c64b2c | ||
|   | 3b80112521 | ||
|   | 459feea31e | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | eea5839390 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | c79414ebd9 | ||
|   | ed1775e689 | ||
|   | cd50f20a20 | ||
|   | c8ec70c05f | ||
|   | 5e3ee3a80d | ||
|   | 29726c3ce1 | ||
|   | 6804c92861 | ||
|   | a32077566b | ||
|   | 283bcb4c91 | ||
|   | f68ee628d9 | ||
|   | bd5ba97ee8 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 325594034e | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 23ef52f405 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 2b45793bc2 | 
| @@ -123,13 +123,13 @@ RUN set -eux \ | |||||||
| WORKDIR /usr/src/paperless/src/docker/ | WORKDIR /usr/src/paperless/src/docker/ | ||||||
|  |  | ||||||
| COPY [ \ | COPY [ \ | ||||||
|   "docker/imagemagick-policy.xml", \ |   "docker/rootfs/etc/ImageMagick-6/paperless-policy.xml", \ | ||||||
|   "./" \ |   "./" \ | ||||||
| ] | ] | ||||||
|  |  | ||||||
| RUN set -eux \ | RUN set -eux \ | ||||||
|   && echo "Configuring ImageMagick" \ |   && echo "Configuring ImageMagick" \ | ||||||
|     && mv imagemagick-policy.xml /etc/ImageMagick-6/policy.xml |     && mv paperless-policy.xml /etc/ImageMagick-6/policy.xml | ||||||
|  |  | ||||||
| # Packages needed only for building a few quick Python | # Packages needed only for building a few quick Python | ||||||
| # dependencies | # dependencies | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ services: | |||||||
|     command: /bin/sh -c "chown -R paperless:paperless /usr/src/paperless/paperless-ngx/src/documents/static/frontend && chown -R paperless:paperless /usr/src/paperless/paperless-ngx/.ruff_cache && while sleep 1000; do :; done" |     command: /bin/sh -c "chown -R paperless:paperless /usr/src/paperless/paperless-ngx/src/documents/static/frontend && chown -R paperless:paperless /usr/src/paperless/paperless-ngx/.ruff_cache && while sleep 1000; do :; done" | ||||||
|  |  | ||||||
|   gotenberg: |   gotenberg: | ||||||
|     image: docker.io/gotenberg/gotenberg:7.10 |     image: docker.io/gotenberg/gotenberg:8.17 | ||||||
|     restart: unless-stopped |     restart: unless-stopped | ||||||
|  |  | ||||||
|     # The Gotenberg Chromium route is used to convert .eml files. We do not |     # The Gotenberg Chromium route is used to convert .eml files. We do not | ||||||
|   | |||||||
| @@ -26,3 +26,5 @@ | |||||||
| ./dist | ./dist | ||||||
| ./scripts | ./scripts | ||||||
| ./resources | ./resources | ||||||
|  | # Other stuff | ||||||
|  | **/*.drawio.png | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							| @@ -2,10 +2,10 @@ blank_issues_enabled: false | |||||||
| contact_links: | contact_links: | ||||||
|   - name: 🤔 Questions and Help |   - name: 🤔 Questions and Help | ||||||
|     url: https://github.com/paperless-ngx/paperless-ngx/discussions |     url: https://github.com/paperless-ngx/paperless-ngx/discussions | ||||||
|     about: This issue tracker is not for support questions. Please refer to our Discussions. |     about: General questions or support for using Paperless-ngx. | ||||||
|   - name: 💬 Chat |   - name: 💬 Chat | ||||||
|     url: https://matrix.to/#/#paperlessngx:matrix.org |     url: https://matrix.to/#/#paperlessngx:matrix.org | ||||||
|     about: Want to discuss Paperless-ngx with others? Check out our chat. |     about: Want to discuss Paperless-ngx with others? Check out our chat. | ||||||
|   - name: 🚀 Feature Request |   - name: 🚀 Feature Request | ||||||
|     url: https://github.com/paperless-ngx/paperless-ngx/discussions/new?category=feature-requests |     url: https://github.com/paperless-ngx/paperless-ngx/discussions/new?category=feature-requests | ||||||
|     about: Remember to search for existing feature requests and "up-vote" any you like |     about: Remember to search for existing feature requests and "up-vote" those that you like. | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -16,7 +16,7 @@ on: | |||||||
| env: | env: | ||||||
|   # This is the version of pipenv all the steps will use |   # This is the version of pipenv all the steps will use | ||||||
|   # If changing this, change Dockerfile |   # If changing this, change Dockerfile | ||||||
|   DEFAULT_PIP_ENV_VERSION: "2024.4.0" |   DEFAULT_PIP_ENV_VERSION: "2024.4.1" | ||||||
|   # This is the default version of Python to use in most steps which aren't specific |   # This is the default version of Python to use in most steps which aren't specific | ||||||
|   DEFAULT_PYTHON_VERSION: "3.11" |   DEFAULT_PYTHON_VERSION: "3.11" | ||||||
|  |  | ||||||
| @@ -131,7 +131,7 @@ jobs: | |||||||
|       - |       - | ||||||
|         name: Configure ImageMagick |         name: Configure ImageMagick | ||||||
|         run: | |         run: | | ||||||
|           sudo cp docker/imagemagick-policy.xml /etc/ImageMagick-6/policy.xml |           sudo cp docker/rootfs/etc/ImageMagick-6/paperless-policy.xml /etc/ImageMagick-6/policy.xml | ||||||
|       - |       - | ||||||
|         name: Install Python dependencies |         name: Install Python dependencies | ||||||
|         run: | |         run: | | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ repos: | |||||||
|       - id: check-case-conflict |       - id: check-case-conflict | ||||||
|       - id: detect-private-key |       - id: detect-private-key | ||||||
|   - repo: https://github.com/codespell-project/codespell |   - repo: https://github.com/codespell-project/codespell | ||||||
|     rev: v2.3.0 |     rev: v2.4.0 | ||||||
|     hooks: |     hooks: | ||||||
|       - id: codespell |       - id: codespell | ||||||
|         exclude: "(^src-ui/src/locale/)|(^src-ui/e2e/)|(^src/paperless_mail/tests/samples/)" |         exclude: "(^src-ui/src/locale/)|(^src-ui/e2e/)|(^src/paperless_mail/tests/samples/)" | ||||||
| @@ -51,7 +51,7 @@ repos: | |||||||
|           - 'prettier-plugin-organize-imports@4.1.0' |           - 'prettier-plugin-organize-imports@4.1.0' | ||||||
|   # Python hooks |   # Python hooks | ||||||
|   - repo: https://github.com/astral-sh/ruff-pre-commit |   - repo: https://github.com/astral-sh/ruff-pre-commit | ||||||
|     rev: v0.8.6 |     rev: v0.9.6 | ||||||
|     hooks: |     hooks: | ||||||
|       - id: ruff |       - id: ruff | ||||||
|       - id: ruff-format |       - id: ruff-format | ||||||
|   | |||||||
| @@ -32,13 +32,13 @@ extend-select = [ | |||||||
|   "RUF",   # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf |   "RUF",   # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf | ||||||
|   "FLY",   # https://docs.astral.sh/ruff/rules/#flynt-fly |   "FLY",   # https://docs.astral.sh/ruff/rules/#flynt-fly | ||||||
|   "PTH",   # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth |   "PTH",   # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth | ||||||
|  |   "FBT",   # https://docs.astral.sh/ruff/rules/#flake8-boolean-trap-fbt | ||||||
| ] | ] | ||||||
| ignore = ["DJ001", "SIM105", "RUF012"] | ignore = ["DJ001", "SIM105", "RUF012"] | ||||||
|  |  | ||||||
| [lint.per-file-ignores] | [lint.per-file-ignores] | ||||||
| ".github/scripts/*.py" = ["E501", "INP001", "SIM117"] | ".github/scripts/*.py" = ["E501", "INP001", "SIM117"] | ||||||
| "docker/wait-for-redis.py" = ["INP001", "T201"] | "docker/wait-for-redis.py" = ["INP001", "T201"] | ||||||
| "src/documents/consumer.py" = ["PTH"]  # TODO Enable & remove |  | ||||||
| "src/documents/file_handling.py" = ["PTH"]  # TODO Enable & remove | "src/documents/file_handling.py" = ["PTH"]  # TODO Enable & remove | ||||||
| "src/documents/management/commands/document_consumer.py" = ["PTH"]  # TODO Enable & remove | "src/documents/management/commands/document_consumer.py" = ["PTH"]  # TODO Enable & remove | ||||||
| "src/documents/management/commands/document_exporter.py" = ["PTH"]  # TODO Enable & remove | "src/documents/management/commands/document_exporter.py" = ["PTH"]  # TODO Enable & remove | ||||||
| @@ -51,8 +51,6 @@ ignore = ["DJ001", "SIM105", "RUF012"] | |||||||
| "src/documents/signals/handlers.py" = ["PTH"]  # TODO Enable & remove | "src/documents/signals/handlers.py" = ["PTH"]  # TODO Enable & remove | ||||||
| "src/documents/tasks.py" = ["PTH"]  # TODO Enable & remove | "src/documents/tasks.py" = ["PTH"]  # TODO Enable & remove | ||||||
| "src/documents/tests/test_api_app_config.py" = ["PTH"]  # TODO Enable & remove | "src/documents/tests/test_api_app_config.py" = ["PTH"]  # TODO Enable & remove | ||||||
| "src/documents/tests/test_api_bulk_download.py" = ["PTH"]  # TODO Enable & remove |  | ||||||
| "src/documents/tests/test_api_documents.py" = ["PTH"]  # TODO Enable & remove |  | ||||||
| "src/documents/tests/test_classifier.py" = ["PTH"]  # TODO Enable & remove | "src/documents/tests/test_classifier.py" = ["PTH"]  # TODO Enable & remove | ||||||
| "src/documents/tests/test_consumer.py" = ["PTH"]  # TODO Enable & remove | "src/documents/tests/test_consumer.py" = ["PTH"]  # TODO Enable & remove | ||||||
| "src/documents/tests/test_file_handling.py" = ["PTH"]  # TODO Enable & remove | "src/documents/tests/test_file_handling.py" = ["PTH"]  # TODO Enable & remove | ||||||
| @@ -78,8 +76,12 @@ ignore = ["DJ001", "SIM105", "RUF012"] | |||||||
| "src/paperless_tesseract/tests/test_parser.py" = ["RUF001", "PTH"]  # TODO PTH Enable & remove | "src/paperless_tesseract/tests/test_parser.py" = ["RUF001", "PTH"]  # TODO PTH Enable & remove | ||||||
| "src/paperless_tika/tests/test_live_tika.py" = ["PTH"]  # TODO Enable & remove | "src/paperless_tika/tests/test_live_tika.py" = ["PTH"]  # TODO Enable & remove | ||||||
| "src/paperless_tika/tests/test_tika_parser.py" = ["PTH"]  # TODO Enable & remove | "src/paperless_tika/tests/test_tika_parser.py" = ["PTH"]  # TODO Enable & remove | ||||||
|  | # Testing | ||||||
| "*/tests/*.py" = ["E501", "SIM117"] | "*/tests/*.py" = ["E501", "SIM117"] | ||||||
|  | # Migrations | ||||||
| "*/migrations/*.py" = ["E501", "SIM", "T201"] | "*/migrations/*.py" = ["E501", "SIM", "T201"] | ||||||
|  | # Docker specific | ||||||
|  | "docker/rootfs/usr/local/bin/wait-for-redis.py" = ["INP001", "T201"] | ||||||
|  |  | ||||||
| [lint.isort] | [lint.isort] | ||||||
| force-single-line = true | force-single-line = true | ||||||
|   | |||||||
							
								
								
									
										161
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										161
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -39,15 +39,70 @@ COPY Pipfile* ./ | |||||||
|  |  | ||||||
| RUN set -eux \ | RUN set -eux \ | ||||||
|   && echo "Installing pipenv" \ |   && echo "Installing pipenv" \ | ||||||
|     && python3 -m pip install --no-cache-dir --upgrade pipenv==2024.4.0 \ |     && python3 -m pip install --no-cache-dir --upgrade pipenv==2024.4.1 \ | ||||||
|   && echo "Generating requirement.txt" \ |   && echo "Generating requirement.txt" \ | ||||||
|     && pipenv requirements > requirements.txt |     && pipenv requirements > requirements.txt | ||||||
|  |  | ||||||
|  | # Stage: s6-overlay-base | ||||||
|  | # Purpose: Installs s6-overlay and rootfs | ||||||
|  | # Comments: | ||||||
|  | #  - Don't leave anything extra in here either | ||||||
|  | FROM docker.io/python:3.12-slim-bookworm AS s6-overlay-base | ||||||
|  |  | ||||||
|  | WORKDIR /usr/src/s6 | ||||||
|  |  | ||||||
|  | # https://github.com/just-containers/s6-overlay#customizing-s6-overlay-behaviour | ||||||
|  | ENV \ | ||||||
|  |     S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \ | ||||||
|  |     S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ | ||||||
|  |     S6_VERBOSITY=1 \ | ||||||
|  |     PATH=/command:$PATH | ||||||
|  |  | ||||||
|  | # Buildx provided, must be defined to use though | ||||||
|  | ARG TARGETARCH | ||||||
|  | ARG TARGETVARIANT | ||||||
|  | # Lock this version | ||||||
|  | ARG S6_OVERLAY_VERSION=3.2.0.2 | ||||||
|  |  | ||||||
|  | ARG S6_BUILD_TIME_PKGS="curl \ | ||||||
|  |                         xz-utils" | ||||||
|  |  | ||||||
|  | RUN set -eux \ | ||||||
|  |     && echo "Installing build time packages" \ | ||||||
|  |       && apt-get update \ | ||||||
|  |       && apt-get install --yes --quiet --no-install-recommends ${S6_BUILD_TIME_PKGS} \ | ||||||
|  |     && echo "Determining arch" \ | ||||||
|  |       && S6_ARCH="" \ | ||||||
|  |       && if [ "${TARGETARCH}${TARGETVARIANT}" = "amd64" ]; then S6_ARCH="x86_64"; \ | ||||||
|  |       elif [ "${TARGETARCH}${TARGETVARIANT}" = "arm64" ]; then S6_ARCH="aarch64"; fi\ | ||||||
|  |       && if [ -z "${S6_ARCH}" ]; then { echo "Error: Not able to determine arch"; exit 1; }; fi \ | ||||||
|  |     && echo "Installing s6-overlay for ${S6_ARCH}" \ | ||||||
|  |       && curl --fail --silent --no-progress-meter --show-error --location --remote-name-all --parallel --parallel-max 4 \ | ||||||
|  |         "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" \ | ||||||
|  |         "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz.sha256" \ | ||||||
|  |         "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz" \ | ||||||
|  |         "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz.sha256" \ | ||||||
|  |       && echo "Validating s6-archive checksums" \ | ||||||
|  |         && sha256sum --check ./*.sha256 \ | ||||||
|  |       && echo "Unpacking archives" \ | ||||||
|  |         && tar --directory / -Jxpf s6-overlay-noarch.tar.xz \ | ||||||
|  |         && tar --directory / -Jxpf s6-overlay-${S6_ARCH}.tar.xz \ | ||||||
|  |       && echo "Removing downloaded archives" \ | ||||||
|  |         && rm ./*.tar.xz \ | ||||||
|  |         && rm ./*.sha256 \ | ||||||
|  |     && echo "Cleaning up image" \ | ||||||
|  |       && apt-get --yes purge ${S6_BUILD_TIME_PKGS} \ | ||||||
|  |       && apt-get --yes autoremove --purge \ | ||||||
|  |       && rm -rf /var/lib/apt/lists/* | ||||||
|  |  | ||||||
|  | # Copy our service defs and filesystem | ||||||
|  | COPY ./docker/rootfs / | ||||||
|  |  | ||||||
| # Stage: main-app | # Stage: main-app | ||||||
| # Purpose: The final image | # Purpose: The final image | ||||||
| # Comments: | # Comments: | ||||||
| #  - Don't leave anything extra in here | #  - Don't leave anything extra in here | ||||||
| FROM docker.io/python:3.12-slim-bookworm AS main-app | FROM s6-overlay-base AS main-app | ||||||
|  |  | ||||||
| LABEL org.opencontainers.image.authors="paperless-ngx team <hello@paperless-ngx.com>" | LABEL org.opencontainers.image.authors="paperless-ngx team <hello@paperless-ngx.com>" | ||||||
| LABEL org.opencontainers.image.documentation="https://docs.paperless-ngx.com/" | LABEL org.opencontainers.image.documentation="https://docs.paperless-ngx.com/" | ||||||
| @@ -61,7 +116,7 @@ ARG DEBIAN_FRONTEND=noninteractive | |||||||
| ARG TARGETARCH | ARG TARGETARCH | ||||||
|  |  | ||||||
| # Can be workflow provided, defaults set for manual building | # Can be workflow provided, defaults set for manual building | ||||||
| ARG JBIG2ENC_VERSION=0.29 | ARG JBIG2ENC_VERSION=0.30 | ||||||
| ARG QPDF_VERSION=11.9.0 | ARG QPDF_VERSION=11.9.0 | ||||||
| ARG GS_VERSION=10.03.1 | ARG GS_VERSION=10.03.1 | ||||||
|  |  | ||||||
| @@ -127,91 +182,39 @@ RUN set -eux \ | |||||||
|     && apt-get update \ |     && apt-get update \ | ||||||
|     && apt-get install --yes --quiet --no-install-recommends ${RUNTIME_PACKAGES} \ |     && apt-get install --yes --quiet --no-install-recommends ${RUNTIME_PACKAGES} \ | ||||||
|     && echo "Installing pre-built updates" \ |     && echo "Installing pre-built updates" \ | ||||||
|  |       && curl --fail --silent --no-progress-meter --show-error --location --remote-name-all --parallel --parallel-max 4 \ | ||||||
|  |         https://github.com/paperless-ngx/builder/releases/download/qpdf-${QPDF_VERSION}/libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \ | ||||||
|  |         https://github.com/paperless-ngx/builder/releases/download/qpdf-${QPDF_VERSION}/qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \ | ||||||
|  |         https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ | ||||||
|  |         https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ | ||||||
|  |         https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10-common_${GS_VERSION}.dfsg-1_all.deb \ | ||||||
|  |         https://github.com/paperless-ngx/builder/releases/download/jbig2enc-${JBIG2ENC_VERSION}/jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \ | ||||||
|       && echo "Installing qpdf ${QPDF_VERSION}" \ |       && echo "Installing qpdf ${QPDF_VERSION}" \ | ||||||
|         && curl --fail --silent --show-error --location \ |  | ||||||
|           --output libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \ |  | ||||||
|           https://github.com/paperless-ngx/builder/releases/download/qpdf-${QPDF_VERSION}/libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \ |  | ||||||
|         && curl --fail --silent --show-error --location \ |  | ||||||
|           --output qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \ |  | ||||||
|           https://github.com/paperless-ngx/builder/releases/download/qpdf-${QPDF_VERSION}/qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \ |  | ||||||
|         && dpkg --install ./libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \ |         && dpkg --install ./libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \ | ||||||
|         && dpkg --install ./qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \ |         && dpkg --install ./qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \ | ||||||
|       && echo "Installing Ghostscript ${GS_VERSION}" \ |       && echo "Installing Ghostscript ${GS_VERSION}" \ | ||||||
|         && curl --fail --silent --show-error --location \ |  | ||||||
|           --output libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ |  | ||||||
|           https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ |  | ||||||
|         && curl --fail --silent --show-error --location \ |  | ||||||
|           --output ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ |  | ||||||
|           https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ |  | ||||||
|         && curl --fail --silent --show-error --location \ |  | ||||||
|           --output libgs10-common_${GS_VERSION}.dfsg-1_all.deb \ |  | ||||||
|           https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10-common_${GS_VERSION}.dfsg-1_all.deb \ |  | ||||||
|         && dpkg --install ./libgs10-common_${GS_VERSION}.dfsg-1_all.deb \ |         && dpkg --install ./libgs10-common_${GS_VERSION}.dfsg-1_all.deb \ | ||||||
|         && dpkg --install ./libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ |         && dpkg --install ./libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ | ||||||
|         && dpkg --install ./ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ |         && dpkg --install ./ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \ | ||||||
|       && echo "Installing jbig2enc" \ |       && echo "Installing jbig2enc" \ | ||||||
|         && curl --fail --silent --show-error --location \ |  | ||||||
|           --output jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \ |  | ||||||
|           https://github.com/paperless-ngx/builder/releases/download/jbig2enc-${JBIG2ENC_VERSION}/jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \ |  | ||||||
|         && dpkg --install ./jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \ |         && dpkg --install ./jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \ | ||||||
|  |       && echo "Configuring imagemagick" \ | ||||||
|  |         && cp /etc/ImageMagick-6/paperless-policy.xml /etc/ImageMagick-6/policy.xml \ | ||||||
|       && echo "Cleaning up image layer" \ |       && echo "Cleaning up image layer" \ | ||||||
|         && rm --force --verbose *.deb \ |         && rm --force --verbose *.deb \ | ||||||
|     && rm --recursive --force --verbose /var/lib/apt/lists/* \ |     && rm --recursive --force --verbose /var/lib/apt/lists/* | ||||||
|   && echo "Installing supervisor" \ |  | ||||||
|     && python3 -m pip install --default-timeout=1000 --upgrade --no-cache-dir supervisor==4.2.5 |  | ||||||
|  |  | ||||||
| # Copy gunicorn config | # Copy gunicorn config | ||||||
| # Changes very infrequently | # Changes very infrequently | ||||||
| WORKDIR /usr/src/paperless/ | WORKDIR /usr/src/paperless/ | ||||||
|  |  | ||||||
| COPY gunicorn.conf.py . | COPY --chown=1000:1000 gunicorn.conf.py /usr/src/paperless/gunicorn.conf.py | ||||||
|  |  | ||||||
| # setup docker-specific things |  | ||||||
| # These change sometimes, but rarely |  | ||||||
| WORKDIR /usr/src/paperless/src/docker/ |  | ||||||
|  |  | ||||||
| COPY [ \ |  | ||||||
|   "docker/imagemagick-policy.xml", \ |  | ||||||
|   "docker/supervisord.conf", \ |  | ||||||
|   "docker/docker-entrypoint.sh", \ |  | ||||||
|   "docker/docker-prepare.sh", \ |  | ||||||
|   "docker/paperless_cmd.sh", \ |  | ||||||
|   "docker/wait-for-redis.py", \ |  | ||||||
|   "docker/env-from-file.sh", \ |  | ||||||
|   "docker/management_script.sh", \ |  | ||||||
|   "docker/flower-conditional.sh", \ |  | ||||||
|   "docker/install_management_commands.sh", \ |  | ||||||
|   "/usr/src/paperless/src/docker/" \ |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| RUN set -eux \ |  | ||||||
|   && echo "Configuring ImageMagick" \ |  | ||||||
|     && mv imagemagick-policy.xml /etc/ImageMagick-6/policy.xml \ |  | ||||||
|   && echo "Configuring supervisord" \ |  | ||||||
|     && mkdir /var/log/supervisord /var/run/supervisord \ |  | ||||||
|     && mv supervisord.conf /etc/supervisord.conf \ |  | ||||||
|   && echo "Setting up Docker scripts" \ |  | ||||||
|     && mv docker-entrypoint.sh /sbin/docker-entrypoint.sh \ |  | ||||||
|     && chmod 755 /sbin/docker-entrypoint.sh \ |  | ||||||
|     && mv docker-prepare.sh /sbin/docker-prepare.sh \ |  | ||||||
|     && chmod 755 /sbin/docker-prepare.sh \ |  | ||||||
|     && mv wait-for-redis.py /sbin/wait-for-redis.py \ |  | ||||||
|     && chmod 755 /sbin/wait-for-redis.py \ |  | ||||||
|     && mv env-from-file.sh /sbin/env-from-file.sh \ |  | ||||||
|     && chmod 755 /sbin/env-from-file.sh \ |  | ||||||
|     && mv paperless_cmd.sh /usr/local/bin/paperless_cmd.sh \ |  | ||||||
|     && chmod 755 /usr/local/bin/paperless_cmd.sh \ |  | ||||||
|     && mv flower-conditional.sh /usr/local/bin/flower-conditional.sh \ |  | ||||||
|     && chmod 755 /usr/local/bin/flower-conditional.sh \ |  | ||||||
|   && echo "Installing management commands" \ |  | ||||||
|     && chmod +x install_management_commands.sh \ |  | ||||||
|     && ./install_management_commands.sh |  | ||||||
|  |  | ||||||
| WORKDIR /usr/src/paperless/src/ | WORKDIR /usr/src/paperless/src/ | ||||||
|  |  | ||||||
| # Python dependencies | # Python dependencies | ||||||
| # Change pretty frequently | # Change pretty frequently | ||||||
| COPY --from=pipenv-base /usr/src/pipenv/requirements.txt ./ | COPY --chown=1000:1000 --from=pipenv-base /usr/src/pipenv/requirements.txt ./ | ||||||
|  |  | ||||||
| # Packages needed only for building a few quick Python | # Packages needed only for building a few quick Python | ||||||
| # dependencies | # dependencies | ||||||
| @@ -224,20 +227,22 @@ ARG BUILD_PACKAGES="\ | |||||||
|   default-libmysqlclient-dev \ |   default-libmysqlclient-dev \ | ||||||
|   pkg-config" |   pkg-config" | ||||||
|  |  | ||||||
|  | ARG ZXING_VERSION=2.3.0 | ||||||
|  | ARG PSYCOPG_VERSION=3.2.4 | ||||||
|  |  | ||||||
| # hadolint ignore=DL3042 | # hadolint ignore=DL3042 | ||||||
| RUN --mount=type=cache,target=/root/.cache/pip/,id=pip-cache \ | RUN --mount=type=cache,target=/root/.cache/pip/,id=pip-cache \ | ||||||
|   set -eux \ |   set -eux \ | ||||||
|   && echo "Installing build system packages" \ |   && echo "Installing build system packages" \ | ||||||
|     && apt-get update \ |     && apt-get update \ | ||||||
|     && apt-get install --yes --quiet --no-install-recommends ${BUILD_PACKAGES} \ |     && apt-get install --yes --quiet --no-install-recommends ${BUILD_PACKAGES} \ | ||||||
|     && python3 -m pip install --no-cache-dir --upgrade wheel \ |     && python3 -m pip install --upgrade wheel \ | ||||||
|   && echo "Installing Python requirements" \ |   && echo "Installing Python requirements" \ | ||||||
|     && curl --fail --silent --show-error --location \ |     && curl --fail --silent --no-progress-meter --show-error --location --remote-name-all --parallel --parallel-max 4 \ | ||||||
|     --output psycopg_c-3.2.3-cp312-cp312-linux_x86_64.whl \ |       https://github.com/paperless-ngx/builder/releases/download/psycopg-${PSYCOPG_VERSION}/psycopg_c-${PSYCOPG_VERSION}-cp312-cp312-linux_x86_64.whl \ | ||||||
|     https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.3/psycopg_c-3.2.3-cp312-cp312-linux_x86_64.whl \ |       https://github.com/paperless-ngx/builder/releases/download/psycopg-${PSYCOPG_VERSION}/psycopg_c-${PSYCOPG_VERSION}-cp312-cp312-linux_aarch64.whl \ | ||||||
|     && curl --fail --silent --show-error --location \ |       https://github.com/paperless-ngx/builder/releases/download/zxing-${ZXING_VERSION}/zxing_cpp-${ZXING_VERSION}-cp312-cp312-linux_aarch64.whl \ | ||||||
|     --output psycopg_c-3.2.3-cp312-cp312-linux_aarch64.whl  \ |       https://github.com/paperless-ngx/builder/releases/download/zxing-${ZXING_VERSION}/zxing_cpp-${ZXING_VERSION}-cp312-cp312-linux_x86_64.whl \ | ||||||
|     https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.3/psycopg_c-3.2.3-cp312-cp312-linux_aarch64.whl \ |  | ||||||
|     && python3 -m pip install --default-timeout=1000 --find-links . --requirement requirements.txt \ |     && python3 -m pip install --default-timeout=1000 --find-links . --requirement requirements.txt \ | ||||||
|   && echo "Installing NLTK data" \ |   && echo "Installing NLTK data" \ | ||||||
|     && python3 -W ignore::RuntimeWarning -m nltk.downloader -d "/usr/share/nltk_data" snowball_data \ |     && python3 -W ignore::RuntimeWarning -m nltk.downloader -d "/usr/share/nltk_data" snowball_data \ | ||||||
| @@ -276,18 +281,16 @@ RUN set -eux \ | |||||||
|   && echo "Adjusting all permissions" \ |   && echo "Adjusting all permissions" \ | ||||||
|     && chown --from root:root --changes --recursive paperless:paperless /usr/src/paperless \ |     && chown --from root:root --changes --recursive paperless:paperless /usr/src/paperless \ | ||||||
|   && echo "Collecting static files" \ |   && echo "Collecting static files" \ | ||||||
|     && gosu paperless python3 manage.py collectstatic --clear --no-input --link \ |     && s6-setuidgid paperless python3 manage.py collectstatic --clear --no-input --link \ | ||||||
|     && gosu paperless python3 manage.py compilemessages |     && s6-setuidgid paperless python3 manage.py compilemessages | ||||||
|  |  | ||||||
| VOLUME ["/usr/src/paperless/data", \ | VOLUME ["/usr/src/paperless/data", \ | ||||||
|         "/usr/src/paperless/media", \ |         "/usr/src/paperless/media", \ | ||||||
|         "/usr/src/paperless/consume", \ |         "/usr/src/paperless/consume", \ | ||||||
|         "/usr/src/paperless/export"] |         "/usr/src/paperless/export"] | ||||||
|  |  | ||||||
| ENTRYPOINT ["/sbin/docker-entrypoint.sh"] | ENTRYPOINT ["/init"] | ||||||
|  |  | ||||||
| EXPOSE 8000 | EXPOSE 8000 | ||||||
|  |  | ||||||
| CMD ["/usr/local/bin/paperless_cmd.sh"] |  | ||||||
|  |  | ||||||
| HEALTHCHECK --interval=30s --timeout=10s --retries=5 CMD [ "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000" ] | HEALTHCHECK --interval=30s --timeout=10s --retries=5 CMD [ "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000" ] | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								Pipfile
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Pipfile
									
									
									
									
									
								
							| @@ -14,12 +14,14 @@ django-celery-results = "*" | |||||||
| django-compression-middleware = "*" | django-compression-middleware = "*" | ||||||
| django-cors-headers = "*" | django-cors-headers = "*" | ||||||
| django-extensions = "*" | django-extensions = "*" | ||||||
| django-filter = "~=24.3" | django-filter = "~=25.1" | ||||||
| django-guardian = "*" | django-guardian = "*" | ||||||
| django-multiselectfield = "*" | django-multiselectfield = "*" | ||||||
| django-soft-delete = "*" | django-soft-delete = "*" | ||||||
| djangorestframework = "~=3.15.2" | djangorestframework = "~=3.15.2" | ||||||
| djangorestframework-guardian = "*" | djangorestframework-guardian = "*" | ||||||
|  | drf-spectacular = "*" | ||||||
|  | drf-spectacular-sidecar = "*" | ||||||
| drf-writable-nested = "*" | drf-writable-nested = "*" | ||||||
| bleach = "*" | bleach = "*" | ||||||
| celery = {extras = ["redis"], version = "*"} | celery = {extras = ["redis"], version = "*"} | ||||||
| @@ -37,7 +39,7 @@ jinja2 = "~=3.1" | |||||||
| langdetect = "*" | langdetect = "*" | ||||||
| mysqlclient = "*" | mysqlclient = "*" | ||||||
| nltk = "*" | nltk = "*" | ||||||
| ocrmypdf = "~=16.8" | ocrmypdf = "~=16.9" | ||||||
| pathvalidate = "*" | pathvalidate = "*" | ||||||
| pdf2image = "*" | pdf2image = "*" | ||||||
| psycopg = {version = "*", extras = ["c"]} | psycopg = {version = "*", extras = ["c"]} | ||||||
| @@ -56,9 +58,9 @@ tqdm = "*" | |||||||
| # See https://github.com/paperless-ngx/paperless-ngx/issues/5494 | # See https://github.com/paperless-ngx/paperless-ngx/issues/5494 | ||||||
| uvicorn = {extras = ["standard"], version = "==0.25.0"} | uvicorn = {extras = ["standard"], version = "==0.25.0"} | ||||||
| watchdog = "~=6.0" | watchdog = "~=6.0" | ||||||
| whitenoise = "~=6.8" | whitenoise = "~=6.9" | ||||||
| whoosh = "~=2.7" | whoosh = "~=2.7" | ||||||
| zxing-cpp = {version = "*", platform_machine = "== 'x86_64'"} | zxing-cpp = "*" | ||||||
|  |  | ||||||
|  |  | ||||||
| [dev-packages] | [dev-packages] | ||||||
|   | |||||||
							
								
								
									
										3493
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3493
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| services: | services: | ||||||
|   gotenberg: |   gotenberg: | ||||||
|     image: docker.io/gotenberg/gotenberg:8.7 |     image: docker.io/gotenberg/gotenberg:8.17 | ||||||
|     hostname: gotenberg |     hostname: gotenberg | ||||||
|     container_name: gotenberg |     container_name: gotenberg | ||||||
|     network_mode: host |     network_mode: host | ||||||
|   | |||||||
| @@ -77,7 +77,7 @@ services: | |||||||
|       PAPERLESS_TIKA_ENDPOINT: http://tika:9998 |       PAPERLESS_TIKA_ENDPOINT: http://tika:9998 | ||||||
|  |  | ||||||
|   gotenberg: |   gotenberg: | ||||||
|     image: docker.io/gotenberg/gotenberg:8.7 |     image: docker.io/gotenberg/gotenberg:8.17 | ||||||
|     restart: unless-stopped |     restart: unless-stopped | ||||||
|     # The gotenberg chromium route is used to convert .eml files. We do not |     # The gotenberg chromium route is used to convert .eml files. We do not | ||||||
|     # want to allow external content like tracking pixels or even javascript. |     # want to allow external content like tracking pixels or even javascript. | ||||||
|   | |||||||
| @@ -71,7 +71,7 @@ services: | |||||||
|       PAPERLESS_TIKA_ENDPOINT: http://tika:9998 |       PAPERLESS_TIKA_ENDPOINT: http://tika:9998 | ||||||
|  |  | ||||||
|   gotenberg: |   gotenberg: | ||||||
|     image: docker.io/gotenberg/gotenberg:8.7 |     image: docker.io/gotenberg/gotenberg:8.17 | ||||||
|     restart: unless-stopped |     restart: unless-stopped | ||||||
|  |  | ||||||
|     # The gotenberg chromium route is used to convert .eml files. We do not |     # The gotenberg chromium route is used to convert .eml files. We do not | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ services: | |||||||
|       PAPERLESS_TIKA_ENDPOINT: http://tika:9998 |       PAPERLESS_TIKA_ENDPOINT: http://tika:9998 | ||||||
|  |  | ||||||
|   gotenberg: |   gotenberg: | ||||||
|     image: docker.io/gotenberg/gotenberg:8.7 |     image: docker.io/gotenberg/gotenberg:8.17 | ||||||
|     restart: unless-stopped |     restart: unless-stopped | ||||||
|  |  | ||||||
|     # The gotenberg chromium route is used to convert .eml files. We do not |     # The gotenberg chromium route is used to convert .eml files. We do not | ||||||
|   | |||||||
| @@ -1,120 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| set -e |  | ||||||
|  |  | ||||||
| wait_for_postgres() { |  | ||||||
| 	local attempt_num=1 |  | ||||||
| 	local -r max_attempts=5 |  | ||||||
|  |  | ||||||
| 	echo "Waiting for PostgreSQL to start..." |  | ||||||
|  |  | ||||||
| 	local -r host="${PAPERLESS_DBHOST:-localhost}" |  | ||||||
| 	local -r port="${PAPERLESS_DBPORT:-5432}" |  | ||||||
|  |  | ||||||
| 	# Disable warning, host and port can't have spaces |  | ||||||
| 	# shellcheck disable=SC2086 |  | ||||||
| 	while [ ! "$(pg_isready --host ${host} --port ${port})" ]; do |  | ||||||
|  |  | ||||||
| 		if [ $attempt_num -eq $max_attempts ]; then |  | ||||||
| 			echo "Unable to connect to database." |  | ||||||
| 			exit 1 |  | ||||||
| 		else |  | ||||||
| 			echo "Attempt $attempt_num failed! Trying again in 5 seconds..." |  | ||||||
| 		fi |  | ||||||
|  |  | ||||||
| 		attempt_num=$(("$attempt_num" + 1)) |  | ||||||
| 		sleep 5 |  | ||||||
| 	done |  | ||||||
| 	echo "Connected to PostgreSQL" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| wait_for_mariadb() { |  | ||||||
| 	echo "Waiting for MariaDB to start..." |  | ||||||
|  |  | ||||||
| 	local -r host="${PAPERLESS_DBHOST:=localhost}" |  | ||||||
| 	local -r port="${PAPERLESS_DBPORT:=3306}" |  | ||||||
|  |  | ||||||
| 	local attempt_num=1 |  | ||||||
| 	local -r max_attempts=5 |  | ||||||
|  |  | ||||||
| 	# Disable warning, host and port can't have spaces |  | ||||||
| 	# shellcheck disable=SC2086 |  | ||||||
| 	while ! true > /dev/tcp/$host/$port; do |  | ||||||
|  |  | ||||||
| 		if [ $attempt_num -eq $max_attempts ]; then |  | ||||||
| 			echo "Unable to connect to database." |  | ||||||
| 			exit 1 |  | ||||||
| 		else |  | ||||||
| 			echo "Attempt $attempt_num failed! Trying again in 5 seconds..." |  | ||||||
|  |  | ||||||
| 		fi |  | ||||||
|  |  | ||||||
| 		attempt_num=$(("$attempt_num" + 1)) |  | ||||||
| 		sleep 5 |  | ||||||
| 	done |  | ||||||
| 	echo "Connected to MariaDB" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| wait_for_redis() { |  | ||||||
| 	# We use a Python script to send the Redis ping |  | ||||||
| 	# instead of installing redis-tools just for 1 thing |  | ||||||
| 	if ! python3 /sbin/wait-for-redis.py; then |  | ||||||
| 		exit 1 |  | ||||||
| 	fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| migrations() { |  | ||||||
| 	( |  | ||||||
| 		# flock is in place to prevent multiple containers from doing migrations |  | ||||||
| 		# simultaneously. This also ensures that the db is ready when the command |  | ||||||
| 		# of the current container starts. |  | ||||||
| 		flock 200 |  | ||||||
| 		echo "Apply database migrations..." |  | ||||||
| 		python3 manage.py migrate --skip-checks --no-input |  | ||||||
| 	) 200>"${DATA_DIR}/migration_lock" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| django_checks() { |  | ||||||
| 	# Explicitly run the Django system checks |  | ||||||
| 	echo "Running Django checks" |  | ||||||
| 	python3 manage.py check |  | ||||||
| } |  | ||||||
|  |  | ||||||
| search_index() { |  | ||||||
|  |  | ||||||
| 	local -r index_version=9 |  | ||||||
| 	local -r index_version_file=${DATA_DIR}/.index_version |  | ||||||
|  |  | ||||||
| 	if [[ (! -f "${index_version_file}") || $(<"${index_version_file}") != "$index_version" ]]; then |  | ||||||
| 		echo "Search index out of date. Updating..." |  | ||||||
| 		python3 manage.py document_index reindex --no-progress-bar |  | ||||||
| 		echo ${index_version} | tee "${index_version_file}" >/dev/null |  | ||||||
| 	fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| superuser() { |  | ||||||
| 	if [[ -n "${PAPERLESS_ADMIN_USER}" ]]; then |  | ||||||
| 		python3 manage.py manage_superuser |  | ||||||
| 	fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| do_work() { |  | ||||||
| 	if [[ "${PAPERLESS_DBENGINE}" == "mariadb" ]]; then |  | ||||||
| 		wait_for_mariadb |  | ||||||
| 	elif [[ -n "${PAPERLESS_DBHOST}" ]]; then |  | ||||||
| 		wait_for_postgres |  | ||||||
| 	fi |  | ||||||
|  |  | ||||||
| 	wait_for_redis |  | ||||||
|  |  | ||||||
| 	migrations |  | ||||||
|  |  | ||||||
| 	django_checks |  | ||||||
|  |  | ||||||
| 	search_index |  | ||||||
|  |  | ||||||
| 	superuser |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| do_work |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| # Scans the environment variables for those with the suffix _FILE |  | ||||||
| # When located, checks the file exists, and exports the contents |  | ||||||
| # of the file as the same name, minus the suffix |  | ||||||
| # This allows the use of Docker secrets or mounted files |  | ||||||
| # to fill in any of the settings configurable via environment |  | ||||||
| # variables |  | ||||||
|  |  | ||||||
| set -eu |  | ||||||
|  |  | ||||||
| for line in $(printenv) |  | ||||||
| do |  | ||||||
| 	# Extract the name of the environment variable |  | ||||||
| 	env_name=${line%%=*} |  | ||||||
| 	# Check if it starts with "PAPERLESS_" and ends in "_FILE" |  | ||||||
| 	if [[ ${env_name} == PAPERLESS_*_FILE ]]; then |  | ||||||
| 		# This should have been named different.. |  | ||||||
| 		if [[ ${env_name} == "PAPERLESS_OCR_SKIP_ARCHIVE_FILE" || ${env_name} == "PAPERLESS_MODEL_FILE" ]]; then |  | ||||||
| 			continue |  | ||||||
| 		fi |  | ||||||
| 		# Extract the value of the environment |  | ||||||
| 		env_value=${line#*=} |  | ||||||
|  |  | ||||||
| 		# Check the file exists |  | ||||||
| 		if [[ -f ${env_value} ]]; then |  | ||||||
|  |  | ||||||
| 			# Trim off the _FILE suffix |  | ||||||
| 			non_file_env_name=${env_name%"_FILE"} |  | ||||||
| 			echo "Setting ${non_file_env_name} from file" |  | ||||||
|  |  | ||||||
| 			# Reads the value from th file |  | ||||||
| 			val="$(< "${!env_name}")" |  | ||||||
|  |  | ||||||
| 			# Sets the normal name to the read file contents |  | ||||||
| 			export "${non_file_env_name}"="${val}" |  | ||||||
|  |  | ||||||
| 		else |  | ||||||
| 			echo "File ${env_value} referenced by ${env_name} doesn't exist" |  | ||||||
| 		fi |  | ||||||
| 	fi |  | ||||||
| done |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| echo "Checking if we should start flower..." |  | ||||||
|  |  | ||||||
| if [[ -n  "${PAPERLESS_ENABLE_FLOWER}" ]]; then |  | ||||||
| 	# Small delay to allow celery to be up first |  | ||||||
| 	echo "Starting flower in 5s" |  | ||||||
| 	sleep 5 |  | ||||||
| 	celery --app paperless flower --conf=/usr/src/paperless/src/paperless/flowerconfig.py |  | ||||||
| else |  | ||||||
| 	echo "Not starting flower" |  | ||||||
| fi |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								docker/init-flow.drawio.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docker/init-flow.drawio.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 30 KiB | 
| @@ -1,5 +1,7 @@ | |||||||
| #!/usr/bin/env bash | #!/usr/bin/env bash | ||||||
|  |  | ||||||
|  | # Run this script to generate the management commands again (for example if a new command is create or the template is updated) | ||||||
|  |  | ||||||
| set -eu | set -eu | ||||||
|  |  | ||||||
| for command in decrypt_documents \ | for command in decrypt_documents \ | ||||||
| @@ -19,6 +21,6 @@ for command in decrypt_documents \ | |||||||
| 	prune_audit_logs; | 	prune_audit_logs; | ||||||
| do | do | ||||||
| 	echo "installing $command..." | 	echo "installing $command..." | ||||||
| 	sed "s/management_command/$command/g" management_script.sh > /usr/local/bin/$command | 	sed "s/management_command/$command/g" management_script.sh >"$PWD/rootfs/usr/local/bin/$command" | ||||||
| 	chmod +x /usr/local/bin/$command | 	chmod +x "$PWD/rootfs/usr/local/bin/$command" | ||||||
| done | done | ||||||
|   | |||||||
| @@ -1,17 +1,13 @@ | |||||||
| #!/usr/bin/env bash | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
| set -e | set -e | ||||||
|  |  | ||||||
| cd /usr/src/paperless/src/ | cd "${PAPERLESS_SRC_DIR}" | ||||||
| # This ensures environment is setup |  | ||||||
| # shellcheck disable=SC1091 |  | ||||||
| source /sbin/env-from-file.sh |  | ||||||
|  |  | ||||||
| if [[ $(id -u) == 0 ]] ; | if [[ $(id -u) == 0 ]]; then | ||||||
| then | 	s6-setuidgid paperless python3 manage.py management_command "$@" | ||||||
| 	gosu paperless python3 manage.py management_command "$@" | elif [[ $(id -un) == "paperless" ]]; then | ||||||
| elif [[ $(id -un) == "paperless" ]] ; |  | ||||||
| then |  | ||||||
| 	python3 manage.py management_command "$@" | 	python3 manage.py management_command "$@" | ||||||
| else | else | ||||||
| 	echo "Unknown user." | 	echo "Unknown user." | ||||||
|   | |||||||
| @@ -1,16 +0,0 @@ | |||||||
| #!/usr/bin/env bash |  | ||||||
|  |  | ||||||
| SUPERVISORD_WORKING_DIR="${PAPERLESS_SUPERVISORD_WORKING_DIR:-$PWD}" |  | ||||||
| rootless_args=() |  | ||||||
| if [ "$(id -u)" == "$(id -u paperless)" ]; then |  | ||||||
| 	rootless_args=( |  | ||||||
| 		--user |  | ||||||
| 		paperless |  | ||||||
| 		--logfile |  | ||||||
| 		"${SUPERVISORD_WORKING_DIR}/supervisord.log" |  | ||||||
| 		--pidfile |  | ||||||
| 		"${SUPERVISORD_WORKING_DIR}/supervisord.pid" |  | ||||||
| 	) |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| exec /usr/local/bin/supervisord -c /etc/supervisord.conf "${rootless_args[@]}" |  | ||||||
							
								
								
									
										8
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-complete/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-complete/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  | declare -r log_prefix="[init-complete]" | ||||||
|  | declare -r end_time=$(date +%s) | ||||||
|  | declare -r start_time=${PAPERLESS_START_TIME_S} | ||||||
|  |  | ||||||
|  | echo "${log_prefix} paperless-ngx docker container init completed in $(($end_time-$start_time)) seconds" | ||||||
|  | echo "${log_prefix} Starting services" | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-complete/type
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-complete/type
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-complete/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-complete/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-complete/run | ||||||
							
								
								
									
										44
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-custom-init/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										44
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-custom-init/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[custom-init]" | ||||||
|  |  | ||||||
|  | # Mostly borrowed from the LinuxServer.io base image | ||||||
|  | # https://github.com/linuxserver/docker-baseimage-ubuntu/tree/bionic/root/etc/cont-init.d | ||||||
|  | declare -r custom_script_dir="/custom-cont-init.d" | ||||||
|  |  | ||||||
|  | # Tamper checking. | ||||||
|  | # Don't run files which are owned by anyone except root | ||||||
|  | # Don't run files which are writeable by others | ||||||
|  | if [ -d "${custom_script_dir}" ]; then | ||||||
|  | 	if [ -n "$(/usr/bin/find "${custom_script_dir}" -maxdepth 1 ! -user root)" ]; then | ||||||
|  | 		echo "${log_prefix} **** Potential tampering with custom scripts detected ****" | ||||||
|  | 		echo "${log_prefix} **** The folder '${custom_script_dir}' must be owned by root ****" | ||||||
|  | 		exit 0 | ||||||
|  | 	fi | ||||||
|  | 	if [ -n "$(/usr/bin/find "${custom_script_dir}" -maxdepth 1 -perm -o+w)" ]; then | ||||||
|  | 		echo "${log_prefix} **** The folder '${custom_script_dir}' or some of contents have write permissions for others, which is a security risk. ****" | ||||||
|  | 		echo "${log_prefix} **** Please review the permissions and their contents to make sure they are owned by root, and can only be modified by root. ****" | ||||||
|  | 		exit 0 | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# Make sure custom init directory has files in it | ||||||
|  | 	if [ -n "$(/bin/ls --almost-all "${custom_script_dir}" 2>/dev/null)" ]; then | ||||||
|  | 		echo "${log_prefix} files found in ${custom_script_dir} executing" | ||||||
|  | 		# Loop over files in the directory | ||||||
|  | 		for SCRIPT in "${custom_script_dir}"/*; do | ||||||
|  | 			NAME="$(basename "${SCRIPT}")" | ||||||
|  | 			if [ -f "${SCRIPT}" ]; then | ||||||
|  | 				echo "${log_prefix} ${NAME}: executing..." | ||||||
|  | 				/command/with-contenv /bin/bash "${SCRIPT}" | ||||||
|  | 				echo "${log_prefix} ${NAME}: exited $?" | ||||||
|  | 			elif [ ! -f "${SCRIPT}" ]; then | ||||||
|  | 				echo "${log_prefix} ${NAME}: is not a file" | ||||||
|  | 			fi | ||||||
|  | 		done | ||||||
|  | 	else | ||||||
|  | 		echo "${log_prefix} no custom files found exiting..." | ||||||
|  | 	fi | ||||||
|  | else | ||||||
|  | 	echo "${log_prefix} ${custom_script_dir} doesn't exist, nothing to do" | ||||||
|  | fi | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-custom-init/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-custom-init/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-custom-init/run | ||||||
							
								
								
									
										30
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-env-file/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-env-file/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[env-init]" | ||||||
|  |  | ||||||
|  | echo "${log_prefix} Checking for environment from files" | ||||||
|  |  | ||||||
|  | if find /run/s6/container_environment/*"_FILE" -maxdepth 1 > /dev/null 2>&1; then | ||||||
|  | 	for FILENAME in /run/s6/container_environment/*; do | ||||||
|  | 		if [[ "${FILENAME##*/}" == PAPERLESS_*_FILE ]]; then | ||||||
|  | 			# This should have been named different.. | ||||||
|  | 			if [[ ${FILENAME} == "PAPERLESS_OCR_SKIP_ARCHIVE_FILE" || ${FILENAME} == "PAPERLESS_MODEL_FILE" ]]; then | ||||||
|  | 				continue | ||||||
|  | 			fi | ||||||
|  | 			SECRETFILE=$(cat "${FILENAME}") | ||||||
|  | 			# Check the file exists | ||||||
|  | 			if [[ -f ${SECRETFILE} ]]; then | ||||||
|  | 				# Trim off trailing _FILE | ||||||
|  | 				FILESTRIP=${FILENAME//_FILE/} | ||||||
|  | 				# Set environment variable | ||||||
|  | 				cat "${SECRETFILE}" > "${FILESTRIP}" | ||||||
|  | 				echo "${log_prefix} ${FILESTRIP##*/} set from ${FILENAME##*/}" | ||||||
|  | 			else | ||||||
|  | 				echo "${log_prefix} cannot find secret in ${FILENAME##*/}" | ||||||
|  | 			fi | ||||||
|  | 		fi | ||||||
|  | 	done | ||||||
|  | else | ||||||
|  | 		echo "${log_prefix} No *_FILE environment found" | ||||||
|  | fi | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-env-file/type
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-env-file/type
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-env-file/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-env-file/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-env-file/run | ||||||
							
								
								
									
										33
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-folders/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										33
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-folders/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[init-folders]" | ||||||
|  |  | ||||||
|  | declare -r export_dir="/usr/src/paperless/export" | ||||||
|  | declare -r data_dir="${PAPERLESS_DATA_DIR:-/usr/src/paperless/data}" | ||||||
|  | declare -r media_root_dir="${PAPERLESS_MEDIA_ROOT:-/usr/src/paperless/media}" | ||||||
|  | declare -r consume_dir="${PAPERLESS_CONSUMPTION_DIR:-/usr/src/paperless/consume}" | ||||||
|  | declare -r tmp_dir="${PAPERLESS_SCRATCH_DIR:=/tmp/paperless}" | ||||||
|  |  | ||||||
|  | echo "${log_prefix} Checking for folder existence" | ||||||
|  |  | ||||||
|  | for dir in \ | ||||||
|  | 	"${export_dir}" \ | ||||||
|  | 	"${data_dir}" "${data_dir}/index" \ | ||||||
|  | 	"${media_root_dir}" "${media_root_dir}/documents" "${media_root_dir}/documents/originals" "${media_root_dir}/documents/thumbnails" \ | ||||||
|  | 	"${consume_dir}" \ | ||||||
|  | 	"${tmp_dir}"; do | ||||||
|  | 	if [[ ! -d "${dir}" ]]; then | ||||||
|  | 		mkdir --parents --verbose "${dir}" | ||||||
|  | 	fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | echo "${log_prefix} Adjusting file and folder permissions" | ||||||
|  | for dir in \ | ||||||
|  | 	"${export_dir}" \ | ||||||
|  | 	"${data_dir}" \ | ||||||
|  | 	"${media_root_dir}" \ | ||||||
|  | 	"${consume_dir}" \ | ||||||
|  | 	"${tmp_dir}"; do | ||||||
|  | 	find "${dir}" -not \( -user paperless -and -group paperless \) -exec chown --changes paperless:paperless {} + | ||||||
|  | done | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-folders/type
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-folders/type
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-folders/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-folders/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-folders/run | ||||||
							
								
								
									
										20
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-migrations/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-migrations/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  | declare -r log_prefix="[init-migrations]" | ||||||
|  | declare -r data_dir="${PAPERLESS_DATA_DIR:-/usr/src/paperless/data}" | ||||||
|  |  | ||||||
|  | ( | ||||||
|  | 	# flock is in place to prevent multiple containers from doing migrations | ||||||
|  | 	# simultaneously. This also ensures that the db is ready when the command | ||||||
|  | 	# of the current container starts. | ||||||
|  | 	flock 200 | ||||||
|  | 	echo "${log_prefix} Apply database migrations..." | ||||||
|  | 	cd "${PAPERLESS_SRC_DIR}" | ||||||
|  |  | ||||||
|  | 	if [[ -n "${USER_IS_NON_ROOT}" ]]; then | ||||||
|  | 		exec python3 manage.py migrate --skip-checks --no-input | ||||||
|  | 	else | ||||||
|  | 		exec s6-setuidgid paperless python3 manage.py migrate --skip-checks --no-input | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | ) 200>"${data_dir}/migration_lock" | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-migrations/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-migrations/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-migrations/run | ||||||
							
								
								
									
										22
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-modify-user/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-modify-user/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  | declare -r log_prefix="[init-user]" | ||||||
|  |  | ||||||
|  | declare -r usermap_original_uid=$(id -u paperless) | ||||||
|  | declare -r usermap_original_gid=$(id -g paperless) | ||||||
|  | declare -r usermap_new_uid=${USERMAP_UID:-$usermap_original_uid} | ||||||
|  | declare -r usermap_new_gid=${USERMAP_GID:-${usermap_original_gid:-$usermap_new_uid}} | ||||||
|  |  | ||||||
|  | if [[ ${usermap_new_uid} != "${usermap_original_uid}" ]]; then | ||||||
|  | 	echo "${log_prefix} Mapping UID for paperless to $usermap_new_uid" | ||||||
|  | 	usermod --non-unique --uid "${usermap_new_uid}" paperless | ||||||
|  | else | ||||||
|  | 	echo "${log_prefix} No UID changes for paperless" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [[ ${usermap_new_gid} != "${usermap_original_gid}" ]]; then | ||||||
|  | 	echo "${log_prefix} Mapping GID for paperless to $usermap_new_gid" | ||||||
|  | 	groupmod --non-unique --gid "${usermap_new_gid}" paperless | ||||||
|  | else | ||||||
|  | 	echo "${log_prefix} No GID changes for paperless" | ||||||
|  | fi | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-modify-user/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-modify-user/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-modify-user/run | ||||||
							
								
								
									
										28
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-search-index/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-search-index/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[init-index]" | ||||||
|  |  | ||||||
|  | declare -r index_version=9 | ||||||
|  | declare -r data_dir="${PAPERLESS_DATA_DIR:-/usr/src/paperless/data}" | ||||||
|  | declare -r index_version_file="${data_dir}/.index_version" | ||||||
|  |  | ||||||
|  | update_index () { | ||||||
|  | 	echo "${log_prefix} Search index out of date. Updating..." | ||||||
|  | 	cd "${PAPERLESS_SRC_DIR}" | ||||||
|  | 	if [[ -n "${USER_IS_NON_ROOT}" ]]; then | ||||||
|  | 		python3 manage.py document_index reindex --no-progress-bar | ||||||
|  | 		echo ${index_version} | tee "${index_version_file}" > /dev/null | ||||||
|  | 	else | ||||||
|  | 		s6-setuidgid paperless python3 manage.py document_index reindex --no-progress-bar | ||||||
|  | 		echo ${index_version} | s6-setuidgid paperless tee "${index_version_file}" > /dev/null | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if [[ (! -f "${index_version_file}") ]]; then | ||||||
|  | 	echo "${log_prefix} No index version file found" | ||||||
|  | 	update_index | ||||||
|  | elif [[ $(<"${index_version_file}") != "$index_version" ]]; then | ||||||
|  | 	echo "${log_prefix} index version updated" | ||||||
|  | 	update_index | ||||||
|  | fi | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-search-index/run | ||||||
							
								
								
									
										19
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-start/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-start/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[init-start]" | ||||||
|  |  | ||||||
|  | echo "${log_prefix} paperless-ngx docker container starting..." | ||||||
|  |  | ||||||
|  | # Set some directories into environment for other steps to access via environment | ||||||
|  | # Sort of like variables for later | ||||||
|  | printf "/usr/src/paperless/src" > /var/run/s6/container_environment/PAPERLESS_SRC_DIR | ||||||
|  | echo $(date +%s) > /var/run/s6/container_environment/PAPERLESS_START_TIME_S | ||||||
|  |  | ||||||
|  | # Check if we're starting as a non-root user | ||||||
|  | if [ $(id -u) == $(id -u paperless) ]; then | ||||||
|  | 	printf "true" > /var/run/s6/container_environment/USER_IS_NON_ROOT | ||||||
|  | 	echo "${log_prefix}  paperless-ngx docker container running under a user" | ||||||
|  | else | ||||||
|  | 	echo "${log_prefix}  paperless-ngx docker container starting init as root" | ||||||
|  | fi | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-start/type
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-start/type
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-start/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-start/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-start/run | ||||||
							
								
								
									
										20
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-superuser/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-superuser/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[init-superuser]" | ||||||
|  |  | ||||||
|  | if [[ -n "${PAPERLESS_ADMIN_USER}" ]]; then | ||||||
|  | 	echo "${log_prefix} Creating superuser..." | ||||||
|  | 	cd "${PAPERLESS_SRC_DIR}" | ||||||
|  |  | ||||||
|  | 	if [[ -n "${USER_IS_NON_ROOT}" ]]; then | ||||||
|  | 		python3 manage.py manage_superuser | ||||||
|  | 	else | ||||||
|  | 		s6-setuidgid paperless python3 manage.py manage_superuser | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	echo "${log_prefix} Superuser creation done" | ||||||
|  |  | ||||||
|  | else | ||||||
|  | 	echo "${log_prefix} Not creating superuser" | ||||||
|  | fi | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-superuser/type
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-superuser/type
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-superuser/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-superuser/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-superuser/run | ||||||
							
								
								
									
										15
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-system-checks/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-system-checks/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[init-checks]" | ||||||
|  |  | ||||||
|  | # Explicitly run the Django system checks | ||||||
|  | echo "${log_prefix} Running Django checks" | ||||||
|  |  | ||||||
|  | cd "${PAPERLESS_SRC_DIR}" | ||||||
|  |  | ||||||
|  | if [[ -n "${USER_IS_NON_ROOT}" ]]; then | ||||||
|  | 	python3 manage.py check | ||||||
|  | else | ||||||
|  | 	s6-setuidgid paperless python3 manage.py check | ||||||
|  | fi | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-system-checks/run | ||||||
							
								
								
									
										65
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-tesseract-langs/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										65
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-tesseract-langs/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[init-tesseract-langs]" | ||||||
|  |  | ||||||
|  | install_languages() { | ||||||
|  | 	echo "Installing languages..." | ||||||
|  |  | ||||||
|  | 	read -ra langs <<<"$1" | ||||||
|  |  | ||||||
|  | 	# Check that it is not empty | ||||||
|  | 	if [ ${#langs[@]} -eq 0 ]; then | ||||||
|  | 		return | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# Build list of packages to install | ||||||
|  | 	to_install=() | ||||||
|  | 	for lang in "${langs[@]}"; do | ||||||
|  | 		pkg="tesseract-ocr-$lang" | ||||||
|  |  | ||||||
|  | 		if dpkg --status "$pkg" &>/dev/null; then | ||||||
|  | 			echo "${log_prefix} Package $pkg already installed!" | ||||||
|  | 			continue | ||||||
|  | 		else | ||||||
|  | 			to_install+=("$pkg") | ||||||
|  | 		fi | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | 	# Use apt only when we install packages | ||||||
|  | 	if [ ${#to_install[@]} -gt 0 ]; then | ||||||
|  |  | ||||||
|  | 		# Warn the user if they're not root, but try anyway | ||||||
|  | 		if [[ -n "${USER_IS_NON_ROOT}" ]]; then | ||||||
|  | 			echo "${log_prefix} ERROR: Unable to install language ${pkg} as non-root, startup may fail" | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		apt-get --quiet update &>/dev/null | ||||||
|  |  | ||||||
|  | 		for pkg in "${to_install[@]}"; do | ||||||
|  | 			if ! apt-cache --quiet show "$pkg" &>/dev/null; then | ||||||
|  | 				echo "${log_prefix} Skipped $pkg: Package not found! :(" | ||||||
|  | 				continue | ||||||
|  | 			fi | ||||||
|  | 			echo "${log_prefix} Installing package $pkg..." | ||||||
|  | 			if ! apt-get --quiet --assume-yes install "$pkg" &>/dev/null; then | ||||||
|  | 				echo "${log_prefix} Could not install $pkg" | ||||||
|  | 				exit 1 | ||||||
|  | 			else | ||||||
|  | 				echo "${log_prefix} Installed $pkg" | ||||||
|  | 			fi | ||||||
|  | 		done | ||||||
|  |  | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | echo "${log_prefix} Checking if additional teseract languages needed" | ||||||
|  |  | ||||||
|  | # Install additional languages if specified | ||||||
|  | if [[ -n "$PAPERLESS_OCR_LANGUAGES" ]]; then | ||||||
|  |  | ||||||
|  | 	install_languages "$PAPERLESS_OCR_LANGUAGES" | ||||||
|  | 	echo "${log_prefix} Additional packages installed" | ||||||
|  | else | ||||||
|  | 	echo "${log_prefix} No additional installs requested" | ||||||
|  | fi | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-tesseract-langs/run | ||||||
							
								
								
									
										70
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-db/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										70
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-db/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[init-db-wait]" | ||||||
|  |  | ||||||
|  | wait_for_postgres() { | ||||||
|  | 	local attempt_num=1 | ||||||
|  | 	local -r max_attempts=5 | ||||||
|  |  | ||||||
|  | 	echo "${log_prefix} Waiting for PostgreSQL to start..." | ||||||
|  |  | ||||||
|  | 	local -r host="${PAPERLESS_DBHOST:-localhost}" | ||||||
|  | 	local -r port="${PAPERLESS_DBPORT:-5432}" | ||||||
|  | 	local -r user="${PAPERLESS_DBUSER:-paperless}" | ||||||
|  |  | ||||||
|  | 	# Disable warning, host and port can't have spaces | ||||||
|  | 	# shellcheck disable=SC2086 | ||||||
|  | 	while [ ! "$(pg_isready -h ${host} -p ${port} --username ${user})" ]; do | ||||||
|  |  | ||||||
|  | 		if [ $attempt_num -eq $max_attempts ]; then | ||||||
|  | 			echo "${log_prefix} Unable to connect to database." | ||||||
|  | 			exit 1 | ||||||
|  | 		else | ||||||
|  | 			echo "${log_prefix} Attempt $attempt_num failed! Trying again in 5 seconds..." | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		attempt_num=$(("$attempt_num" + 1)) | ||||||
|  | 		sleep 5 | ||||||
|  | 	done | ||||||
|  | 	# Extra in case this is a first start | ||||||
|  | 	sleep 5 | ||||||
|  | 	echo "Connected to PostgreSQL" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | wait_for_mariadb() { | ||||||
|  | 	echo "${log_prefix} Waiting for MariaDB to start..." | ||||||
|  |  | ||||||
|  | 	local -r host="${PAPERLESS_DBHOST:=localhost}" | ||||||
|  | 	local -r port="${PAPERLESS_DBPORT:=3306}" | ||||||
|  |  | ||||||
|  | 	local attempt_num=1 | ||||||
|  | 	local -r max_attempts=5 | ||||||
|  |  | ||||||
|  | 	# Disable warning, host and port can't have spaces | ||||||
|  | 	# shellcheck disable=SC2086 | ||||||
|  | 	while ! true > /dev/tcp/$host/$port; do | ||||||
|  |  | ||||||
|  | 		if [ $attempt_num -eq $max_attempts ]; then | ||||||
|  | 			echo "${log_prefix} Unable to connect to database." | ||||||
|  | 			exit 1 | ||||||
|  | 		else | ||||||
|  | 			echo "${log_prefix} Attempt $attempt_num failed! Trying again in 5 seconds..." | ||||||
|  |  | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		attempt_num=$(("$attempt_num" + 1)) | ||||||
|  | 		sleep 5 | ||||||
|  | 	done | ||||||
|  | 	echo "Connected to MariaDB" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if [[ "${PAPERLESS_DBENGINE}" == "mariadb" ]]; then | ||||||
|  | 	echo "${log_prefix} Waiting for MariaDB to report ready" | ||||||
|  | 	wait_for_mariadb | ||||||
|  | elif [[ -n "${PAPERLESS_DBHOST}" ]]; then | ||||||
|  | 	echo "${log_prefix} Waiting for postgresql to report ready" | ||||||
|  | 	wait_for_postgres | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | 	echo "${log_prefix} Database is ready" | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-db/up
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-db/up
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-wait-for-db/run | ||||||
							
								
								
									
										14
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-redis/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/init-wait-for-redis/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[init-redis-wait]" | ||||||
|  |  | ||||||
|  | echo "${log_prefix} Waiting for Redis to report ready" | ||||||
|  |  | ||||||
|  | # We use a Python script to send the Redis ping | ||||||
|  | # instead of installing redis-tools just for 1 thing | ||||||
|  | if ! python3 /usr/local/bin/wait-for-redis.py; then | ||||||
|  | 	exit 1 | ||||||
|  | else | ||||||
|  | 	echo "${log_prefix} Redis ready" | ||||||
|  | fi | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | oneshot | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | /etc/s6-overlay/s6-rc.d/init-wait-for-redis/run | ||||||
							
								
								
									
										18
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/svc-consumer/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/svc-consumer/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  |  | ||||||
|  | if [[ -n "${PAPERLESS_CONSUMER_DISABLE}" ]]; then | ||||||
|  | 	echo "[svc-consumer] Consumer is disabled, exiting" | ||||||
|  | 	# https://skarnet.org/software/s6/s6-svc.html | ||||||
|  | 	s6-svc -Od . | ||||||
|  |  | ||||||
|  | else | ||||||
|  | 	cd ${PAPERLESS_SRC_DIR} | ||||||
|  |  | ||||||
|  | 	if [[ -n "${USER_IS_NON_ROOT}" ]]; then | ||||||
|  | 		exec python3 manage.py document_consumer | ||||||
|  | 	else | ||||||
|  | 		exec s6-setuidgid paperless python3 manage.py document_consumer | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/svc-consumer/type
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/svc-consumer/type
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | longrun | ||||||
							
								
								
									
										24
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/svc-flower/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/svc-flower/run
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | #!/command/with-contenv /usr/bin/bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | declare -r log_prefix="[svc-flower]" | ||||||
|  |  | ||||||
|  | echo "${log_prefix} Checking if we should start flower..." | ||||||
|  |  | ||||||
|  | if [[ -n "${PAPERLESS_ENABLE_FLOWER}" ]]; then | ||||||
|  | 	# Small delay to allow celery to be up first | ||||||
|  | 	echo "${log_prefix} Starting flower in 5s" | ||||||
|  | 	sleep 5 | ||||||
|  | 	cd ${PAPERLESS_SRC_DIR} | ||||||
|  |  | ||||||
|  | 	if [[ -n "${USER_IS_NON_ROOT}" ]]; then | ||||||
|  | 		exec /usr/local/bin/celery --app paperless flower --conf=${PAPERLESS_SRC_DIR}/paperless/flowerconfig.py | ||||||
|  | 	else | ||||||
|  | 		exec s6-setuidgid paperless /usr/local/bin/celery --app paperless flower --conf=${PAPERLESS_SRC_DIR}/paperless/flowerconfig.py | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | else | ||||||
|  | 	echo "${log_prefix} Not starting flower" | ||||||
|  | 	# https://skarnet.org/software/s6/s6-svc.html | ||||||
|  | 	s6-svc -Od . | ||||||
|  | fi | ||||||
							
								
								
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/svc-flower/type
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/svc-flower/type
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | longrun | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user