docker-practice

1) Python

3) Go

5) Kotlin

7) Conclusion

PYTHON


1) Unoptimized build

 FROM ubuntu:latest
 MAINTAINER Michael Chirozidi 'chirozidi.m@gmail.com'
 RUN apt-get update -qy
 RUN apt-get install -qy python3.10 python3-pip python3.10-dev
 COPY . /app
 WORKDIR /app
 RUN pip install pipreqs
 RUN pipreqs &&  echo 'uvicorn[standard]==0.21.1' >> requirements.txt
 RUN pip install -r requirements.txt
 CMD ["uvicorn", "spaceship.main:app", "--host=0.0.0.0","--port=8080"] 

3) Dockerfile optimization

 FROM python:slim-bullseye
 MAINTAINER Michael Chirozidi chirozidi.m@gmail.com
 COPY requirements/backend.in .
 RUN pip install --no-cache-dir -r backend.in
 COPY . .
 CMD ["uvicorn", "spaceship.main:app", "--host=0.0.0.0", "--port=8080"] 

4) Upgrading of app.py


5) NumPy

 NumPy==1.24.3
 fastapi==0.95.0
 pydantic==1.10.7
 starlette==0.26.1
 uvicorn[standard]==0.21.1
 pyproject.toml==0.0.10 

On Bullseye

On Alpine

 FROM python:alpine
 MAINTAINER Michael Chirozidi chirozidi.m@gmail.com
 RUN apk add --no-cache musl-dev g++ gcc lapack-dev
 WORKDIR /app
 COPY requirements/backend.in .
 RUN pip install --no-cache-dir -r backend.in
 COPY . .
 CMD ["uvicorn", "spaceship.main:app", "--host=0.0.0.0", "--port=8080"]

GOLANG

1) Default build

 FROM golang:latest
 MAINTAINER Michael Chirozidi chirozidi.m@gmail.com
 WORKDIR /app
 COPY go.mod go.sum ./
 RUN go mod download
 COPY . .
 RUN go build -o build/fizzbuzz
 EXPOSE 8080
 CMD ["./build/fizzbuzz", "serve"] 

2) Multi-stage building with Scratch

 FROM golang:latest AS builder
 MAINTAINER Michael Chirozidi chirozidi.m@gmail.com
 WORKDIR /app
 COPY go.mod go.sum ./
 RUN go mod download
 COPY . .
 RUN CGO_ENABLED=0 go build -ldflags "-w -s -extldflags '-static'" -o build/fizzbuzz
 
 FROM scratch
 COPY --from=builder /app/build/fizzbuzz /
 COPY --from=builder /app/templates/index.html /templates/
 EXPOSE 8080
 CMD ["./build/fizzbuzz", "serve"] 

3) Multi-stage building with Distorless

 FROM golang:latest AS builder
 MAINTAINER Michael Chirozidi chirozidi.m@gmail.com
 WORKDIR /app
 COPY go.mod go.sum ./
 RUN go mod download
 COPY . .
 RUN go build -o build/fizzbuzz
 FROM gcr.io/distroless/base
 COPY --from=builder /app/build/fizzbuzz /
 COPY --from=builder /app/templates/index.html /templates/
 EXPOSE 8080
 CMD ["./build/fizzbuzz", "serve"] 

If we compare using a Scratch image and a Distroless image as the base, Scratch allows us to create a highly optimized and lightweight image that contains only the necessary components and dependencies. However, it requires manually installing all the dependencies and libraries inside the image, which takes time and expertise, and may not be the best choice during development.

Distroless images are designed to be used with specific programming languages and frameworks such as Java, Python, or Node.js, and already include dependencies and libraries for those languages and frameworks. Therefore, if you don’t want to deal with manually installing dependencies and libraries and prefer to use a ready-made image that already contains all the necessary components to run your program, a Distroless image can be the best choice.

It should be noted that using a multi-stage build, regardless of the choice of the base image, is more optimal compared to using a golang-based image for the reasons mentioned earlier.


KOTLIN

1) Code of simple server on Ktor framework for Kotlin language

fun Application.module() { configureSerialization() configureRouting() }

* Serialization.kt:
```Kotlin
fun Application.configureSerialization() {
    install(ContentNegotiation) {
        json()
    }
    helloWorldJson()
}

fun Application.helloWorldJson(){ routing { get(“/json/hello”) { call.respond(HttpStatusCode.OK, mapOf(“hello” to “world”)) } } }

2) Dockerfile for mutli-stage building image
``` Dockerfile
FROM gradle:7-jdk11 AS build
COPY --chown=gradle:gradle . /app
WORKDIR /app
RUN gradle buildFatJar --no-daemon

FROM openjdk:11
EXPOSE 8080:8080
RUN mkdir /server
COPY --from=build /app/build/libs/*.jar /server/kotlin-all.jar
ENTRYPOINT ["java","-jar","/server/kotlin-all.jar"]

CONCLUSION

After familiarizing myself with working with Docker, the following conclusions can be drawn:

In general, working with Docker allows you to simplify the deployment and management of applications, provides portability and consistency of the environment, and allows you to speed up the development process. The choice between different types of images, such as Scratch and Distroless, depends on your needs and project requirements. With Docker, you can create an infrastructure that is easily scalable and maintainable, which contributes to the efficient operation of the software.