How to Install Paperless with Nginx on Debian
Paperless is a Python application that ingests scanned documents, indexes them, and presents them in a user-friendly web interface. In this tutorial, we will be installing Paperless with an Nginx HTTPS reverse proxy on Debian 10.
Requirements
- A Debian 10 system on which you have root access.
- A registered domain name is pointing to your server.
All commands shown in this document should be executed as root unless indicated otherwise.
Set the $VISUAL environment variable to a text editor of your choice. For example, to use nano:
echo "export VISUAL=nano" >> ~/.bashrc . ~/.bashrc
Step 1: Installing Dependencies
Paperless requires several software components for its installation and operation. Install them as follows:
apt update apt install -y gnupg2 python3 python3-dev python3-pip python3-virtualenv tesseract-ocr tesseract-ocr-eng unpaper imagemagick libpoppler-cpp-dev optipng git gcc g++
If you're going to be working with documents in languages other than english, install the matching Tesseract language files. For example, for french and spanish:
apt install -y tesseract-ocr-fra tesseract-ocr-spa
You can list all available tesseract packages using:
apt list tesseract-ocr-*
If you're unsure which 3-letter code corresponds to the desired language, refer to this ISO 639-2 Code List.
Step 2: Creating a System User
While it is possible to run paperless as root, using a user with low privileges and disabled login is strongly recommended. Create a user and group named paperless:
useradd -d /opt/paperless -M -r -s /bin/bash -U -p x paperless
Step 3: Installing Paperless
Clone the Paperless Github repository to /opt/paperless
git clone https://github.com/the-paperless-project/paperless.git /opt/paperless
Give the paperless user ownership of that directory:
chown -R paperless:paperless /opt/paperless
Copy the included configuration sample as a starting point:
cp /opt/paperless/paperless.conf.example /etc/paperless.conf
And open it in your text editor:
$VISUAL /etc/paperless.conf
Choose a directory from which Paperless will ingest scanned documents and set the PAPERLESS_CONSUMPTION_DIR parameter accordingly:
PAPERLESS_CONSUMPTION_DIR="/opt/paperless/paper_in"
Find, uncomment (by removing the # character) and change the values of the following lines to something secure:
#PAPERLESS_PASSPHRASE="secret" #PAPERLESS_SECRET_KEY="change-me"
If your scanner supports emailing scanned documents, you can have paperless ingest them from the receiving inbox automatically. To enable this feature, set the PAPERLESS_CONSUME_MAIL_* options. For security reasons, creating a mail account dedicated to Paperless is recommended. For example:
PAPERLESS_CONSUME_MAIL_HOST="imap.example.com" PAPERLESS_CONSUME_MAIL_PORT="993" PAPERLESS_CONSUME_MAIL_USER="[email protected]" PAPERLESS_CONSUME_MAIL_PASS="imap_password"
Save your changes and exit, then change the owner of this file to paperless and tighten its permissions:
chown paperless:paperless /etc/paperless.conf chmod 0400 /etc/paperless.conf
Switch to the paperless user:
su - paperless
Create the consumption directory:
mkdir /opt/paperless/paper_in
Create a python virtual environment. This will provide a stable and isolated environment where we can install the specific python modules and versions required by Paperless.
python3 -m virtualenv --python=/usr/bin/python3 venv
Activate it:
. venv/bin/activate
Install the python modules required by paperless:
pip3 install -r requirements.txt
This command may take a while. Once it finishes, run the following commands to initialize the database and create the static files for the web service:
cd src/ ./manage.py migrate ./manage.py collectstatic
Create login credentials for the web interface administrator account by running the following command and answering the prompts:
./manage.py createsuperuser
Step 4: Initial Testing
Before setting up a proper web server and systemd services, we'll try running paperless manually. At this point, you should still be logged in as the paperless in the virtual python environment.
Start the web server and document consumer in the background:
./manage.py runserver 0.0.0.0:8000 & ./manage.py document_consumer &
Place any scanned document in the consumption directory configured in Step 3. For example:
wget https://i.imgur.com/DPr5wWG.jpg -O /opt/paperless/paper_in/test1.jpg
Browse to http://IP_or_DOMAIN:8000/ and login with the credentials chosen in Step 3. In the "DOCUMENTS" menu, click on "Documents" to view the document list. Within a few minutes, the scanned document should be processed and available.
Stop paperless before proceeding to the next step:
pkill -f manage.py
Step 5: Systemd Services
We'll create systemd unit files so we can properly manage the web and consumer services. Exit back to your root shell:
exit
Create a unit file for the web service:
$VISUAL /etc/systemd/system/paperless-webserver.service
And enter the following:
[Unit] Description=Paperless Gunicorn Web Server Requires=network.target [Service] User=paperless Group=paperless ExecStart=/opt/paperless/venv/bin/gunicorn --pythonpath=/opt/paperless/src paperless.wsgi -w 3 -b 127.0.0.1:8000 Restart=on-failure [Install] WantedBy=multi-user.target
NOTE: You may want to modify the number of worker processes in the ExecStart command. The service shown here starts Gunicorn with 3 workers (-w 3).
Next, create another unit file for the document consumer process:
$VISUAL /etc/systemd/system/paperless-consumer.service
And enter the following:
[Unit] Description=Paperless Document Consumer Requires=network.target [Service] User=paperless Group=paperless ExecStart=/opt/paperless/venv/bin/python3 /opt/paperless/src/manage.py document_consumer Restart=on-failure [Install] WantedBy=multi-user.target
Start these services:
systemctl daemon-reload systemctl start paperless-webserver.service paperless-consumer.service
Make sure both of them are running:
systemctl status paperless-webserver.service paperless-consumer.service
If you'd like paperless to start automatically at system startup, execute the command:
systemctl enable paperless-webserver.service paperless-consumer.service
Step 6: Nginx Reverse Proxy and HTTPS
Install Nginx and certbot:
apt update apt install -y nginx certbot
Ensure Nginx is enabled and running:
systemctl enable --now nginx.service
Obtain a Let's Encrypt certificate for your domain with certbot:
certbot certonly --webroot --webroot-path /var/www/html -d your_domain
Disable the default Nginx configuration file and open a new one:
rm /etc/nginx/sites-enabled/default $VISUAL /etc/nginx/sites-available/paperless
Input the following, replace your_domain with your domain name:
server { listen 80; server_name your_domain; return 301 https://$server_name$request_uri; access_log /var/log/nginx/paperless_access.log; error_log /var/log/nginx/paperless_error.log; } server { listen 443 ssl; server_name your_domain; index index.html index.htm index.php; access_log /var/log/nginx/paperless_access.log; error_log /var/log/nginx/paperless_error.log; ssl on; ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem; location /static { autoindex on; alias /opt/paperless/static; } location / { proxy_set_header Host $http_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-Proto $scheme; proxy_pass http://127.0.0.1:8000; } }
Enable this configuration by linking to it in the sites-enabled Nginx directory, and check for any errors:
ln -s /etc/nginx/sites-available/paperless /etc/nginx/sites-enabled nginx -t
Then load the changes:
systemctl reload nginx.service
Your Paperless instance should now be accessible at https://your_domain.
Step 7: Enhancements
Since the paperless system user doesn't need access to a working shell after the initial setup, we can change it to /usr/sbin/nologin:
usermod -s /usr/sbin/nologin paperless
Troubleshooting
If the Gunicorn webserver fails to start with the error message [ERROR] Connection in use, check for any processes already bound to port 8000/tcp:
ss -lntp
Kill/Disable the offending process if necessary, or modify /etc/systemd/system/paperless-webserver.service and /etc/nginx/sites-enabled/paperless to use another network port for Gunicorn.