How can I run script automatically after Docker container startup
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To run a script automatically when a Docker container starts, the standard solution is to use an entrypoint script. That script runs as the container process or as a wrapper around the main process, performs startup work, and then execs the real application. The key detail is that containers should still end up with one main foreground process, not a shell script that spawns background work and exits unpredictably.
The Basic Docker Startup Model
Docker starts a container by running the image’s ENTRYPOINT and CMD. The most reliable pattern is:
- copy a startup script into the image
- make it executable
- set it as
ENTRYPOINT - have the script finish by running the main service with
exec
That gives you a place to run initialization logic before the application begins serving.
Example Dockerfile
The entrypoint script will always run, while CMD supplies the default application command.
Example entrypoint.sh
The final exec "$@" matters. It replaces the shell with the target process so signals such as SIGTERM are delivered correctly to the application.
Why exec Matters
Without exec, the shell remains PID 1 and the actual application runs as a child. That can break signal handling and shutdown behavior.
Bad pattern:
Better:
Or, when using CMD, just:
That keeps the container aligned with Docker’s process model.
Running One-Time Initialization
Entrypoint scripts are often used for:
- generating config files
- waiting for dependent services
- running database migrations
- creating directories or permissions
Example:
This is common, but it should still be designed carefully. If migrations fail, the container should fail fast rather than continuing in a bad state.
ENTRYPOINT Versus CMD
Use ENTRYPOINT for the fixed startup wrapper. Use CMD for the default command or arguments that the wrapper ultimately runs.
If you put everything in CMD, a caller can easily override it and skip your startup logic. If you put everything in ENTRYPOINT, overrides become more awkward. The combination shown above is usually the right balance.
Docker Compose Example
Compose can still use the same pattern:
If you override command: in Compose, the entrypoint script still runs and receives the new command through "$@".
Avoid Backgrounding the Main Process
One common mistake is starting the real service in the background and letting the shell script end.
Bad:
If the script exits, the container may stop even though you expected it to keep running. The main application should stay in the foreground as the container’s primary process.
When a Wrapper Script Is Not Needed
If all you need is to run a single program directly, skip the wrapper and use ENTRYPOINT or CMD directly.
Use a startup script only when there is real initialization work to do. Otherwise it adds indirection without value.
Common Pitfalls
The biggest mistake is writing an entrypoint script that does setup work but never execs the real application. Another is running the main process in the background, which breaks the container lifecycle. Teams also often overload startup scripts with too much orchestration logic that would be better handled elsewhere, such as in deployment tooling. Finally, if the script depends on tools like bash but the base image only has sh, the container fails before startup logic even begins.
Summary
- Use an entrypoint script when you need startup logic before the main application begins.
- End the script with
exec "$@"orexec your-commandso signal handling works correctly. - Keep the main process in the foreground.
- Use
ENTRYPOINTfor the wrapper andCMDfor default application arguments. - Skip the wrapper entirely if there is no real initialization work to perform.

