Bake cron scripts into the image instead of bind-mounting them
DokPloy's redeploy process rm -rf's the host code dir and recreates it. The cron container is `restart: unless-stopped` so docker-compose doesn't recreate it when only scripts/* change — but its bind mount on ./scripts:/app/scripts then points at orphaned inodes inside the running container, leaving /app/scripts empty until someone manually `docker restart`s it. Bake the scripts into the image instead. A scripts/* change now forces a Dockerfile rebuild → docker-compose recreates the cron service → fresh /app/scripts inside, no manual restart required. content/ and .git/ stay bind-mounted because the export job needs to write commits the host can see. Also adds .dockerignore so the host's scripts/node_modules (potentially darwin-specific) doesn't get COPY'd into the alpine image and shadow the deps installed by `npm install` at build time.
This commit is contained in:
parent
8ea553c304
commit
83c987bb71
3 changed files with 28 additions and 5 deletions
16
.dockerignore
Normal file
16
.dockerignore
Normal file
|
|
@ -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
|
||||||
|
|
@ -11,14 +11,18 @@ RUN apk add --no-cache \
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install script dependencies at /app/node_modules. The /app/scripts dir is
|
# Install script dependencies at /app/node_modules. Node ESM walks up from
|
||||||
# a read-only host mount at runtime, so deps can't live inside it. Node ESM
|
# the importing file (/app/scripts/*.js) and finds node_modules at /app.
|
||||||
# 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.
|
|
||||||
# (NODE_PATH is intentionally NOT used: ESM resolution ignores it.)
|
# (NODE_PATH is intentionally NOT used: ESM resolution ignores it.)
|
||||||
COPY scripts/package*.json ./
|
COPY scripts/package*.json ./
|
||||||
RUN npm install --omit=dev
|
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/crontab /etc/crontabs/root
|
||||||
COPY cron/entrypoint.sh /entrypoint.sh
|
COPY cron/entrypoint.sh /entrypoint.sh
|
||||||
RUN chmod +x /entrypoint.sh
|
RUN chmod +x /entrypoint.sh
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,10 @@ services:
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
volumes:
|
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
|
- ./content:/app/content
|
||||||
- ./.git:/app/.git
|
- ./.git:/app/.git
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue