- this guide adheres to the recommendation of the postgres documentation to use the version of
pg_dumpall
from the postgres version you're upgrading to, not the old/curent one https://www.postgresql.org/docs/current/upgrading.html#UPGRADING-VIA-PGDUMPALL - shutdown paperless-ngx and postgres
- write a
temp.yaml
compose file:
services:
old:
image: postgres:13
container_name: pg13
volumes:
- old_data_mount:/var/lib/postgresql/data
new:
image: postgres:17
container_name: pg17
environment:
POSTGRES_PASSWORD: pw # postgres refuses to start without a pw even though we won't use it
docker compose -f temp.yaml up
(use--detach
/-d
if you like or use tmux for next commands)docker exec -it -e PGPASSWORD=paperless pg17 pg_dumpall -U paperless -h pg13 > paperless_dump.sql
docker compose -f temp.yaml down
rm temp.yaml
- in your paperless-ngx
docker-compose.yaml
change the postgresimage
to the new version, e.g.postgres:13
->postgres:17
- make sure that it doesn't use
old_data_mount
- if
old_data_mount
is a volume, create or specify a new volume (different name) - if
old_data_mount
is a bind, either pick a new path or move/rename the existing one
- if
- only start the db, not the whole stack:
docker compose up -d db
cat paperless_dump.sql | docker exec -i <db container> psql -U paperless
- we might need to fix SCRAM secret issues, otherwise paperless-ngx won't be able to connect to postgres and you'd get these errors:
- paperless-ngx:
django.db.utils.OperationalError: connection failed: connection to server at "10.0.1.2", port 5432 failed: FATAL: password authentication failed for user "paperless"
- postgres:
paperless-db | 2025-06-14 19:53:35.177 UTC [33] FATAL: password authentication failed for user "paperless" paperless-db | 2025-06-14 19:53:35.177 UTC [33] DETAIL: User "paperless" does not have a valid SCRAM secret. paperless-db | Connection matched file "/var/lib/postgresql/data/pg_hba.conf" line 128: "host all all all scram-sha-256"
- paperless-ngx:
- to fix SCRAM issue (more info: https://www.cybertec-postgresql.com/en/from-md5-to-scram-sha-256-in-postgresql/):
docker exec -it <db container> bash
psql -U paperless
SHOW password_encryption;
<- should say "scram-sha-256", then we're on the right path\password paperless
<- this prompts you to enter the new password and confirm again but with scram-sha-256 instead of md5. with the default config for paperless, the password ispaperless
. NOTE THE BACKSLASH AT THE BEGINNING! when i ran the command without the backslash,psql
would print nothing and it didn't set the password. the cybertec-postgresql.com article doesn't have this backslash.Ctrl+D
x2 to exitpsql
and container shell
docker compose down && docker compose up
<- should have no errors in the output, inspect closely to make sure everything's fine before cleaning up :)- optional, if everything is working and you don't need the old data:
rm paperless_dump.sql
- remove/delete
old_data_mount
bind/volume
// sshd_config
# Only allow connections from 192.168.0.0 - 192.168.255.255 by default
AllowUsers *@192.168.0.0/24
Match User specificuser
# Allow all IPs to attempt connecting as specificuser
# Unlike what ChatGPT says (maybe due to Distro and version differences), this works as expected on Ubuntu Server 24+
AllowUsers *@*
adduser --disabled-login --comment "" SomeUserName
adduser
: friendlier front-end foruseradd
,usermod
andgroupadd
--disabled-login
: no password and shell set to/usr/sbin/nologin
--comment ""
: don't prompt for details, successor of deprecated--gecos
flag i think
Only needed if a user needs to run a command as root/sudo (e.g. not needed for zfs send
/syncoid
when setting it up rootless with zfs allow
)
visudo /etc/sudoers.d/SomeUserName
(better than just visudo
because of package manager upgrades)
To check sudoers configuration (above command won't check permissions by default):
visudo --check --strict
#!/bin/bash
/usr/sbin/syncoid \
--sendoptions=w # send raw/encrypted
--no-privilege-elevation \ # don't attempt to use root/sudo (assumes proper permissions / zfs allow)
--no-sync-snap \ # don't create a snapshot for this sync (would require additional permissions, i skip this because sanoid already creates plenty of snapshots)
--pv-options='-L 5M' \ # optional: limit bandwidth to 5MB/s
tank/source-dataset SomeUser@SomeServer:tank/target-dataset
from="192.168.0.0/24",restrict,command="SomeCommandHere" ssh-[...] [key] user@host
--pv-options='-L 2M'
ssh -F ~/.ssh/config user@ip
-F
forces usage of the config, skipping global config which attempts to send locales.
Source: https://stackoverflow.com/a/41786965
services:
app:
build:
context: .
dockerfile_inline: |
FROM baseimage ...
- grow VM disk on Proxmox
- in VM:
growpart [device] [partitionNumber]
(e.g.growpart /dev/sda 2
) - in VM:
resize2fs [partition]
(e.g.resize2fs /dev/sda2
) - verify with
df -h
- use
namei -l
, 99% of my issues were due to insufficient parent directory permissions - my ScanJet Pro 4500 fn1 only supported old SMB versions out of the box -> update the firmware -> it now supports SMB2/3 but still not SMB3_11 so i set
min protocol = SMB3_02
- by default on ubuntu, samba is configured create log files per client (hostname or IP). probably great for large scale deployments but sucks for small scale / homelab troubleshooting. use
log file = /var/log/samba/log.smbd
in/var/samba/smb.conf
(change existing line) +smbcontrol all reload-config
to change this. it will still write tons of other files, but troubleshooting should now be as easy astail -f /var/log/samba/log.smbd
systemctl edit --full --force custom-zfs-load-keys
[Unit]
Before=zfs-mount.service
After=zfs-import.target
Requires=zfs-import.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/zfs load-key -a
[Install]
WantedBy=zfs-mount.service
systemctl edit docker
[Unit]
Requires=zfs-mount.service
Ctrl + W / Alt + Backspace: Remove word left
Ctrl + U: kill whole line
Ctrl + S: stop screen
Ctrl + Q: resume stopped screen
Alt + D: delete all right
Ctrl + _: undo
tl;dr add a caddy.acme_dns: cloudflare TokenHere
label to any container where you don't need the caddy:
label (e.g. the caddy container itself). more info: lucaslorentz/caddy-docker-proxy#500 (comment)
- idempotency (some http verbs, pure functions)
- isomorphism (web dev)