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 .
Improvements
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!) 🚀
Copying only what you need
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.
.dockerignore
🤷
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
Separate Copy Steps
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"]
Multi-Stage Builds
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"]
Next Steps
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!
If you want to go further, check out the next blog post where you learn how to deploy your dockerized Bun App on Hetzner with Sliplane!
Top comments (7)
ERROR: failed to solve: process "/bin/sh -c bun build ./src/index.ts --compile --outfile cli" did not complete successfully: exit code: 1
well that probably means that your code has some error and cant compile.
Hallo
bonjour!
Comment allez-vous
Met mij gaat het goed, hoe gaat het met jou?
Really excited about bun 😍