Dockerizing your Bun app is a breeze with this super minimal Dockerfile. Follow me on the journey to make it production-ready! 🐳🚀
FROM oven/bun COPY . . RUN bun install CMD ["bun", "index.ts"]
Make sure to change
index.ts to your entry point and then build it like this:
docker build -t bun-minimal .
As always with Docker, you can improve your Docker image in a few easy ways. Let's look at the two most obvious ways, copying only what you need (improving caching!) and multi-stage builds (improving the image size!) 🚀
A lot of the time that your docker build takes comes from expensive I/O operations or the inability to cache single steps of your build process.
Firstly, create a
.dockerignore file with everything that you do not want in your Docker image. This usually includes stuff like your
node_modules, compiled files, or documentation. Simply write the folder names that you want to be ignored in a file, or copy an existing one.
node_modules README.md LICENSE
If you are actively developing your app and you need to constantly rebuild your Docker Image, chances are that your code changes a lot more than your dependencies. You can profit from that fact by separating the install and build steps. Docker will then only re-install your dependencies if they actually changed! 🥳
FROM oven/bun # Copy the lock and package file COPY bun.lockb . COPY package.json . # Install dependencies RUN bun install --frozen-lockfile # Copy your source code # If only files in the src folder changed, this is the only step that gets executed! COPY src ./src CMD ["bun", "index.ts"]
If you want to be a bit fancier or you need a smaller Docker image, you can also use bun to bundle an executable.
This will compile your code to a standalone binary that includes the Bun runtime. You can then create a multi-stage build, reducing your image size by around 35%
We take the Dockerfile from the previous step as the template but extend it by not using bun run, but bun build. We then copy the compiled binary and create a new Ubuntu image that only includes this binary. This simple step reduces our build size by 88 Megabyte! 🤯
FROM oven/bun AS build # tag it as build WORKDIR /app COPY bun.lockb . COPY package.json . RUN bun install --frozen-lockfile COPY src ./src # compile everything to a binary called cli which includes the bun runtime RUN bun build ./src/index.ts --compile --outfile cli FROM ubuntu:22.04 # use a smaller image without bun WORKDIR /app # copy the compiled binary from the build image COPY --from=build /app/cli /app/cli # execute the binary! CMD ["/app/cli"]
How was your experience developing and deploying Bun? I've really enjoyed it so far, although there is still a lot of work to do to make it truly great. I'd love to hear your opinions!