Making Containers Lightweight

Containers are considered to be lightweight. Have you ever wondered what makes them lightweight? ?What we can do to make our containers as light as possible?

Well, when we run applications on Virtual Machines, we use host’s OS and Kernel along with other resources and filesystem while containers package minimal application required dependencies and are easy to start reducing time to deployment.

A basic ubuntu server image’s minimal installation takes 200-500 MB, while docker’s official ubuntu image with minimal installation are around 29-60MB, subsequently making containers lightweight.

There are multiple strategies which we can use to make containers lightweight, thus more efficient. Below are some of the most commonly used ways:

Choosing the right Image:

Choosing the right base image to run containers can impact the performance and efficiency of container. In some cases using full Linux distribution would be more suitable, sometimes reducing the size of image and increasing efficiency could be the priority. Depending upon the use case one can choose from the below:

Distro Images:

  • These are built directly from standard OS distribution and are usually larger in size as they include complete distribution with a wide range of system libraries.
  • They can be best suited wherein compatibility with Standard OS packages is important.
  • Eg. Ubuntu:20.04, ubuntu:18.04, etc.

Alpine Images:

  • Alpine image uses Musl libc and BusyBox which are lighter than usual GNU libraries making the images lightweight. These are smaller in size ranging from 5-10 MB.
  • These are best suited for critical operations where time complexity of operations matter.
  • Eg. Node: 14-alpine, alpine:latest, etc.

Slim Images:

  • These are built from standard Debian or ubuntu images but with non-essential packages and files removed.
  • Ideal where minimizing image size is essential and attack surface needs to be reduced.
  • Eg. python:3.9-slim, node:14-slim, etc.

Distorless Images:

  • These images are provided by Docker and only contain essential runtime required for the application to run. They do not have any shell utilities, package managers and any other binaries for the OS.
  • These are best suited to enhance security of the system, reduce attack surface as they do not have any shell. With fewer libraries and components, there is less overhead and better performance and efficiency.
  • Eg: gcr.io/distroless/nodejs:14, etc.

** Slim, Apline and Distro Images can be pulled from Dockerhub. Distorless images can be pulled from Google’s Container Registry.

Multi Staged Images

Multi Staged Images separate build environment from runtime environment. This reduces the size of the image by removing unwanted build files in the final image. Each stage in Dockerfile operates independently and can have different base images. Files from each of the stage can be used in subsequent stages. One can build code with all the dependencies in one stage and can pass only the compiled and cleaner code in final stage. Thus, reducing the size of the image.

Sample Dockerfile for Multi Staged Image:

# Stage 1: Build
FROM maven:3.8.6-openjdk-17 AS build

# Set the working directory
WORKDIR /app

# Copy the Maven POM file and source code
COPY pom.xml .
COPY src ./src
# Build the application
RUN mvn clean package -DskipTests

# Stage 2: Runtime
FROM openjdk:17-jdk-slim

# Set the working directory
WORKDIR /app

# Copy the built JAR file from the build stage
COPY --from=build /app/target/myapp.jar ./myapp.jar

# Expose the port the app runs on
EXPOSE 8080

# Command to run the application
CMD ["java", "-jar", "myapp.jar"]        

Where:

Build Stage

“FROM maven:3.8.6-openjdk-17 AS build”- Naming first stage as Build and pulling maven:3.8.6-openjdk-17 as base image for the same.

Further setting up the current directory and building the application using “RUN mvn clean package -DskipTests”.

Runtime Stage

“FROM openjdk:17-jdk-slim”- Using a slimmer version of java to run the image. Setting up the directory and copying files from prior stage to current stage using:

COPY --from=build /app/target/myapp.jar ./myapp.jar

Further exposing port and running the application.

In this way we can use multi staged images to reduce container's size and enhance efficiency.

Dockerignore

Docker can ignore the files present in the working directory if configured in the .dockerignore file. It also improves caching by ignoring unnecessary files and prevents unnecessary cache invalidation.

By above mentioned ways we can reduce the size of Docker containers as per requirements.



要查看或添加评论,请登录

Mehak Talwar的更多文章

  • Streamlining Network Connections with AWS Transit Gateway

    Streamlining Network Connections with AWS Transit Gateway

    AWS Transit Gateway provides a hub and spoke architecture for connecting VPCs and on-premises networks as a fully…

    1 条评论
  • Securing AWS S3 Buckets

    Securing AWS S3 Buckets

    Amazon Simple Storage Service- S3 is a highly scalable and durable data storage solution. However, since S3 is…

  • Docker Compose: Simplifying development and testing in lower environments

    Docker Compose: Simplifying development and testing in lower environments

    Docker Compose is a tool for defining and running multi-container applications. It is the key to unlocking a…

    1 条评论
  • Dockers and Containers

    Dockers and Containers

    In today's fast-paced tech landscape, where agility, scalability, and efficiency are paramount, Containers have emerged…

    3 条评论

社区洞察

其他会员也浏览了