DEV Community

Cover image for 5 Best Practices when deploying a Docker Container🚀
Shrijal Acharya
Shrijal Acharya

Posted on • Edited on

5 Best Practices when deploying a Docker Container🚀

Ahoy, Docker adventurers!🚀 Ready to set sail into the Docker universe? Get ready for simple yet smart container advice – let's make Docker a breeze! 🐳


Best Practices🚩

Let's get straight into it. These are my top 5 best practices to follow when creating a docker container.


✅ Use Smaller Base Image

💡If possible, never ever use big base images.

In Docker Hub when choosing for any images, you will see a bunch of image with it's OS.

Best Practice 1 - Docker Image with OS

If there is an alpine OS version of the image you are looking for then try to use it always.

It comes with just the tools you need and is very lightweight compared to any other versions🔥.

By doing so you need a very small storage capacity for the image itself and also reduce the attack surface since it does not come with whole bunch of unnecessary tools.

There is a clear performance difference between choosing a lightweight alpine image vs a full blown debian.

Debian: 🐢

time docker run --rm debian sh -c "apt-get update && apt-get install curl"

real    0m27.928s
user    0m0.019s
sys 0m0.077s
Enter fullscreen mode Exit fullscreen mode

Alpine:⚡

time docker run --rm alpine sh -c "apk update && apk add curl"

real    0m5.698s
user    0m0.008s
sys 0m0.037s
Enter fullscreen mode Exit fullscreen mode

✅ Always use .dockerignore file

💡Use .dockerignore to ignore files that are not needed for your container.

Don't push the unnecessary build folders such as dist or build and files such as README.md and Dockerfile itself. They are not needed to run our container and take up unnecessary space.

So, with .dockerignore we reduce the image size.😉


✅ Use Specific Docker Image Version

💡When choosing a base image never choose the latest tag.
Use a specific version.

This is a very bad practice ❌

FROM python
Enter fullscreen mode Exit fullscreen mode

You know, in the future, even the smallest change could accidentally bring in a bug, or worse, break your application. 🥲

This is a good practice ✅

FROM python:3.11
Enter fullscreen mode Exit fullscreen mode

✅ Do not use the root user

💡Try to use the least privileged user when running the container.

By default, when Dockerfile does not specify a user, it uses the root user. You do not want to run the container with root privilege. ❌

Running the container with root access makes it easier for a hacker to exploit the application inside the container.

To avoid this create a specific user and use it to run all the processes.


# Setup group and user
RUN groupadd -r limiteduser && useradd -g limiteduser limiteduser
RUN chown -R limiteduser:limiteduser /app

# This switches the user from root to limiteduser
USER limiteduser
Enter fullscreen mode Exit fullscreen mode

✅ Use multi-stage builds

💡Again, this helps reduce the image size.

Imagine you're baking a cake: you gather ingredients, mix them, and bake. But what if you could magically remove all the mixing bowls and just keep the final cake?😲

That's what multi-stage builds do! They help build containers in stages, and you only keep the necessary parts.

It allows you to use multiple temporary image during build, but keep only the final image.

This is a sample Dockerfile example that uses multi-stage build.

# Stage 1: Build the application
FROM python:3.8 AS build
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .

# Stage 2: Create the final container
FROM python:3.8-slim
WORKDIR /app
COPY --from=build /app /app
CMD ["python", "app.py"]

Enter fullscreen mode Exit fullscreen mode

So, that is it for this article. Hope this is useful for every one of you. 🤗

If you think of any other helpful tips that I haven't covered in this article, please don't hesitate to share them in the comments section below. 🔥


Let's stay connected👋

See you next time✌️

Top comments (5)

Collapse
 
chuniversiteit profile image
Chun Fei Lung

Alpine may be small, but in my experience it’s also very good at suddenly breaking builds and being the root cause of unexpected issues.

Collapse
 
josh_navarro_d69e76fa6bd3 profile image
Josh Navarro

Most of this comes down the implementation of its C library. There are also minor performance considerations when using musl over glibc.

Collapse
 
shricodev profile image
Shrijal Acharya

I understand. Alpine's small size might occasionally cause surprises. But I haven't had any issues with it up until now.😮‍💨

Collapse
 
robsongrangeiro profile image
Robson Grangeiro

Nice hints!

Collapse
 
shricodev profile image
Shrijal Acharya

🙌