#!/bin/sh set -eu # Ensure runtime directories exist before chowning them; otherwise chown -R on a # bind-mounted or freshly-created named volume can race with MkdirAll in the app. mkdir -p /workspace/data/files /workspace/content # Make the runtime dirs owned by appuser so the Go process can write attachments # and read content even when /workspace/data is a host bind mount created as root # (or a named volume initialized with the container's root uid). chown -R appuser:appuser /workspace/data /workspace/content # Drop to the unprivileged appuser and hand control to the container CMD. # gosu handles signal forwarding and TTY correctly; plain `su` and `su -c` do not. exec gosu appuser "$@" # Smoke test (run on a host with Docker available): # docker compose build app # docker compose up -d app # docker compose exec app id # should print: uid=(appuser) gid=(appuser) # docker compose exec app ls -ld /workspace/data # should be owned by appuser # curl -fsS http://localhost:${PORT:-8080}/healthz