- this guide adheres to the recommendation of the postgres documentation to use the version of
pg_dumpallfrom 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.yamlcompose 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 itdocker compose -f temp.yaml up(use--detach/-dif you like or use tmux for next commands)docker exec -it -e PGPASSWORD=paperless pg17 pg_dumpall -U paperless -h pg13 > paperless_dump.sqldocker compose -f temp.yaml downrm temp.yaml- in your paperless-ngx
docker-compose.yamlchange the postgresimageto the new version, e.g.postgres:13->postgres:17 - make sure that it doesn't use
old_data_mount- if
old_data_mountis a volume, create or specify a new volume (different name) - if
old_data_mountis 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> bashpsql -U paperlessSHOW 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,psqlwould print nothing and it didn't set the password. the cybertec-postgresql.com article doesn't have this backslash.Ctrl+Dx2 to exitpsqland 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_mountbind/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,usermodandgroupadd--disabled-login: no password and shell set to/usr/sbin/nologin--comment "": don't prompt for details, successor of deprecated--gecosflag 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-datasetfrom="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.smbdin/var/samba/smb.conf(change existing line) +smbcontrol all reload-configto 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)