Docker cookbook · Intermediate
Write an entrypoint script that handles signals
Run setup steps before the app without breaking graceful shutdown.
Approach
Do the setup in a shell script, then exec "$@" so the app replaces the shell as PID 1 and receives
SIGTERM. Keep the command in CMD so it can be overridden.
Solution
#!/bin/sh
# docker-entrypoint.sh
set -eu
if [ -n "${CONFIG_TEMPLATE:-}" ]; then
envsubst < "$CONFIG_TEMPLATE" > /tmp/app.conf
fi
exec "$@"
FROM alpine:3.24
RUN apk add --no-cache gettext-envsubst
COPY --chmod=0755 docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["my-server", "--config", "/tmp/app.conf"]
Pitfalls
- Running the app without
exec: the shell stays PID 1 and SIGTERM never reaches the app. - Running migrations in every container's entrypoint; with many replicas they race.
Variations
--initortiniwhen the app spawns child processes it doesn't reap.- Run migrations as a separate job instead of in the entrypoint.
Further reading: ENTRYPOINT
Reference: https://docs.docker.com/reference/dockerfile/#entrypoint
More Docker recipes
- Add a healthcheck to an HTTP service
- Build a layered image for a Spring Boot app
- Build a production image for a Node.js service
- Build a production image for a Python web app
- Build, cache and push images in GitHub Actions
- Build one image tag for amd64 and arm64
- Configure nginx from environment variables
- Develop with Compose and live reload