Run a script in Dockerfile
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Running a script from a Dockerfile can mean two different things: executing a script while the image is being built or arranging for a script to run when a container starts. Those are different phases with different instructions. The key is to choose RUN for build-time actions and CMD or ENTRYPOINT for container startup behavior.
Build-Time Script Execution With RUN
If the script installs packages, prepares files, or compiles assets into the image, execute it during the build with RUN.
A common pattern is to copy the script into the image, make it executable, and then run it:
An example setup.sh might be:
Everything done by RUN becomes part of the image layer produced at build time.
Runtime Script Execution With CMD or ENTRYPOINT
If the script should execute when the container starts, use CMD or ENTRYPOINT instead.
And the script:
This script runs each time a container starts from the image. That is very different from RUN, which executes only when you build the image.
When to Use Which Instruction
Use RUN when the script:
- installs dependencies
- generates build artifacts
- prepares the filesystem inside the image
- should not run again every time the container starts
Use CMD or ENTRYPOINT when the script:
- launches the application
- performs startup initialization
- reads runtime environment variables
- must execute every time a container is started
A simple mental model is: RUN changes the image, while CMD and ENTRYPOINT define container behavior.
Prefer Small, Transparent Scripts
Scripts inside Docker builds should usually be short and predictable. If the logic is only one or two shell lines, writing it directly in the Dockerfile can be clearer:
Use an external script when it improves readability, is reused elsewhere, or contains enough logic that embedding it would make the Dockerfile harder to maintain.
Also keep line endings in mind. Shell scripts copied from Windows environments often fail in Linux containers because of carriage-return characters. If a script inexplicably will not execute, check the file format.
Exec Form Is Usually Better
For CMD and ENTRYPOINT, prefer the JSON exec form:
This avoids an extra shell layer and gives cleaner signal handling. Good signal handling matters because containers should stop cleanly when they receive termination signals.
If your startup script launches the main process, use exec inside the script so the target process becomes PID 1:
That small detail improves shutdown behavior a lot.
A Full Example
This image uses one script during the build to prepare assets and another at runtime to start the service.
Common Pitfalls
The most common mistake is using RUN for something that should happen when the container starts. That script runs only during image build, so the expected runtime behavior never appears.
Another mistake is forgetting to copy the script into the image or forgetting to set executable permissions.
Developers also often use shell-form CMD or ENTRYPOINT without realizing it changes signal handling and argument parsing.
Finally, startup scripts should usually end with exec when they launch the main process. Without it, container shutdown can become awkward and less predictable.
Summary
- Use
RUNto execute scripts during image build. - Use
CMDorENTRYPOINTto execute scripts when a container starts. - Copy scripts into the image and mark them executable.
- Prefer exec-form
ENTRYPOINTorCMDfor cleaner runtime behavior. - Keep scripts small and use
execin startup scripts when launching the main process.
Related reading
- Run a script when docker is stopped
- Run Database as Docker container or on a bare metal server?
- Run docker in ubuntu live disk
- Run Grunt / Gulp inside Docker container or outside?
- Run a Tensorflow model without having Tensorflow installed
- Run inference using Onnx model in python?
- running a container with runAsNonRoot and add capabilities
- Running a daemonset on all nodes of a kubernetes cluster

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.