gopher://gopher.someodd.zip:70/1/catalog/tech/running_a_server/Running a ServerLargely about configuring software as daemons to provide services.2026-01-25T00:00:00Zgopher.someodd.zipgopher://gopher.someodd.zip:70/0/tech/running_a_server/ipv6_ddns_afraid.mdThe Missing Link in My TLS Chain2026-01-25T00:00:00Z2026-01-25T00:00:00ZDebugging session for a TLS chain bug where some clients could reac...gopher://gopher.someodd.zip:70/0/tech/running_a_server/immich.txtimmich2025-12-31T00:00:00Z2025-12-31T00:00:00ZSetup guide for a self-hosted Immich photo and video system on a De... Immich ---> Server Storage ---> Backups (RAID + tape)
```
Key principles:
* One-way ingestion (no destructive sync)
* Server never deletes data due to client actions
* Immich handles indexing + UX
* Filesystem handles durability + backups
## Storage Layout
Root path:
```
/media/root/BackupRAID/baudrillard/photos/
```
Structure:
```
immich/ -> main Immich media library
immich-db/ -> postgres database storage
staging/ -> temporary import area
backups/ -> database dumps
```
## Docker Setup
Install Docker:
```
sudo apt update
sudo apt install docker.io docker-compose-plugin
sudo systemctl enable --now docker
```
Create Immich directory:
```
mkdir -p ~/immich
cd ~/immich
```
Download compose file:
```
curl -LO https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
```
Create .env file (based on example.env):
```
UPLOAD_LOCATION=/media/root/BackupRAID/baudrillard/photos/immich
DB_DATA_LOCATION=/media/root/BackupRAID/baudrillard/photos/immich-db
TZ=America/Los_Angeles
IMMICH_VERSION=v2
DB_PASSWORD=
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
```
Edit docker-compose.yml:
1. Ensure upload mount is correct:
* ${UPLOAD_LOCATION}:/data
2. Enable HDD optimization:
DB_STORAGE_TYPE: 'HDD'
3. (Optional) staging mount:
* /media/root/BackupRAID/baudrillard/photos/staging:/staging:ro
Create directories:
```
mkdir -p /media/root/BackupRAID/baudrillard/photos/immich
mkdir -p /media/root/BackupRAID/baudrillard/photos/immich-db
mkdir -p /media/root/BackupRAID/baudrillard/photos/staging
mkdir -p /media/root/BackupRAID/baudrillard/photos/backups
```
Start Immich:
```
sudo docker compose up -d
```
Access:
```
http://SERVER_IP:2283
```
Create admin account.
## WireGuard + Firewall Setup
Goal: Only allow access via WireGuard (no public exposure)
WireGuard subnet:
```
10.1.0.0/24
```
UFW rules:
```
sudo ufw allow 51820/udp comment 'WireGuard VPN'
sudo ufw allow from 10.1.0.0/24 to any port 2283 comment 'Immich via WireGuard only'
sudo ufw deny 2283 comment 'Block public Immich access'
sudo ufw reload
```
Test:
```
http://10.1.0.1:2283 (over WireGuard)
```
## Android Setup (GrapheneOS)
Install Immich app.
Configure:
* Enable Backup
* Select albums:
* Camera (ONLY initially)
* Enable:
* Background backup
* WiFi only (optional)
* Charging only (optional)
Test:
* Take a photo
* Verify upload appears in web UI
Important:
* Backup is one-way
* Deleting from phone does NOT delete from server
## Storage Template Engine
Leave OFF.
Reason:
* Simpler
* More stable
* Filesystem layout handled by Immich
* Archive integrity prioritized over human-readable folders
## Importing External Media
NEVER:
* copy files directly into immich/ directory
Use one of these methods instead:
## Method 1: Web Upload (simple)
* Open web UI
* Drag and drop files or folders
* Create album afterward
Best for:
* small imports
* manual curation
## Method 2: Immich CLI (recommended for server-side bulk import)
1. Create API key in Immich UI
2. Run CLI via Docker:
sudo docker run --rm -it
-v /media/root/BackupRAID/baudrillard/photos/staging/import1:/import:ro
-e IMMICH_INSTANCE_URL=http://10.1.0.1:2283/api
-e IMMICH_API_KEY='YOUR_API_KEY'
ghcr.io/immich-app/immich-cli:latest
upload --recursive /import
Optional:
* Use --album-name "Import Name"
* Use --skip-hash for faster import
* Use --dry-run for preview (slow on large datasets)
Workflow:
```
server files -> staging -> CLI upload -> Immich library
```
## Backups
Media:
* stored in RAID mirror]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/boot-full.txtFixing a Full /boot in an `apt` Error Loop2025-09-29T00:00:00Z2025-09-29T00:00:00ZRecovery guide for when /boot fills up and apt upgrade gets stuck i...gopher://gopher.someodd.zip:70/0/tech/running_a_server/ii-logger.txtUse ii to log IRC (for scripting purposes)2025-09-29T00:00:00Z2025-09-29T00:00:00ZUses the ii IRC client as a minimal logger so gopher pages can surf... "$BASE/$SRV/in"
# keep the process in the foreground so systemd can supervise it
wait "$pid"
```
then
```
chmod +x ~/.local/bin/ii-main-logger
```
create systemd `~/.config/systemd/user/ii-logger.service`
```
[Unit]
Description=ii logger for %E{IRC_CHAN:-#main} on %E{IRC_SERVER:-127.0.0.1}
After=network.target
[Service]
Type=simple
Environment=II_DIR=%h/irc
Environment=IRC_SERVER=127.0.0.1
Environment=IRC_PORT=6667
Environment=IRC_NICK=digestlog
Environment=IRC_CHAN=#main
ExecStart=%h/.local/bin/ii-main-logger
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
```
then
```
systemctl --user daemon-reload
systemctl --user enable --now ii-logger.service
```
sanity check:
```
ls -R ~/irc
tail -n3 ~/irc/127.0.0.1/#main/out
```
change nick/channel later (systemctl --user edit ii-logger.service and override the Environment= lines, then):
```
systemctl --user daemon-reload
systemctl --user restart ii-logger.service
```
Also, logrotate so doesn't keep track everything forever:
```
sudo tee /etc/logrotate.d/ii-logger >/dev/null <<'ROT'
# Rotate ii channel logs under your home. Adjust the path if needed.
# Keeps 14 compressed rotations; trims when file >256k or daily, whichever first.
# copytruncate avoids needing to restart ii.
/home/*/irc/*/#*/out {
daily
size 256k
rotate 14
compress
delaycompress
copytruncate
missingok
notifempty
}
ROT
# test it (dry run shows what would rotate)
sudo logrotate -d /etc/logrotate.conf
```
]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/music-server-mpd.txtMusic server with Music Player Daemon2025-03-11T00:00:00Z2025-03-11T00:00:00ZSets up a music server with MPD to stream to an xbox, an Android at...gopher://gopher.someodd.zip:70/0/tech/running_a_server/xmpp-server-video-audio-calls.txtXMPP: audio/video call support (prosody)2025-03-09T00:00:00Z2025-03-09T00:00:00ZAdds audio/video calling to a Prosody XMPP server on Debian by conf...gopher://gopher.someodd.zip:70/0/tech/running_a_server/mumble-server.txtHow to set up a Mumble server2025-03-08T00:00:00Z2025-03-08T00:00:00ZSets up a Mumble voice-chat server — low-latency, strongly encrypte...gopher://gopher.someodd.zip:70/0/tech/running_a_server/letsencrypt-renewal-hook-mistake.txtLetsEncrypt renewal hooks: I was doing it all wrong!2025-03-02T00:00:00Z2025-03-02T00:00:00ZCatalogs a LetsEncrypt hook misconfiguration where the author used ...gopher://gopher.someodd.zip:70/0/tech/running_a_server/linux-counter-strike-16-server.txtCounter-Strike 1.6 Server (Linux)2025-02-25T00:00:00Z2025-02-25T00:00:00ZCounter-Strike 1.6 server setup on Linux (Debian), with nginx and L... mapcycle.txt`
* Add the map name to `mapcycle.txt`
* i should make a script
## Resource server
I'm not sure if this is working.
```
sv_allowupload 1
sv_allowdownload 1
sv_downloadurl "http://cs16.someodd.zip/cstrike/"
```
you could just serve the same cstrike dir you're already serving! and then hide the server.cfg to hide the rcon. just modify the nginx config i have here. it'll make it super fast.
add to the server block:
```
location /cstrike/ {
root /home/someuser/steamcmd/cs16/; # Specific root for the cstrike directory
index index.html index.htm;
location = /cstrike/server.cfg {
deny all; # Deny access to the server.cfg file, returning 403 Forbidden
}
try_files $uri $uri/ =404; # Correctly handle the file paths within cstrike
}
```
this is working super fast!
## Bots
Back up the entire directory first.
### installing metamod
`cd ~/steamcmd`
Before installing Podbot, you need to install Metamod, which is a plugin interface for Half-Life modifications that allows you to use plugins like Podbot.
**Download Metamod**: Visit the Metamod website and download the latest version appropriate for your server (P or V depending on your server's OS). http://metamod.org/ (i downloaded the regular linux, not x64 version). **IMPORTANT NOTE STARTING WITH DEBIAN TRIXIE (13)** just use Metamod-p like from https://sourceforge.net/projects/metamod-p/files/Metamod-P%20Binaries/.
**Extract the Files**: Unzip the downloaded file into the `cstrike/addons/` directory of your server. Something like this:
```
mkdir -p cs16/cstrike/addons/metamod/dlls
tar -xf metamod-1.20-linux.tar.gz -C cs16/cstrike/addons/metamod/dlls
```
edit `c16/cstrike/liblist.gam` and edit the value of `gameddl_linux`:
```
gamedll_linux "addons/metamod/dlls/metamod.so"
```
### installing podbot
Download podbot, I got `podbot_full_V]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/out-of-disk-space.txtOut of disk space!2024-12-04T00:00:00Z2024-12-04T00:00:00ZSteps to take when a Debian server runs out of disk space: diagnosi...gopher://gopher.someodd.zip:70/0/tech/running_a_server/upgrading-server-gpu.txtServer upgrade! 4x RAM + GPU! Including CUDA+ollama!2024-12-04T00:00:00Z2024-12-04T00:00:00ZServer upgrade writeup: quadrupled RAM plus a Quadro P620 GPU, incl...gopher://gopher.someodd.zip:70/0/tech/running_a_server/wireguard-simple.txtSimple, quick VPN server using WireGuard2024-12-04T00:00:00Z2024-12-04T00:00:00ZWhy the author prefers exposing a WireGuard VPN instead of SSH dire... /etc/wireguard/publickey
```
]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/bitcoin-server.txtRunning Bitcoin on my server2024-11-26T00:00:00Z2024-11-26T00:00:00ZNotes on self-hosting Bitcoin by running bitcoind on a Debian serve...
User=youruser
Group=youruser
# Hardening measures
####################
# Provide a private /tmp and /var/tmp.
PrivateTmp=true
# Use a new /dev namespace only populated with API pseudo devices
# such as /dev/null, /dev/zero and /dev/random.
PrivateDevices=true
# Deny the creation of writable and executable memory mappings.
MemoryDenyWriteExecute=true
[Install]
WantedBy=multi-user.target
```
Create script and set the permissions:
```
sudo vi /usr/local/bin/bitcoind-start.sh
```
The file:
```
#!/bin/bash
# Just a simple wrapper to start bitcoind.
#
# If using systemd, simply create a file (e.g. /etc/systemd/system/bitcoind.service)
# from example file below and add this script in ExecStart.
# https://raw.githubusercontent.com-/bitcoin/bitcoin/76deb30550b2492f9c8d9f0302da32025166e0c5/contrib/init/bitcoind.service
#
# Then run following to always start:
# systemctl enable bitcoind
#
# and the following to start immediately:
# systemctl start bitcoind
# If you are mounting a secondary disk, find the UUID of your
# disk and a line entry in /etc/fstab e.g.
#
# UUID=foo-bar-1234 /path-to-dir/.bitcoin ext4 defaults 0 0
set -e
# Let's wait for 30 seconds in case other processes need to come up first.
sleep 30
echo "Starting bitcoind..."
bitcoind --daemon --server -pid=/home/baudrillard/.bitcoin/bitcoind.pid -conf=/home/baudrillard/.bitcoin/bitcoin.conf
echo "Done!"
```
```
sudo chmod +x /usr/local/bin/bitcoind-start.sh
```
Enable:
]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/ltfs-restic-backup-archives.txtRestic on LTFS2024-11-18T00:00:00Z2024-11-18T00:00:00ZUsing restic with LTFS to back up to LTO tape the easy and fast way...> /mnt/ltfs/test.txt
sudo umount /mnt/ltfs
sudo mt -f /dev/st0 eject
ls /mnt/ltfs
```
then try mounting again and checking the file.
## restic
check out these tweaks:
https://restic.readthedocs.io/en/latest/manual_rest.html
from above i was sad to find that `--read-concurrency` is not available in the
stable repo for debian as of right now (current restic verison is 0.14.x or
whatever).
Prepare the restic repository:
```
sudo RESTIC_PASSWORD_FILE=/etc/restic-password /usr/bin/restic init -r /mnt/ltfs
```
To find what you should exclude you should exclude firstly, the things in Linux
that don't make much sense to me to backup (things like `/proc`), but also see
what the largest files are, which may indicate which directories to ignore:
```
sudo find / -type f -exec du -h {} + | sort -rh | head -n 10
```
Here's my command for backups, note the `pack-size` (chosen relative to LTFS
block size), and be sure to `exclude` what you can (lowest hanging fruit, at
least):
```
sudo RESTIC_PASSWORD_FILE=/etc/restic-password /usr/bin/restic backup / \
--exclude /home/baudrillard/.bitmonero \
--exclude /root/.bitmonero \
--exclude /nix \
--exclude /mnt \
--exclude /tmp \
--exclude /run \
--exclude /var/tmp \
--exclude /lost+found \
--exclude /media \
--exclude /sys \
--exclude /usr/share/ollama/.ollama/models/blobs \
--exclude /proc \
--exclude /dev \
-r /mnt/ltfs \
--compression max \
--pack-size 128
```
Pretty impressive speed for me:
```
processed 414986 files, 64.833 GiB in 11:22
```
Don't forget to keep `/etc/restic-password` backed up, like in a password manager!
verify the backup:
```
sudo RESTIC_PASSWORD_FILE=/etc/restic-password /usr/bin/restic snapshots -r /mnt/ltfs
```
You can do a differential/incremental update by running the same backup
command, but here I try adding over 1TB of data from my `/media` backup
directories by simply running the backup command again, but removing `/media`
from `exclude`.
## Things to think about
handy debug:
```
sudo ltfsck /dev/sg4
```
If you interrupt a backup it'll just totally mess up]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/lto_simple.txtSimpler Encrypted LTO Tape Archives2024-11-18T00:00:00Z2024-11-18T00:00:00ZSimpler encrypted LTO6 tape backup workflow on Debian, meant as an ... /etc/backup.passphrase'
# now create the archive
sudo sh -c '
tar --totals \
--checkpoint=100 \
--checkpoint-action=dot \
--use-compress-program="zstd" \
-cvf - /media/root/BackupRAID \
| gpg --symmetric --cipher-algo AES256 \
--batch --yes \
--pinentry-mode loopback \
--passphrase-file /etc/backup.passphrase \
| dd of=/dev/nst0 bs=1M status=progress
'
```
This is crazy fast. But if blocking factor is large you'll run out of space
quickly. The solution is to perhaps place a single archive onto the tar.
## Test archive, restore
See status:
```
sudo stenc -f /dev/st0
```
Rewind and list contents:
```
sudo mt -f /dev/nst0 rewind
sudo tar -tvf /dev/nst0 --use-compress-program=zstd
```
### if you used pgp (best imo)
Read test successful with:
```
sudo mt -f /dev/nst0 rewind
sudo dd if=/dev/nst0 bs=64k count=1 | file -
# Expect: "GPG symmetrically encrypted data"
```
and...
```
sudo mt -f /dev/nst0 rewind
sudo dd if=/dev/nst0 bs=1M \
| g]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/server-too-noisy.txtMaking my server quieter2024-11-18T00:00:00Z2024-11-18T00:00:00ZMaking a home server quieter through BIOS fan curves and additional...gopher://gopher.someodd.zip:70/0/tech/running_a_server/dynamic-dns-linux-debian.txtDynamic DNS in Linux (Debian)2024-11-16T00:00:00Z2024-11-16T00:00:00ZDynamic DNS on Debian using afraid.org (freedns) with a cron-driven...> /tmp/freedns_someodd_mooo_com.log 2>&1 &
```
Something like the above command, that you get from Afraid.org.
You can crontab:
```
*/5 * * * * ~/duckdns/duck.sh >/dev/null 2>&1
```
You could also use systemd. Above does every five minutes.
]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/restic_entire_server.txtRestic Backup Entire Server2024-10-13T00:00:00Z2024-10-13T00:00:00ZRestic backup recipe covering an entire Debian server. Chooses rest... "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
DATE=$(date "+%Y-%m-%d %H:%M:%S")
echo "Backup completed successfully at $DATE" >> "$LOG_FILE"
else
DATE=$(date "+%Y-%m-%d %H:%M:%S")
echo "Backup failed at $DATE" >> "$LOG_FILE"
fi
```
I also created a script to check the integrity and prune restic (`/usr/local/bin/restic-maintain.sh`):
```
#!/bin/bash
LOG_FILE="/var/log/restic-maintain.log"
export RESTIC_PASSWORD_FILE=/etc/restic-password
export RESTIC_REPOSITORY=/media/root/BackupRAID/server-backups/restic-simulacra-entire-server-start-2024-10-13
# Check integrity and prune
restic check > $LOG_FILE
restic forget --prune --keep-daily=7 --keep-weekly=4 --keep-monthly=12 >> $LOG_FILE
# Appends a timestamp to the log
date "+%Y-%m-%d %H:%M:%S" >> $LOG_FILE
```
Let's simply add the script to root's crontab:
```
sudo crontab -e
```
Add these entries (backup daily at 2am, maintain weekly Saturday at 6am):
```
0 2 * * * /usr/local/bin/restic-backup.sh
0 6 * * 6 /usr/local/bin/restic-maintain.sh
```
## Restore from backup (when needed)
### List snapshots
```
restic snapshots -r /media/roo]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/Server Torrent Create.txtTorrents for data longevity2024-10-01T00:00:00Z2024-10-01T00:00:00ZCreating torrents for data longevity on a Debian server using trans...gopher://gopher.someodd.zip:70/0/tech/running_a_server/diagnosing-server-latency.txtHigh latency: how DNS and NAT was to blame2024-09-05T00:00:00Z2024-09-05T00:00:00ZDebugging persistent high-latency on a gopherhole, ultimately trace...> DiG 9.20.1-1-Debian <<>> gopher.someodd.zip
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60485
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;gopher.someodd.zip. IN A
;; ANSWER SECTION:
gopher.someodd.zip. 844 IN CNAME someodd.duckdns.org.
someodd.duckdns.org. 60 IN A 73.93.14.18
;; Query time: 3403 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Thu Sep 05 13:36:17 PDT 2024
;; MSG SIZE rcvd: 96
$ gopherhole git:(master) nslookup gopher.someodd.zip
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
gopher.someodd.zip canonical name = someodd.duckdns.org.
Name: someodd.duckdns.org
Address: 73.93.14.18
;; communications error to 127.0.0.53#53: timed out
;; communications error to 127.0.0.53#53: timed out
;; communications error to 127.0.0.53#53: timed out
;; no servers could be reached
```
`dig`: I believe the results above show an unusually high response time for the
DNS resolution process (while inside the network).
`nslookup`: I think the above results show problems with the local DNS resolver.
I then tested adding this line to my `/etc/hosts`, which made browsing my gopherhole practially instantaneous:
```
192.168.1.100 gopher.someodd.zip
```
I removed the above entry after testing. At this point I became tasked with
switching away from DuckDNS, especially after reading about other people's
problems.
## Switch from DuckDNS to Afraid.org
I updated my DNS records (CNAME) on the domain registrar service I use (for
someodd.zip) to point to the new Dynamic DNS service I signed up for:
afraid.org.
Afraid.org has been around for a long time, people seem to like the service and
think it's reliable. I also liked that it uses FreeBSD.
I felt that after switching to Afraid.org that the issues were mostly resolved.
However, now, if I'm on the local network it now works very fast. If I'm
outside the server's network the gopherhole works very slow on port 70, yet
port 7070 and 7071 are fast.
## NAT
I started thinking that this was a NAT issue. For some reason I ran into the
concept of NAT loopback/hairpin/reflect before when looking into some issue I
think was related to XMPP.
To just double-check DNS I tried accessing `gopher://[server ip here]` on the
external network and it was still slow. I also used a DNS propagation checker
and it looked like the CNAME records rolled over to `someodd.mooo.com` away
from `someodd.duckdns.org`.
I decided to test out the NAT loopback hypothesis. On the server's network router, I enabled NAT loopback/masquerading for my `LAN => WAN` zone.
Once the router reloaded everything was working ver]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/xmpp-server.txtSet up an XMPP Server2024-04-22T00:00:00Z2024-04-22T00:00:00ZSets up an XMPP server on Debian for hosting your own encrypted mes...gopher://gopher.someodd.zip:70/0/tech/running_a_server/irc-server.txtSet up an IRC server2024-03-30T00:00:00Z2024-03-30T00:00:00ZJourney setting up an IRC server on Debian 12 with ngircd plus athe...
```
## ngircd + LetsEncrypt (SSL)
Get SSL connections working on the IRC server by using LetsEncrypt to manage the certificate automatically.
I was able to specify my icecast2 web root (selecting 2, place in web root when asked) since I already have that in order to do the ACME verification or whatever! Otherwise you might wanna do something like `sudo certbot certonly --standalone -d irc.someodd.zip` (which will start a web server for you).
```
sudo certbot certonly --webroot-path="/usr/share/icecast2/web" -d 'irc.someodd.zip'
```
Do a bunch of file management for ngircd's permissions sake, but also create a `dhparams.pem`:
```
sudo mkdir /etc/ngircd/ssl
sudo openssl dhparam -out /etc/letsencrypt/live/irc.someodd.zip/dhparams.pem 2048
sudo cp /etc/letsencrypt/live/irc.someodd.zip/fullchain.pem /etc/ngircd/ssl/
sudo cp /etc/letsencrypt/live/irc.someodd.zip/dhparams.pem /etc/ngircd/ssl/
sudo cp /etc/letsencrypt/live/irc.someodd.zip/privkey.pem /etc/ngircd/ssl/
sudo chown -R irc:irc /etc/ngircd/ssl/
```
Point to those files in `/etc/ngircd/ngircd.conf`, in the `[SSL]` section. In fact here's basically my entire `[SSL]` block, with comments removed:
```
[SSL]
CertFile = /etc/ngircd/ssl/fullchain.pem
CipherList = SECURE128:-VERS-SSL3.0
DHFile = /etc/ngircd/ssl/dhparams.pem
KeyFile = /etc/ngircd/ssl/privkey.pem
Ports = 6697
```
Note I have SSL connections accepted on port 6697.
Allow connections to the configured SSL port with:
```
sudo ufw allow 6697/tcp comment 'SSL IRC'
```
Of course if you want to test external connections, do some port forwarding on your router. Finally, test it out by first restarting `ngircd` (`sudo service ngircd restart`) and then connecting to your server on that port with SSL!
### Handling LetsEncrypt renewals
Certificates expire or something, I guess. Luckily LetsEncrypt makes automation fairly simple.
Configure this in `/etc/letsencrypt/renewal/irc.someodd.zip.conf` under `[renewalparams]`:
```
renew_hook = cp /etc/letsencrypt/live/irc.someodd.zip/fullchain.pem /etc/ngircd/ssl/ && cp /etc/letsencrypt/live/irc.someodd.zip/privkey.pem /etc/ngircd/ssl/ && chown -R irc:irc /etc/ngircd/s]]>gopher://gopher.someodd.zip:70/0/tech/running_a_server/archive_lto_zpaq.txtArchive using LTO Tape + zpaq2024-01-01T00:00:00Z2024-01-01T00:00:00ZArchival setup using LTO tape with zpaq compression and encryption.... README
sudo mt -f /dev/nst0 rewind
sudo tar -cvf /dev/nst0 README
```
The above made sure the tape was rewound, and we added README. Let's rewind the tape and check the contents, and then after we check the contents move back to end of memory or whatever:
```
sudo mt -f /dev/nst0 rewind
sudo tar tvf /dev/nst0
sudo mt -f /dev/nst0 eom
```
I don't think zpaq can stream so I can't pipe to tar I don't think, so I zpaq the older automatic backup directories i want to remove soon (before putting on tape):
```
mkdir /home/baudrillard/zpaq-to-tape
sudo zpaq a /home/baudrillard/zpaq-to-tape/simulacra-server-restic-backups.zpaq /media/root/BackupRAID/simulacra-server-restic-backups
sudo zpaq a /home/baudrillard/zpaq-to-tape/duplicity-coffeepad-deja-dup.zpaq /media/root/BackupRAID/sftpbackups/backup_coffee/backups-auto/coffeepad-deja-dup
sudo zpaq a /home/baudrillard/zpaq-to-tape/duplicity-fzg2.zpaq /media/root/BackupRAID/sftpbackups/backup_coffee/backups-auto/fzg2
sudo zpaq a /home/baudrillard/zpaq-to-tape/duplicity-simulation.zpaq /media/root/BackupRAID/sftpbackups/backup_coffee/backups-auto/simulation-deja-dup
sudo zpaq a /home/baudrillard/zpaq-to-tape/duplicity-toughbook-begin-2021-03-13.zpaq /media/root/BackupRAID/sftpbackups/backup_coffee/backups-auto/toughbook-begin-2021-03-13
sudo zpaq a /home/baudrillard/zpaq-to-tape/duplicity-x390_waiting_on_fzg2.zpaq /media/root/BackupRAID/sftpbackups/backup_coffee/backups-auto/x390_waiting_on_fzg2
```
Now I can add them all (make sure we're at eom):
```
sudo mt -f /dev/nst0 eom
sudo tar -cvf /dev/nst0 /home/baudrillard/zpaq-to-tape/*.zpaq
```
Finally check the contents again:
```
sudo mt -f /dev/nst0 rewind
sudo tar tvf /dev/nst0
sudo mt -f /dev/nst0 eom
```
Eject and mark as read-only!
Don't be alarmed if it looks like only README is there! You just have to skip through files:
```
sudo mt -f /dev/nst0 rewind
sudo mt -f /dev/nst0 fsf 1
sudo tar tvf /dev/nst0
```
### ChatGPT: It looks like it's not all there!
> The behavior you're experiencing with `tar` and your tape drive (`/dev/nst0`) suggests that the `README` file was the first file written to the tape and the subsequent `*.zpaq` files wer]]>