How to run bash function in Dockerfile
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A Dockerfile does not keep shell state between RUN instructions, so a Bash function defined in one layer is gone in the next one. If you want to use a Bash function during image build, define and call it in the same RUN step or put the function in a script file and execute that script.
Why the Function Disappears
Each RUN instruction starts a fresh shell process and commits the filesystem changes into a new image layer. Shell functions are in-memory shell state, not files, so they do not survive into the next RUN.
That means this does not work the way people expect:
The second RUN cannot see the function because the first shell process has already exited.
Define and Use the Function in One RUN
If the function is small, keep it in the same instruction:
This works because definition and execution happen in the same Bash process.
The SHELL directive matters here. Docker defaults to /bin/sh -c on many images, and plain sh may not support the Bash function syntax you are expecting.
Prefer Scripts for Anything Non-Trivial
For real build logic, a script file is usually better than a long inline shell expression.
setup.sh:
Dockerfile:
This is easier to read, easier to test locally, and much easier to maintain as the build grows.
Sourcing a Script Also Works
If you want to keep several helper functions in one file and call one of them during a build step, source the file in the same RUN:
Again, it all happens in one shell process. That is the rule to remember.
Avoid Treating Dockerfiles Like Interactive Shell Sessions
A Docker build is not an interactive Bash session. It is a sequence of isolated build steps. Files persist between layers, but shell functions, aliases, and local variables do not unless you recreate them each time. That distinction becomes especially important when a Dockerfile grows from a quick prototype into a repeatable build pipeline, because hidden shell state assumptions then start causing non-obvious failures.
Once you understand that separation, the behavior stops being surprising.
Common Pitfalls
The biggest mistake is defining a Bash function in one RUN layer and trying to call it in another. That state does not persist.
Another issue is forgetting that the default shell may be /bin/sh rather than Bash. If the function syntax depends on Bash, set the SHELL directive explicitly or invoke bash -c yourself.
Developers also sometimes pack a large amount of shell logic into one unreadable RUN command. At that point, a script file is the cleaner solution.
Finally, do not confuse environment variables with shell functions. Variables can be made persistent with ENV, but functions are a different kind of shell state.
Summary
- Bash functions do not persist across separate
RUNinstructions. - Define and call the function in the same
RUNstep, or use a script file. - Set the build shell to Bash if your syntax depends on it.
- Source helper scripts and call functions in one shell process.
- For non-trivial logic, prefer scripts over long inline Dockerfile commands.

