eratic / docs / 07-troubleshooting.md
723 words

When something is wrong

Roughly in the order things actually go wrong.

The build refuses to run

✗ N image(s) carry GPS coordinates

Working as intended — a photograph would have published your location. Strip location on export from your photo editor (lossless), or:

npm run photos:strip

See docs/06-privacy.md.

Alt text is required / summary errors

Schema validation. The message names the file and the field. Every photograph needs alt; every entry needs summary. Both are load-bearing — see CLAUDE.md.

ImageNotFound for a photo you just deleted

The content store outlives the files. It lives in sites/<site>/node_modules/.astro/data-store.json — not the .astro directory next to it, which is the one you would think to delete.

npm run clean

covers both, plus dist/. This bites every time you remove an entry that had images.

The collection "posts" does not exist or is empty

A warning, not an error, and correct — the collection really is empty. It goes away with the first entry.

Cannot find module '@eratic/core/...'

Usually a fresh clone with no node_modules, or a new subpath that is not in the package's exports map. .astro imports resolve through the wildcard because they carry an extension; a bare .ts subpath needs an explicit entry in packages/core/package.json.

npm install

A change does not appear on the site

Check what is actually live:

ssh -i ~/.ssh/id_ed25519_eratic root@178.104.116.235 \
  'readlink /opt/web/sites/eratic/current'

If that is the release you just deployed, and the page still looks old, it is a browser cache. HTML is served must-revalidate, so a hard reload settles it.

If the entry is missing entirely: it is draft: true, or its pubDate is in the future. Both are excluded from production builds and visible in npm run dev. That is the intended staging mechanism.

A site returns 404 for everything

Almost always the symlink.

ssh -i ~/.ssh/id_ed25519_eratic root@178.104.116.235 \
  'ls -la /opt/web/sites/eratic/current; docker exec web-caddy ls /srv/eratic/current/'

current must be relative (releases/2026…, not /opt/web/...). Caddy resolves it from inside the container, where the absolute path does not exist. deploy.sh creates it correctly; a hand-made link is the usual culprit.

Caddy config changes appear to do nothing

The reload says it succeeded and behaviour does not change.

Confirm the container can see the file:

ssh -i ~/.ssh/id_ed25519_eratic root@178.104.116.235 \
  'diff <(docker exec web-caddy cat /etc/caddy/Caddyfile) /opt/web/caddy/etc/Caddyfile'

If they differ, something is bind-mounting a file instead of a directory. Docker pins single-file mounts to an inode; rsync and most editors replace files by rename, creating a new one. The container then serves the old contents forever. /opt/web/caddy/etc is mounted as a directory precisely to avoid this — see deploy/server/docker-compose.yml.

TLS certificate problems

Caddy fetches certificates on the first request for a hostname. A fresh hostname can take a few seconds; deploy.sh retries five times.

ssh -i ~/.ssh/id_ed25519_eratic root@178.104.116.235 \
  'docker logs web-caddy 2>&1 | grep -i -E "certificate|acme|error" | tail -20'

Most failures are DNS: the name must resolve to 178.104.116.235 before Caddy asks, because Let's Encrypt validates over HTTP.

dig +short blog.eratic.ro @ns1.ird.ro

Let's Encrypt rate-limits repeated failures for the same name. If you have been retrying, wait an hour rather than looping.

Rolling back

./deploy/rollback.sh --list
./deploy/rollback.sh                          # previous release
./deploy/rollback.sh 20260805-110627-6cd485e  # a specific one

Seconds, no rebuild. The last 5 releases are kept.

The server itself

ssh -i ~/.ssh/id_ed25519_eratic root@178.104.116.235

docker ps                                    # caddy should be Up
cd /opt/web/caddy && docker compose logs --tail 50
df -h /                                      # releases are hard-linked; disk is rarely the issue
free -m                                      # the whole stack idles around 18 MB
ufw status                                   # 22, 80, 443 only

Restart the web server:

cd /opt/web/caddy && docker compose restart

Rebuilding the server from nothing

If the box is lost entirely:

ird vps create web --tier 0x --image ubuntu-24.04 --ssh-key <id>
ird dns set eratic.ro @ A <new-ip>          # and www, blog, fav, io, media
# update SERVER in deploy/bootstrap.sh and deploy/deploy.sh
./deploy/bootstrap.sh
npm run deploy

About ten minutes, most of it waiting for apt. Everything except the contents of media/ is reproducible from this repository — which is why media/ is the one directory that needs a backup of its own.

static mirror of HEAD · about · clone: git clone https://git.makefuture.ro/eratic.git