Files
ProxmoxVE/install/paperless-ngx-install.sh
T
CanbiZ (MickLesk) 54c8b2393e install: answer every prompt from the environment, survive a closed stdin (#18121)
* install: answer every prompt from the environment, survive a closed stdin

Every interactive prompt takes a var_<app>_<name> override and treats a
closed stdin like Enter (`|| true`), so an install keeps going after the
console that started it is gone. Values the script cannot do without end
with exit 64 and name the variable to set. Validation loops stop asking
when nobody can answer instead of spinning on an empty read.

* mongodb, paperless-gpt: accept yes as well as y
2026-10-24 17:55:50 +02:00

183 lines
5.3 KiB
Bash

#!/usr/bin/env bash
# Copyright (c) 2021-2026 tteck
# Author: tteck (tteckster) | MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://docs.paperless-ngx.com/ | Github: https://github.com/paperless-ngx/paperless-ngx
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies (Patience)"
$STD apt install -y \
redis \
build-essential \
imagemagick \
fonts-liberation \
gnupg \
optipng \
libpq-dev \
libmagic-dev \
poppler-utils \
default-libmysqlclient-dev \
automake \
libtool \
pkg-config \
libtiff-dev \
libpng-dev \
libleptonica-dev \
unpaper \
icc-profiles-free \
qpdf \
libleptonica6 \
libxml2 \
pngquant \
zlib1g \
tesseract-ocr \
tesseract-ocr-eng \
ghostscript
msg_ok "Installed Dependencies"
PG_VERSION="18" setup_postgresql
PG_DB_NAME="paperlessdb" PG_DB_USER="paperless" setup_postgresql_db
fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
PYTHON_VERSION="3.13" UV_PROJECT_DIR="/opt/paperless" setup_uv
msg_info "Setup Paperless-ngx"
cd /opt/paperless
rm -rf /opt/paperless/docker
$STD uv sync --all-extras
mkdir -p /opt/paperless_data/{consume,data,media,trash}
mkdir -p /opt/paperless/static
SECRET_KEY="$(random_password 32)"
cat <<EOF >~/paperless-ngx.creds
Paperless-ngx Secret Key: $SECRET_KEY
Paperless-ngx WebUI User: admin
Paperless-ngx WebUI Password: $PG_DB_PASS
EOF
sed -i \
-e 's|#PAPERLESS_REDIS=redis://localhost:6379|PAPERLESS_REDIS=redis://localhost:6379|' \
-e "s|#PAPERLESS_CONSUMPTION_DIR=../consume|PAPERLESS_CONSUMPTION_DIR=/opt/paperless_data/consume|" \
-e "s|#PAPERLESS_DATA_DIR=../data|PAPERLESS_DATA_DIR=/opt/paperless_data/data|" \
-e "s|#PAPERLESS_MEDIA_ROOT=../media|PAPERLESS_MEDIA_ROOT=/opt/paperless_data/media|" \
-e "s|#PAPERLESS_EMPTY_TRASH_DIR=|PAPERLESS_EMPTY_TRASH_DIR=/opt/paperless_data/trash|" \
-e "s|#PAPERLESS_STATICDIR=../static|PAPERLESS_STATICDIR=/opt/paperless/static|" \
-e 's|#PAPERLESS_DBHOST=localhost|PAPERLESS_DBENGINE=postgresql\nPAPERLESS_DBHOST=localhost|' \
-e 's|#PAPERLESS_DBPORT=5432|PAPERLESS_DBPORT=5432|' \
-e "s|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=$PG_DB_NAME|" \
-e "s|#PAPERLESS_DBUSER=paperless|PAPERLESS_DBUSER=$PG_DB_USER|" \
-e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$PG_DB_PASS|" \
-e "s|PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" \
/opt/paperless/paperless.conf
cd /opt/paperless/src
set -a
. /opt/paperless/paperless.conf
set +a
$STD uv run -- python manage.py migrate
msg_ok "Setup Paperless-ngx"
msg_info "Setting up admin Paperless-ngx User & Password"
cat <<EOF | uv run -- python /opt/paperless/src/manage.py shell
from django.contrib.auth import get_user_model
UserModel = get_user_model()
user = UserModel.objects.create_user('admin', password='$PG_DB_PASS')
user.is_superuser = True
user.is_staff = True
user.save()
EOF
msg_ok "Set up admin Paperless-ngx User & Password"
setup_nltk "snowball_data stopwords punkt_tab" "/usr/share/nltk_data"
for policy_file in /etc/ImageMagick-6/policy.xml /etc/ImageMagick-7/policy.xml; do
if [[ -f "$policy_file" ]]; then
sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' "$policy_file"
fi
done
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/paperless-scheduler.service
[Unit]
Description=Paperless Celery beat
Requires=redis.service
[Service]
WorkingDirectory=/opt/paperless/src
ExecStart=uv run --no-sync -- celery --app paperless beat --loglevel INFO
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/paperless-task-queue.service
[Unit]
Description=Paperless Celery Workers
Requires=redis.service
After=postgresql.service
[Service]
WorkingDirectory=/opt/paperless/src
ExecStart=uv run --no-sync -- celery --app paperless worker --loglevel INFO
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/paperless-consumer.service
[Unit]
Description=Paperless consumer
Requires=redis.service
[Service]
WorkingDirectory=/opt/paperless/src
ExecStartPre=/bin/sleep 2
ExecStart=uv run --no-sync -- python manage.py document_consumer
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/paperless-webserver.service
[Unit]
Description=Paperless webserver
After=network.target
Wants=network.target
Requires=redis.service
[Service]
WorkingDirectory=/opt/paperless/src
#ExecStartPre=uv run --no-sync -- python manage.py document_index reindex --if-needed --no-progress-bar
ExecStart=uv run --no-sync -- granian --interface asginl --ws --loop uvloop "paperless.asgi:application"
Restart=on-failure
RestartSec=5
Environment=GRANIAN_HOST=::
Environment=GRANIAN_PORT=8000
Environment=GRANIAN_WORKERS=1
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now paperless-webserver paperless-scheduler paperless-task-queue paperless-consumer
msg_ok "Created Services"
prompt="${var_paperless_ngx_adminer:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Adminer? <y/N> " prompt || true
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
setup_adminer
fi
motd_ssh
customize
cleanup_lxc