User Tools

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:install_paperless-ngx_on_debian_without_docker [2026-08-17 19:17] – iacchien:install_paperless-ngx_on_debian_without_docker [2026-09-02 10:45] (current) – iacchi
Line 1: Line 1:
 ====== Install paperless-ngx on Debian without Docker ====== ====== Install paperless-ngx on Debian without Docker ======
  
-Caveat: this guide assumes a non-Raspberry pi machine, and SQLite as database (which is ok for small installations).+Caveat: this guide assumes a non-Raspberry pi machine, and SQLite as database (which is ok for small installations). The service will be behind an Nginx proxy.
  
 ===== Install dependencies and configure the system ===== ===== Install dependencies and configure the system =====
  
-First, we'll need to install all required dependencies:+First, we'll need to install all required dependencies (there are also dependencies for MariaDB and PostgreSQL; even if we won't use them, not installing them would require to edit the requirements.txt file later, which I don't want to do just in case it breaks something):
  
 <code bash> <code bash>
-apt install valkey-server python3 python3-pip python3-dev fonts-liberation imagemagick libmagic-dev poppler-utils build-essential python3-setuptools python3-wheel +apt install valkey-server python3 python3-pip python3-dev fonts-liberation imagemagick libmagic-dev poppler-utils build-essential python3-setuptools python3-wheel python3-venv pkg-config default-libmysqlclient-dev libpq-dev 
 </code> </code>
  
Line 32: Line 32:
 cd /opt/paperless cd /opt/paperless
 sudo -u paperless wget https://github.com/paperless-ngx/paperless-ngx/releases/download/vx.x.x/paperless-ngx-vx.x.x.tar.xz sudo -u paperless wget https://github.com/paperless-ngx/paperless-ngx/releases/download/vx.x.x/paperless-ngx-vx.x.x.tar.xz
