The absolute-path + symlink layout added earlier today is awkward to
redeploy against: after a fresh clone the symlinks point at nothing and
compose quietly creates empty directories in their place, so the service
comes up healthy with no history.
/root/apps/ holds services only, so the images and the SQLite database
live in the project again as ./output and ./data, bind-mounted with
relative paths. Backups are handled by a separate hook that copies to
/root/backup_files/ai-image/, which is not part of /root/apps/.
Both directories stay gitignored.
The output/ and data/ directories lived inside this git repo. They are
gitignored, so any rebuild of the directory (git clone into a recreated
path, rm + clone) silently took the generated images and the SQLite
database with it. On 2026-11-04 that cost a full round of regenerated
images.
The real data now lives in /root/apps/ai-image-data/:
output/ generated images, one subdirectory per profile_name
data/ ai_image.db + secret.key
Bind mounts use absolute paths so the container never depends on symlink
resolution. ./output and ./data remain as symlinks for backwards
compatibility with existing scripts and skills.
Also ignore the symlinks themselves: the directory-form rules do not
match them, so git would have picked them up.