Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions kustomize/cronjob/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# cronjob

A `CronJob` that runs the app's own image with a different `command`. Each one
A `CronJob` that runs the app's own image with different `args`. Each one
replaces a single Heroku Scheduler entry. It uses the same security context,
ServiceAccount and `server-secrets` as `node-web-app`, so the job sees the
same env vars as the web process.
Expand Down Expand Up @@ -30,7 +30,7 @@ patches:
path: /spec/schedule
value: "*/20 * * * *"
- op: replace
path: /spec/jobTemplate/spec/template/spec/containers/0/command
path: /spec/jobTemplate/spec/template/spec/containers/0/args
value: ["node", "lib/permissions/run.js"]
```

Expand All @@ -39,5 +39,9 @@ namespace and the `part-of` label, and those apply to the CronJob too.

The base sets `timeZone` to UTC. Heroku Scheduler also uses UTC, so schedules
carry over unchanged. Dead-man-snitch style `&& curl …` suffixes become
`command: ["sh", "-c", "node lib/x.js && curl …"]`; the Node image includes
`args: ["sh", "-c", "node lib/x.js && curl …"]`; the Node image includes
`sh`.

Patch `args`, not `command`. The Node image's ENTRYPOINT is tini, and setting
`command` replaces the ENTRYPOINT, so the job would run without tini as PID 1
and wouldn't stop cleanly on SIGTERM.
6 changes: 4 additions & 2 deletions kustomize/cronjob/cronjob.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ spec:
- name: cron
# Same image as the web Deployment; renamed by the app's deploy/base.
image: electronionicplatform.azurecr.io/PLACEHOLDER_APP:latest
# Replaced by the overlay with the Heroku Scheduler command.
command: ["node", "lib/cron.js"]
# Replaced by the overlay with the Heroku Scheduler command. Set
# as `args`, not `command`: `command` would replace the image's
# ENTRYPOINT, so tini wouldn't run as PID 1.
args: ["node", "lib/cron.js"]
envFrom:
- secretRef:
name: server-secrets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ patches:
path: /spec/schedule
value: "0 6 * * *"
- op: replace
path: /spec/jobTemplate/spec/template/spec/containers/0/command
path: /spec/jobTemplate/spec/template/spec/containers/0/args
value: ["node", "lib/nightly.js"]
10 changes: 10 additions & 0 deletions kustomize/node-web-app/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ spec:
httpGet:
path: /healthz
port: http
lifecycle:
# Keep serving for a few seconds after the pod starts terminating,
# so Envoy Gateway stops routing to it before the app gets SIGTERM
# (tini forwards it and Node exits at once). Uses the kubelet's
# built-in sleep action (GA in Kubernetes 1.34), so the image
# needs no `sleep` binary. Counts against the default 30s
# terminationGracePeriodSeconds.
preStop:
sleep:
seconds: 5
volumes:
- name: tmp
emptyDir: {}
11 changes: 8 additions & 3 deletions templates/Dockerfile.node
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ WORKDIR /app
# root's $HOME, so a `yarn ...` CMD starts as uid 1000 without fetching Yarn
# from repo.yarnpkg.com on every pod start.
ENV COREPACK_HOME=/usr/local/share/corepack
# tzdata is only needed if the app sets TZ. Add `git` here if the app shells
# out to it.
RUN apk add --no-cache tzdata \
# tini: see ENTRYPOINT. tzdata is only needed if the app sets TZ. Add `git`
# here if the app shells out to it.
RUN apk add --no-cache tini tzdata \
&& corepack enable
COPY package.json yarn.lock .yarnrc.yml ./
COPY .yarn/ ./.yarn/
Expand All @@ -45,4 +45,9 @@ EXPOSE 8080
# No HEALTHCHECK: Kubernetes probes /healthz instead (the path can be changed
# in the overlay). For probot apps, use
# CMD ["yarn", "probot", "run", "./lib/index.js"]; probot reads PORT.
# tini runs as PID 1 and forwards SIGTERM to the app. Node (and probot) install
# no SIGTERM handler by default, so without it the kernel ignores the signal
# and every pod waits out the 30s grace period before being SIGKILLed. Keep it
# even if the app adds its own handler.
ENTRYPOINT ["/sbin/tini", "--"]
Comment thread
claude[bot] marked this conversation as resolved.
Resolved
Comment thread
claude[bot] marked this conversation as resolved.
Resolved
CMD ["node", "lib/index.js"]
Loading