-sudo -u paperless tar -xf paperless-ngx-vx.x.x.tar.xz+sudo -u paperless tar xf paperless-ngx-vx.x.x.tar.xz
 mv paperless-ngx/* . mv paperless-ngx/* .
 mv paperless-ngx/.* . mv paperless-ngx/.* .
 +rmdir paperless-ngx
 +rm paperless-ngx-vx.x.x.tar.x
 </code> </code>
  
Line 45: Line 47:
 PAPERLESS_DATA_DIR PAPERLESS_DATA_DIR
 PAPERLESS_MEDIA_ROOT # If needed it can be the same directory as PAPERLESS_DATA_DIR PAPERLESS_MEDIA_ROOT # If needed it can be the same directory as PAPERLESS_DATA_DIR
-PAPERLESS_STATICDIR+PAPERLESS_STATICDIR=../static
 PAPERLESS_SECRET_KEY PAPERLESS_SECRET_KEY
 PAPERLESS_URL PAPERLESS_URL
 PAPERLESS_OCR_LANGUAGE PAPERLESS_OCR_LANGUAGE
 PAPERLESS_TIME_ZONE PAPERLESS_TIME_ZONE
 +PAPERLESS_USE_X_FORWARD_HOST=true
 +PAPERLESS_USE_X_FORWARD_PORT=true
 +PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]'
 </code> </code>
  
-Make sure you create the folders you have assigned in the config file and chown them to the paperless:paperless user and group.+Make sure you create the folders you have assigned in the config file and chown them to the paperless:paperless user and group. To install all the required python packages with pip (Debian doesn't have a lot of them in its repo, plus specific versions are required) it is necessary to create a python virtual environment owned by the user paperless. It will then be possible to install the packages:
  
 <code bash> <code bash>
 +sudo -u paperless makedir venv
 +sudo -u paperless python3 -m venv venv
 +sudo -u paperless venv/bin/pip3 install -r requirements.txt
 +</code>
  
 +Time to populate the database:
 +
 +<code bash>
 +cd src
 +sudo -u paperless ../venv/bin/python3 manage.py migrate
 </code> </code>
  
 +As a last installation step, something undocumented on paperless-ngx's documentation: to enable better document search (which I believe is active by default), we need to download some more python packages. First of all, enable this feature explicitly in ''paperless.conf'':
  
 +<code>
 +PAPERLESS_ENABLE_NLTK=true
 +PAPERLESS_NLTK_DIR=/opt/paperless/nltk_data
 +</code>
 +
 +Then, download the required packages:
  
 <code bash> <code bash>
 +cd /opt/paperless
 +sudo -u paperless venv/bin/python3 -m nltk.downloader  punkt_tab
 +sudo -u paperless venv/bin/python3 -m nltk.downloader  punkt
 +sudo -u paperless venv/bin/python3 -m nltk.downloader  stopwords
 +</code>
  
 +Before testing the server to see if it works, we need to temporarily enable debug mode. Add ''PAPERLESS_DEBUG=true'' to ''paperless.conf'', then run:
 +
 +<code bash>
 +cd src
 +sudo -u paperless ../venv/bin/python3 manage.py runserver
 </code> </code>
  
 +It's now time to set up all the systemd services. Script examples are in the ''script'' folder and we're going to edit those and link them to the systemd folder.
  
 +paperless-consumer.service
 +<code>
 +[Unit]
 +Description=Paperless consumer
 +Requires=redis.service
  
-<code bash>+[Service] 
 +User=paperless 
 +Group=paperless 
 +WorkingDirectory=/opt/paperless/src 
 +ExecStart=/opt/paperless/venv/bin/python3 manage.py document_consumer
  
 +[Install]
 +WantedBy=multi-user.target
 </code> </code>
  
 +paperless-scheduler.service
 +<code>
 +[Unit]
 +Description=Paperless Celery Beat
 +Requires=redis.service
  
 +[Service]
 +User=paperless
 +Group=paperless
 +WorkingDirectory=/opt/paperless/src
 +ExecStart=/opt/paperless/venv/bin/celery --app paperless beat --loglevel INFO
  
-<code bash>+[Install] 
 +WantedBy=multi-user.target 
 +</code> 
 + 
 +paperless-task-queue.service 
 +<code> 
 +[Unit] 
 +Description=Paperless Celery Workers 
 +Requires=redis.service 
 + 
 +[Service] 
 +User=paperless 
 +Group=paperless 
 +WorkingDirectory=/opt/paperless/src 
 +ExecStart=/opt/paperless/venv/bin/celery --app paperless worker --loglevel INFO
  
 +[Install]
 +WantedBy=multi-user.target
 </code> </code>
  
 +paperless-webserver.service
 +<code>
 +[Unit]
 +Description=Paperless webserver
 +After=network.target
 +Wants=network.target
 +Requires=valkey.service
 +#Requires=paperless-webserver.socket
  
 +[Service]
 +User=paperless
 +Group=paperless
 +WorkingDirectory=/opt/paperless/src
  
-<code bash>+Environment=GRANIAN_HOST=:: 
 +Environment=GRANIAN_PORT=8000 
 +Environment=GRANIAN_WORKERS=1 
 + 
 +ExecStart=/bin/sh -c '\ 
 +  # Host: GRANIAN_HOST -> PAPERLESS_BIND_ADDR -> default \ 
 +  [ -n "$PAPERLESS_BIND_ADDR" ] && export GRANIAN_HOST=$PAPERLESS_BIND_ADDR; \ 
 +  # Port: GRANIAN_PORT -> PAPERLESS_PORT -> default \ 
 +  [ -n "$PAPERLESS_PORT" ] && export GRANIAN_PORT=$PAPERLESS_PORT; \ 
 +  # Workers: GRANIAN_WORKERS -> PAPERLESS_WEBSERVER_WORKERS -> default \ 
 +  [ -n "$PAPERLESS_WEBSERVER_WORKERS" ] && export GRANIAN_WORKERS=$PAPERLESS_WEBSERVER_WORKERS; \ 
 +  # URL path prefix: only set if PAPERLESS_FORCE_SCRIPT_NAME exists \ 
 +  [ -n "$PAPERLESS_FORCE_SCRIPT_NAME" ] && export GRANIAN_URL_PATH_PREFIX=$PAPERLESS_FORCE_SCRIPT_NAME; \ 
 +  exec /opt/paperless/venv/bin/granian --interface asginl --ws --loop uvloop "paperless.asgi:application"'
  
 +[Install]
 +WantedBy=multi-user.target
 </code> </code>
  
 +Now that we have the unit files ready, we need to enable and start them:
  
 <code bash> <code bash>
 +cd scripts
 +systemctl enable paperless-task-queue.service
 +systemctl enable paperless-scheduler.service
 +systemctl enable paperless-consumer.service
 +systemctl enable paperless-server.service
 +systemctl start paperless-task-queue.service
 +systemctl start paperless-scheduler.service
 +systemctl start paperless-consumer.service
 +systemctl start paperless-server.service
 +</code>
  
 +All that is left to do now is configure the Nginx reverse proxy:
 +
 +<code bash>
 +cd /etc/nginx/sites-available/
 +nano docs.mydomain.tld
 </code> </code>
  
 +This is the content of the docs.mydomain.tld file:
  
 +<code>
 +server {
 +    listen 443 ssl;
 +    listen [::]:443 ssl;
 +    http2 on;
 +    ssl_certificate     /path/to/cert.crt;
 +    ssl_certificate_key /path/to/cert.key;
 +    server_name docs.mydomain.tld;
 +    access_log /var/log/nginx/docs.mydomain.tld-access.log;
 +    error_log  /var/log/nginx/docs.mydomain.tld-error.log;
 +    client_max_body_size 20M;
  
-<code bash>+    large_client_header_buffers 4 8k; 
 +    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"; 
 +    add_header X-Content-Type-Options nosniff; 
 +    add_header X-XSS-Protection "1; mode=block"; 
 +    add_header X-Robots-Tag none; 
 +    add_header X-Download-Options noopen; 
 +    add_header X-Permitted-Cross-Domain-Policies none;
  
 +    location = /accounts/login/ {
 +        proxy_pass http://localhost:8000;
 +        proxy_http_version 1.1;
 +        proxy_set_header Upgrade $http_upgrade;
 +        proxy_set_header Connection "upgrade";
 +        proxy_redirect off;
 +        proxy_set_header Host $host:$server_port;
 +        proxy_set_header X-Real-IP $remote_addr;
 +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 +        proxy_set_header X-Forwarded-Host $server_name;
 +        proxy_set_header X-Forwarded-Proto $scheme;
 +        proxy_hide_header Referrer-Policy;
 +        add_header Referrer-Policy "same-origin" always;
 +    }
 +
 +    location / {
 +        proxy_pass http://localhost:8000;
 +        proxy_http_version 1.1;
 +        proxy_set_header Upgrade $http_upgrade;
 +        proxy_set_header Connection "upgrade";
 +        proxy_redirect off;
 +        proxy_set_header Host $host;
 +        proxy_set_header X-Real-IP $remote_addr;
 +        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 +        proxy_set_header X-Forwarded-Host $server_name;
 +        proxy_set_header X-Forwarded-Proto $scheme;
 +        proxy_hide_header Referrer-Policy;
 +        add_header Referrer-Policy "no-referrer" always;
 +    }
 +}
 </code> </code>
  
 +And now it's time to enable the configuration:
  
 <code bash> <code bash>
 +ln -s /etc/nginx/sites-available/docs.mydomain.tld /etc/nginx/sites-enabled/ 
 +systemctl restart nginx
 </code> </code>
  
 +===== Updating paperless-ngx =====
  
 +Paperless-ngx's documentation suggests to delete almost all previous files and copy the new ones in place, so we'll do just that. Before starting, we backup the current folder for safety purposes, and we stop all paperless services. Here is the sequence of commands:
  
 <code bash> <code bash>
 +systemctl stop paperless-consumer paperless-scheduler paperless-task-queue paperless-webserver
 +cd /opt
 +cp -R paperless paperless.bak
 +wget https://github.com/paperless-ngx/paperless-ngx/releases/download/vx.x.x/paperless-ngx-vx.x.x.tar.xz
 +tar xf paperless-ngx-vx.x.x.tar.xz
 +chown -R paperless:paperless paperless.bak paperless-ngx
 +</code>
  
 +At this point it's good to stop for a second and check that the systemd unit files in the ''scripts'' directory have not changed, so that we can keep the old ones, or modify them accordingly. Once done with the check, it's time for the update. From the original installation we need to keep the ''.env'', ''paperless.conf'', ''scripts'', and ''venv'' files and folders, so we'll delete everything but those (and of course we'll remove just those from the directory of the new version):
 +
 +<code bash>
 +cd /opt/paperless
 +rm -r `ls -a | grep -v ".env\|paperless.conf\|scripts\|venv"`
 +cd /opt/paperless-ngx
 +rm -r .env paperless.conf scripts
 +mv ./* ../paperless
 </code> </code>
  
 +Now, with all the files in place, we update the python dependencies. In principle we should also manually remove all dependencies that are no longer required, but meh, we'll think about it if errors occur.
  
 +<code bash>
 +cd /opt/paperless
 +sudo -u paperless venv/bin/pip3 install -r requirements.txt
 +cd src
 +sudo -u paperless ../venv/bin/python3 manage.py migrate  # (1)
 +sudo -u paperless ../venv/bin/python3 manage.py document_index reindex --if-needed
 +sudo -u paperless ../venv/bin/python3 manage.py document_llmindex migrate
 +</code>
 +
 +It is now possible to restart the services.
  
 <code bash> <code bash>
 +systemctl start paperless-consumer paperless-scheduler paperless-task-queue paperless-webserver
 +</code>
  
 +If everything works, we can clean up:
 +
 +<code bash>
 +cd /opt
 +rm -R paperless.bak paperless-ngx
 </code> </code>