Docspell is a self-hosted document management/archiving system. This guide deploys it with Docker Compose, using PostgreSQL as the database and Solr for full-text search — the standard production setup.
Target environment: Ubuntu 24.04 LTS, 2+ vCPU, 4 GB+ RAM (Solr and the OCR pipeline are the main memory consumers), 40 GB+ disk depending on document volume.
1. Initial server prep
SSH into your RamNode VPS as root, then:
apt update && apt upgrade -y
apt install -y curl ufw fail2ban
# Create a non-root deploy user
adduser deploy
usermod -aG sudo deploy
# Basic firewall
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enableLog out and back in as deploy for the rest of this guide.
2. Install Docker and Docker Compose
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
# Verify
docker --version
docker compose version3. Create the project layout
mkdir -p ~/docspell/{data/postgres,data/solr,data/docspell,data/imap}
cd ~/docspell4. Create the Compose file
nano docker-compose.ymlservices:
db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: docspell
POSTGRES_USER: docspell
POSTGRES_PASSWORD: "CHANGE_ME_DB_PASSWORD"
volumes:
- ./data/postgres:/var/lib/postgresql/data
networks: [docspell]
solr:
image: solr:9
restart: unless-stopped
command: solr-precreate docspell
volumes:
- ./data/solr:/var/solr
networks: [docspell]
restserver:
image: docspell/restserver:latest
restart: unless-stopped
depends_on: [db, solr]
ports:
- "127.0.0.1:7880:7880"
environment:
DOCSPELL_SERVER_INTERNALURL: "http://restserver:7880"
DOCSPELL_SERVER_BASEURL: "https://docspell.yourdomain.com"
DOCSPELL_SERVER_BACKEND_JDBC_URL: "jdbc:postgresql://db:5432/docspell"
DOCSPELL_SERVER_BACKEND_JDBC_USER: "docspell"
DOCSPELL_SERVER_BACKEND_JDBC_PASSWORD: "CHANGE_ME_DB_PASSWORD"
DOCSPELL_SERVER_FULLTEXTSEARCH_SOLR_URL: "http://solr:8983/solr/docspell"
volumes:
- ./data/docspell:/opt/docspell
networks: [docspell]
joex:
image: docspell/joex:latest
restart: unless-stopped
depends_on: [db, solr]
environment:
DOCSPELL_JOEX_JDBC_URL: "jdbc:postgresql://db:5432/docspell"
DOCSPELL_JOEX_JDBC_USER: "docspell"
DOCSPELL_JOEX_JDBC_PASSWORD: "CHANGE_ME_DB_PASSWORD"
DOCSPELL_JOEX_FULLTEXTSEARCH_SOLR_URL: "http://solr:8983/solr/docspell"
DOCSPELL_JOEX_BASEURL: "http://joex:7878"
volumes:
- ./data/docspell:/opt/docspell
networks: [docspell]
networks:
docspell:
driver: bridgeReplace CHANGE_ME_DB_PASSWORD (both occurrences must match) and docspell.yourdomain.com with your actual values.
Joex is the job executor that runs OCR and text extraction — it needs to share the
docspelldata volume with restserver and needs enough CPU/RAM to run Tesseract comfortably.
5. Bring the stack up
docker compose up -d
docker compose logs -f restserverWait until you see the server report it's listening, then Ctrl+C out of the log follow.
6. Put Nginx + TLS in front of it
sudo apt install -y nginx certbot python3-certbot-nginxsudo nano /etc/nginx/sites-available/docspellserver {
listen 80;
server_name docspell.yourdomain.com;
client_max_body_size 200M;
location / {
proxy_pass http://127.0.0.1:7880;
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-Proto $scheme;
}
}sudo ln -s /etc/nginx/sites-available/docspell /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d docspell.yourdomain.comPoint your domain's A record at the VPS's IP before running certbot.
7. First login and setup
- Visit
https://docspell.yourdomain.com. - Register a new collective (Docspell's term for a tenant/organization).
- Create your admin user under that collective.
- Log in and confirm document upload + OCR works by uploading a test PDF and checking it becomes searchable after a minute.
8. Backups
At minimum, back up:
~/docspell/data/postgres(metadata)~/docspell/data/docspell(uploaded file blobs)
Solr's index (~/docspell/data/solr) can be rebuilt from the documents if lost, so it's lower priority.
# Example: nightly tarball to a separate location
tar -czf docspell-backup-$(date +%F).tar.gz -C ~/docspell data/postgres data/docspell9. Updating
cd ~/docspell
docker compose pull
docker compose up -dCheck the Docspell release notes before upgrading across major versions — schema migrations run automatically on restserver startup but it's worth reading first.
