diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..60a1d77 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,16 @@ +# Don't ship the host's node_modules into images — they may contain +# darwin-specific binaries and would shadow the deps installed by `npm +# install` inside the container. +**/node_modules + +# Backups, exported content, git history — none of these belong in any +# of our images. The cron service mounts what it actually needs. +backups/ +content/ +.git/ + +# Editor / tool noise +.cursorignore +.cursorindexingignore +.DS_Store +**/.DS_Store diff --git a/cron/Dockerfile b/cron/Dockerfile index 7c32432..d2ca6cc 100644 --- a/cron/Dockerfile +++ b/cron/Dockerfile @@ -11,14 +11,18 @@ RUN apk add --no-cache \ WORKDIR /app -# Install script dependencies at /app/node_modules. The /app/scripts dir is -# a read-only host mount at runtime, so deps can't live inside it. Node ESM -# walks up from the importing file looking for node_modules — /app is the -# parent of /app/scripts, and /app itself is NOT mounted, so this works. +# Install script dependencies at /app/node_modules. Node ESM walks up from +# the importing file (/app/scripts/*.js) and finds node_modules at /app. # (NODE_PATH is intentionally NOT used: ESM resolution ignores it.) COPY scripts/package*.json ./ RUN npm install --omit=dev +# Bake the scripts into the image rather than bind-mounting them. DokPloy +# rm-rf's the host code dir on every redeploy, which would orphan a bind +# mount in the long-running cron container. Baking forces a rebuild + +# recreate whenever scripts change, so the cron always sees current code. +COPY scripts/ /app/scripts/ + COPY cron/crontab /etc/crontabs/root COPY cron/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh diff --git a/docker-compose.yml b/docker-compose.yml index fa16ddf..34cb1bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -76,7 +76,10 @@ services: depends_on: - postgres volumes: - - ./scripts:/app/scripts:ro + # NOTE: scripts/ is intentionally NOT bind-mounted — it's baked into + # the cron image (see cron/Dockerfile) so DokPloy redeploys can't + # orphan it. content/ and .git/ stay mounted because the export job + # writes commits the host needs to see. - ./content:/app/content - ./.git:/app/.git - /var/run/docker.sock:/var/run/docker.sock:ro