Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hackathon 2024][Gadolinium][Docker] Use Docker multi-stage build #109

Open
MP-Aubay opened this issue May 30, 2024 · 0 comments
Open

[Hackathon 2024][Gadolinium][Docker] Use Docker multi-stage build #109

MP-Aubay opened this issue May 30, 2024 · 0 comments
Assignees
Labels
ecoCode-CI/CD Hackathon 2024 New issues tagged during the hackathon 2024 spotter

Comments

@MP-Aubay
Copy link
Contributor

MP-Aubay commented May 30, 2024

(Existing rule in draft : green-code-initiative/creedengo-common#44)

Rule title

Use Docker multi-stage build

Language and platform

Docker

Rule description

Multi-stage builds let you reduce the size of your final image, by creating a cleaner separation between the building of your image and the final output. Split your Dockerfile instructions into distinct stages to make sure that the resulting output only contains the files that's needed to run the application.
https://docs.docker.com/develop/develop-images/guidelines/

Noncompliant Code Example

For NodeJS :

FROM node:lts

COPY package*.json ./
    
RUN npm install

COPY . .

RUN npm run build

CMD ["node", "index.js"]

For Maven :

FROM maven:3.9-eclipse-temurin-17

COPY ./ ./
    
RUN mvn clean package

CMD ["java", "-jar", "target/app.jar"]

For C :

FROM gcc

COPY hello.c .

RUN gcc -o hello hello.c

CMD ["./hello"]

For GO :

FROM golang

COPY hello.go .

RUN go build hello.go

CMD ["./hello"]

Compliant Solution

For NodeJS :

FROM node:lts AS builder

COPY package*.json ./
    
RUN npm install

COPY . .

RUN npm run build

FROM node:lts-alpine

COPY package*.json ./

RUN npm install --only=production

COPY --from=builder /dist ./

CMD ["node", "index.js"]

For Maven :

FROM maven:3.9-eclipse-temurin-17 AS builder

COPY ./ ./
    
RUN mvn clean package

FROM eclipse-temurin:17-alpine

COPY --from=builder /target/app.jar ./app.jar

CMD ["java", "-jar", "app.jar"]

For C :

FROM gcc AS builder

COPY hello.c .

RUN gcc -o hello hello.c

FROM ubuntu

COPY --from=builder hello .

CMD ["./hello"]

For GO :

FROM golang AS builder

WORKDIR /src

COPY hello.go .

RUN go build hello.go

FROM ubuntu

COPY --from=builder /src/hello .

CMD ["./hello"]

Rule short description

Using build commands will produce files not needed to run the application, you should use Docker multi-stage build.

Rule justification

Using Docker multi-stage build can reduce the size image and can reduce energy consumption.

Why it matters:

  • For the image itself:
    • Image Size Reduction : Larger images require more storage, more time to transfer, and more resources to load into memory and execute.
  • For the containers created from the image:
    • Startup time: The more layers an image has, the longer it will take for the container to start up because each layer must be pulled from the registry and loaded into memory. This can be noticeable if you have many small layers, as the overhead of loading each layer can add up.
    • Disk usage: Each layer in an image adds to the size of the final image, which in turn affects the disk usage of the container. This can become a problem if you have many images or if you're working with limited disk space.
    • Security: Each layer in an image represents a potential attack surface, so minimizing the number of layers can improve the security of your container. This is because each layer can potentially contain vulnerabilities or malicious code that could be exploited

Official documentation :
https://docs.docker.com/develop/develop-images/guidelines/
https://docs.docker.com/build/building/multi-stage/

Scientific article :
https://assets-eu.researchsquare.com/files/rs-3276965/v1_covered_8dc408b5-6997-486a-89c8-a5c66fddf60e.pdf?c=1693976849

Measurement (from the scientific article) :

Docker Images with Original Image size Obtained Image size Image size Reduced
Being lazy couch potatoes 1.47GB 1.47GB 0%
Using multistage builds 1.47GB 41.6MB 97.17%

Severity / Remediation Cost

Severity : Major, using build commands without multi-stage build will increase the image size, sometimes by ten or more.

Remediation cost : Medium, user need to understand how multi-stage build works and modify the Dockerfile.

Implementation principle

The general idea is to check in Dockerfile the presence of RUN command with build commands, for example mvn clean package or gcc -o hello hello.c.
If there is such commands after the last FROM then the rule should break.

This rule will evolve as we add new build commands to check.

Identified commands :
mvn *
npm *
gcc *
go *

@MP-Aubay MP-Aubay added Hackathon 2024 New issues tagged during the hackathon 2024 spotter labels May 30, 2024
@MP-Aubay MP-Aubay changed the title [Hackathon 2024][GADOLINIUM][Docker] Use Docker multi-stage build [Hackathon 2024][Gadolinium][Docker] Use Docker multi-stage build May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ecoCode-CI/CD Hackathon 2024 New issues tagged during the hackathon 2024 spotter
Projects
None yet
Development

No branches or pull requests

2 participants