PdfDing is a PDF manager and viewer that you can host yourself. It offers a seamless user experience on multiple devices. It's designed be to be minimal, fast, and easy to set up using Docker. As all data stays on your server you have full control over your data and privacy.
With its simple, intuitive and adjustable UI, PdfDing makes it easy for users to keep track of their PDFs and access them whenever they need to. With a dark mode and colored themes users can style the app to their liking. As PdfDing offers SSO support via OIDC it can be easily integrated into existing setups.
The name is a combination of PDF and ding. Ding is the German word for thing. Thus, PdfDing is a thing for your PDFs. The name and the design of PdfDing are inspired by linkding. Linkding is an excellent selfhostable bookmark manager. If you are unfamiliar with it be sure to check it out!
More screenshots can be found here.
I started developing PdfDing as I was searching for a solution for viewing and managing PDF files. I had a few simple requirements:
I was quite surprised to find out that there was no app matching my simple requirements. While there were some existing solutions they still had some problems:
Thus, I am developing PDfDing as a simple webapp with a clear focus on a single thing: viewing and managing PDFs.
PdfDing is designed to be run with container solutions like Docker. The Docker image is compatible with ARM64 platforms, so it can be run on a Raspberry Pi 4.
PdfDing uses an SQLite database by default. Alternatively PdfDing supports PostgreSQL.
To install PdfDing using Docker you can just run the image from Docker Hub:
docker run --name pdfding \
-p 8000:8000 \
-v sqlite_data:/home/nonroot/pdfding/db -v media:/home/nonroot/pdfding/media \
-e HOST_NAME=127.0.0.1 -e SECRET_KEY=some_secret -e CSRF_COOKIE_SECURE=FALSE -e SESSION_COOKIE_SECURE=FALSE \
-d \
mrmn/pdfding:latest
If everything completed successfully, the application should now be running and can be accessed at http://127.0.0.1:8000.
If you use selinux it might be necessary to add the :Z
after the volumes, e.g.
sqlite_data:/home/nonroot/pdfding/db:Z
.
To install linkding using Docker Compose, you can use one of the files in the deploy directory and run e.g.:
docker-compose -d -f sqlite.docker-compose.yaml
If needed or wished it is possible to create an admin user. Admin users can view and delete users. Creating an admin user is optional. To give a user admin rights execute
python pdfding/manage.py make_admin -e admin@pdfding.com
inside the shell of the running container and specify the correct email address. Admin users can can also give other users admin rights via the ui.
PdfDing supports SSO via OIDC. OIDC is set up by using environment variables:
OIDC_ENABLE: "TRUE"
OIDC_CLIENT_ID: "pdfding"
OIDC_CLIENT_SECRET: "client_secret"
OIDC_AUTH_URL: "https://auth.pdfding.com/.well-known/openid-configuration"
OIDC_PROVIDER_NAME: "Authelia"
More information about the environment variables can be found in the Configuration section.
Once PdfDing is set up for using OIDC the same needs to be done on the OIDC identity provider's side. Of course, this configuration depends on the used identity provider. Here is an example configuration for Authelia:
oidc:
## The other portions of the mandatory OpenID Connect 1.0 configuration go here.
## See: https://www.authelia.com/c/oidc
clients:
- id: pdfding
description: PdfDing
# create client secret and hash with
# docker run --rm authelia/authelia:latest authelia crypto rand --length 64 --charset alphanumeric
secret: '$pbkdf2-sha512$310000$<rest_of_hashed_secret>'
public: false
authorization_policy: two_factor
scopes:
- openid
- email
- profile
redirect_uris:
- https://pdfding.com/accountoidc/login/callback/
PdfDing supports automated backups to S3 compatible storage. During backups the Sqlite database and uploaded PDF files will be backed up.
IMPORTANT: The backup of Postgres databases is as of now not supported. Postgres databases should be
backed up by using pg_dump
.
Backups are set up by using environment variables:
BACKUP_ENABLE: "TRUE"
BACKUP_SCHEDULE: "0 2 * * *"
BACKUP_ENDPOINT: 'minio.pdfding.com'
BACKUP_ACCESS_KEY: 'some_access_key'
BACKUP_SECRET_KEY: 'some_secret_key'
BACKUP_SECURE: 'FALSE'
More information about the environment variables can be found in the Configuration section.
PDfDing supports encrypted backups. Encryption is done via Fernet, a symmetric encryption algorithm provided by the cryptography library. Encrypted backups can be enabled by using environment variables:
BACKUP_ENCRYPTION_ENABLED: "TRUE"
BACKUP_ENCRYPTION_PASSWORD: 'some_password'
BACKUP_ENCRYPTION_SALT: 'some_salt'
IMPORTANT: If you enable encrypted backups or change the encryption password/salt, it is absolutely necessary to delete your existing backups in the S3 compatible storage. Not doing so will destroy your backup!
PDFs and the Sqlite database can easily be recovered from the backups by executing
python pdfding/manage.py recover_data
inside the shell of the running container.
DEFAULT_THEME
Values: light
, dark
| Default light
Specify the default theme.
DEFAULT_THEME_COLOR
Values: green
, blue
, gray
, red
, pink
, orange
| Default green
Specify the default theme color.
SECRET_KEY
Values: string
| Default = None
This value is the key to securing signed data. Should be to a large random value! Example: some_secret
HOST_NAME
Values: string
| Default = None
The host/domain name where PdfDing will be reachable. Example: pdfding.com
HOST_PORT
Values: integer
| Default: 8000
Allows to set a custom port for the PdfDing server.
DATABASE_TYPE
Values: SQLITE
, POSTGRES
| Default POSTGRES
Specify which database type should be used.
POSTGRES_HOST
Values: string
| Default = postgres
The host of the postgres DB: Example: postgres.pdfding.com
POSTGRES_PASSWORD
Values: string
| Default = None
The password for the postgres DB: Example: password
POSTGRES_PORT
Values: integer
| Default: 5432
The port of the postgres DB.
ACCOUNT_EMAIL_VERIFICATION
Values: TRUE
, FALSE
| Default: TRUE
Block users until they have verified their email address.
DISABLE_USER_SIGNUP
Values: TRUE
, FALSE
| Default: FALSE
Flag for disabling user signup. By setting this value to TRUE
user signup will be disabled.
OIDC_ENABLE
Values: TRUE
, FALSE
| Default: FALSE
Flag for enabling SSO via OIDC. By setting this value to TRUE
OIDC will be activated.
OIDC_CLIENT_ID
Values: string
| Default = None
PdfDing's OIDC client id. Example: pdfding
OIDC_CLIENT_SECRET
Values: string
| Default = None
PdfDing's OIDC client secret. Should be a large random value! Example: another_long_secret
OIDC_AUTH_URL
Values: string
| Default = None
The URL to the OpenID configuration of the auth server. Example:
https://auth.pdfding.com/.well-known/openid-configuration
OIDC_ONLY
Values: TRUE
, FALSE
| Default: TRUE
By setting this to TRUE
users will only be able to authenticate using OIDC.
OIDC_PROVIDER_NAME
Values: string
| Default = OIDC
The name of the OIDC provider. The name will be displayed on the login screen as OIDC_LOG IN VIA <PROVIDER_NAME>
.
Example: Authelia
CSRF_COOKIE_SECURE
Values: TRUE
, FALSE
| Default: TRUE
Set this to True to avoid transmitting the CSRF cookie over HTTP accidentally.
SESSION_COOKIE_SECURE
Values: TRUE
, FALSE
| Default: TRUE
Set this to True to avoid transmitting the session cookie over HTTP accidentally.
SECURE_SSL_REDIRECT
Values: FALSE
, TRUE
| Default: FALSE
Redirects all non-HTTPS requests to HTTPS. If PdfDing is running behind a reverse proxy this can cause infinite redirects.
SECURE_HSTS_SECONDS
Values: integer
| Default: None
For sites that should only be accessed over HTTPS, you can instruct modern browsers to refuse to connect to your domain
name via an insecure connection (for a given period of time) by setting the “Strict-Transport-Security” header.
SECURE_HSTS_SECONDS
will set this header for you on all HTTPS responses for the specified number of seconds. Test this
with a small value first. If everything works it can be set to a large value, e.g. 31536000
(1 year) , in order to
protect infrequent visitors.
ACCOUNT_DEFAULT_HTTP_PROTOCOL
Values: https
, http
| Default: https
The default protocol for account related URLs, e.g. for the password forgotten procedure.
EMAIL_BACKEND
Values: CONSOLE
, SMTP
| Default: CONSOLE
Whether to send account related emails, e.g a password reset or account verification, to the console or via an SMTP server.
SMTP_HOST
Values: string
| Default = None
The host/domain name of the SMTP server. Example: pdfding.com
SMTP_PORT
Values: integer
| Default: 587
The port of the SMTP server.
SMTP_USER
Values: string
| Default = None
The username used for logging into the SMTP server.
SMTP_PASSWORD
Values: string
| Default = None
The password used for logging into the SMTP server.
SMTP_USE_TLS
Values: FALSE
, TRUE
| Default: FALSE
Secure the connection to the SMTP server with TLS. Some SMTP servers support only one kind and
some support both. Note that SMTP_USE_TLS
/SMTP_USE_SSL
are mutually exclusive.
EMAIL_USE_SSL
Values: FALSE
, TRUE
| Default: FALSE
Secure the connection to the SMTP server with SSL. Some SMTP servers support only one kind and
some support both. Note that SMTP_USE_TLS
/SMTP_USE_SSL
are mutually exclusive.
BACKUP_ENABLE
Values: TRUE
, FALSE
| Default: FALSE
Flag for enabling periodic backups to S3 compatible storage. By setting this value to TRUE
periodic backups will be activated.
BACKUP_ENDPOINT
Values: string
| Default: None
The endpoint of the S3 compatible storage. Example: minio.pdfding.com
BACKUP_ACCESS_KEY
Values: string
| Default: None
The access key of the S3 compatible storage. Example: random_access_key
BACKUP_SECRET_KEY
Values: string
| Default: None
The secret key of the S3 compatible storage. Example: random_secret_key
BACKUP_BUCKET_NAME
Values: string
| Default: pdfding
The name of the bucket where PdfDing should be backed up to. Example: pdfding
BACKUP_SCHEDULE
Values: string
| Default: 0 2 * * *
The schedule for the periodic backups. Example: 0 2 * * *
. This schedule will start the backup
every night at 2:00. More information can be found here.
BACKUP_SECURE
Values: TRUE
, FALSE
| Default: FALSE
Flag to indicate to use secure (TLS) connection to S3 service or not.
BACKUP_ENCRYPTION_ENABLE
Values: TRUE
, FALSE
| Default: FALSE
Flag to enable encrypted backups.
IMPORTANT: If you enable encrypted backups or change the encryption password/salt, it is absolutely necessary to delete your existing backups in the S3 compatible storage. Not doing so will destroy your backup!
BACKUP_ENCRYPTION_PASSWORD
Values: string
| Default: None
Password used for generating the encryption key. The encryption key generation is done via PBKDF2 with 1000000 iterations.
Should be to a large random value! Example: some_secret
BACKUP_ENCRYPTION_SALT
Values: string
| Default: pdfding
Salt used for generating the encryption key. Example: some_salt
PdfDing is open source, so you are free to modify or contribute. PdfDing is built using the Django web framework. You can get started by checking out the excellent Django docs. Currently, PdfDing consists of four applications:
pdf
folder is the one related to managing and viewing PDFsusers
contains the logic related to usersadmin
foldercore
is the Django root applicationbackup
Other than that the code should be self-explanatory / standard Django stuff 🙂.
pipx install poetry
This project has support for pre-commit
hooks. They are used for checking the code quality,
e.g. with: black
, flake8
and bandit
. If pre-commit
is installed on your system just run
pre-commit install
Now whenever you commit your changes the pre-commit hooks will be triggered. If you want to bypass
pre-commit
for some reason just add --no-verify
to your commit command, e.g.:
git commit -m 'some commit message' --no-verify
Clone the repository:
git clone https://github.com/mrmn2/PdfDing.git
cd into the project:
cd PdfDing
Create the virtual environment and install all dependencies:
poetry install
Activate the environment for your shell:
poetry shell
Install frontend dependencies:
mkdir ./js && mkdir ./css
npm ci
npm run build
Initialize the database:
python pdfding/manage.py migrate
Create a user for the frontend:
python pdfding/manage.py createsuperuser
Start the development server with:
# in one shell run
python pdfding/manage.py runserver
# in another run
npx tailwindcss -i pdfding/static/css/input.css -o pdfding/static/css/tailwind.css -c tailwind.config.js --watch
The frontend is now available under http://127.0.0.1:8000. Any changes in regard to Tailwind CSS will be automatically reflected.
Run all tests with:
pytest
It's also possible to run unit tests and e2e tests separately. Unit tests can be run with:
pytest pdfding/admin pdfding/pdf pdfding/users --cov=pdfding/admin --cov=pdfding/pdf --cov=pdfding/users
E2e tests with
pytest pdfding/e2e
Formatting is done via black
:
black .
Further code quality checks are done via flake8
:
flake8