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.
31 lines
909 B
Docker
31 lines
909 B
Docker
FROM alpine:3.20
|
|
|
|
RUN apk add --no-cache \
|
|
bash \
|
|
docker-cli \
|
|
git \
|
|
nodejs \
|
|
npm \
|
|
openssh-client \
|
|
gzip
|
|
|
|
WORKDIR /app
|
|
|
|
# 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
|
|
|
|
ENTRYPOINT ["/entrypoint.sh"]
|
|
CMD ["crond", "-f", "-l", "2"]
|