Qui n’a jamais douté de la création de la bonne image Docker pour son application ? Eh bien, j'ai posé cette question plusieurs fois et je ne savais presque toujours pas si je la faisais bien ou mal.
Donc, dans cet article, nous explorerons des pratiques avancées pour créer des images Docker efficaces et optimisées pour vos applications Go. Nous comparerons différentes approches, telles que l'utilisation des images de base alpines et scratch, et discuterons des avantages de chacune, avec des exemples de code et. performances d'analyse.
Tout d'abord, établissons une structure de projet typique pour une application Go conteneurisée.
A titre d'exemple, j'utilise cette application qui est un raccourcisseur d'URL :
url_shortener ├── cmd │ └── main.go ├── internal │ ├── monitoring │ │ └── prometheus.go │ ├── server │ │ └── server.go │ └── shortener │ ├── model.go │ ├── repository.go │ ├── service.go │ └── service_test.go ├── pkg │ ├── api │ │ └── shortener │ │ ├── handler.go │ │ └── handler_integration_test.go │ └── utils │ └── base62 │ ├── hash.go │ └── hash_test.go ├── Dockerfile ├── Dockerfile.alpine ├── Dockerfile.golang ├── README.md ├── compose.yml ├── go.mod ├── go.sum └── prometheus.yml
Ce que peu de gens savent, c'est que nous n'avons pas besoin d'une image « complète » en production. Par exemple, Ubuntu avec tous les packages, sources, extensions et un SDK pour notre langage. Nous pouvons simplement créer notre application dans un système avec un SDK, puis copier la version dans une image plus petite et optimisée qui exécutera uniquement cette version. Et c'est là qu'intervientMulti-Stage
.Dans le Dockerfile, vous pouvez définir plusieurs étapes de construction, chacune commençant par une instruction FROM. La première étape peut être utilisée pour compiler le code, installer des dépendances, exécuter des tests, etc. Dans les étapes suivantes, vous pouvez copier uniquement les artefacts nécessaires (tels que les binaires compilés) dans l'image finale, en supprimant tout ce qui n'est pas nécessaire pour exécuter l'application.
# syntax=docker/dockerfile:1 # Build stage FROM golang:1.22-alpine AS builder WORKDIR /app COPY . . RUN go mod download RUN go build -o url-shortener ./cmd # Final stage FROM alpine:latest WORKDIR /app COPY --from=builder /app/url-shortener . CMD ["./url-shortener"]
Wow Rafa, mais que fais-tu avec « ces deux images » ? J'utilise d'abord une image comme constructeur, c'est là que nous créons l'exécutable de l'application :
Première étape (étape de construction) :
Ensuite, j'utilise une image plus petite qui exécutera simplement cet exécutable que nous avons généré dans la première étape :
Deuxième étape (Étape finale) :
Si nous voulons confirmer ce qui se passe réellement, dans Docker Desktop il y a la possibilité d'analyser la hiérarchie d'une image. À l'intérieur, nous pouvons voir ce que vous utilisez :

Maintenant, nous pouvons également analyser la taille de cette image que nous venons de générer, dans ce cas l'url-shortener:alpine qui était d'environ 30 Mo :
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE url-shortener alpine aa99d6a2c028 3 minutes ago 29.9MB
Alpine est une distribution Linux minimaliste, sécurisée et légère, largement utilisée dans les environnements de conteneurs en raison de son efficacité et de sa simplicité. Il fournit une base solide pour créer des applications évolutives sans les frais généraux d'autres distributions Linux plus lourdes.
Certains des avantages de l'utilisation d'Alpine dans notre application sont principalement liés à ces 3 piliers :
D'accord, mais que se passe-t-il si j'utilise la même version du SDK, dans ce cas golang:1.22-alpine. Quelle est la taille de ma candidature ?
REPOSITORY TAG IMAGE ID CREATED SIZE url-shortener golang-alpine d615d75c3aff 25 minutes ago 251MB
Eh bien, dans ce cas, nous nous sommes retrouvés avec une image de ~250 Mo... Alors que par rapport à l'alpin, nous sommes passés purement à ~30 Mo, c'est déjà une grosse différence. Et peut-il être encore amélioré ?
La réponse est OUI, et entrons dans les détails
Scratch est une image spéciale et très minimaliste dans Docker. Il s'agit en fait de l'image de base la plus simple et la plus vide possible que vous puissiez utiliser. Il ne contient absolument rien : pas de système d'exploitation, pas de bibliothèques, pas d'outils — c'est littéralement un conteneur vide.
Essa abordagem minimalista traz benefícios significativos, especialmente em termos desegurança. Ao usar Scratch, você minimiza drasticamente a superfície de ataque, já que não há pacotes ou ferramentas adicionais que possam introduzir vulnerabilidades. Seu contêiner contém apenas o essencial para a execução do aplicativo, garantindo um ambiente imutável e previsível em qualquer situação.
# syntax=docker/dockerfile:1 # Build stage FROM golang:1.22-alpine AS builder WORKDIR /app COPY . . RUN go mod download RUN go build -o url-shortener ./cmd # Final stage with Scratch FROM scratch WORKDIR /app COPY --from=builder /app/url-shortener . CMD ["./url-shortener"]
E o resultado após criar as 3 imagens, nosso ranking de menor imagem ficou assim:
O Scratch conseguiu baixar mais alguns megas no tamanho final de nossa aplicação. Isso impacta no tamanho de arquivos transferidos pela rede, hoje algumas empresas cobram pela banda que trafegamos dentro dos servidores, e também pode influenciar em nosso Horizontal Scaling da aplicação.
Deixei os 3 Dockerfiles dentro do repositório do github caso você queira testar em seu próprio pc ?
A resposta mais tranquila para essa é "quase sempre", uma dica de cara é: ele vai muito bem com linguagens como Go, Rust, ou C/C++. Mas qui estão alguns pontos para levar em consideração na hora de escolher se deve ou não usar o scratch:
Usar o cache do Docker para otimizar o tempo de build é uma técnica essencial para evitar recompilar ou baixar dependências desnecessariamente em cada build. O Docker armazena em cache as camadas de cada etapa do Dockerfile, reutilizando-as sempre que possível.
Em projetos Go, baixar dependências com go mod download pode ser um processo demorado, especialmente se houver muitas dependências. Se você recompilar todas as dependências em cada build, isso aumenta significativamente o tempo de build.
Ao copiar apenas os arquivos go.mod e go.sum em uma etapa separada antes de copiar o código-fonte completo, você permite que o Docker use o cache dessa etapa se os arquivos go.mod e go.sum não tiverem mudado. Veja como fica nosso Docker file com as mudanças:
# syntax=docker/dockerfile:1 # Build stage FROM golang:1.22-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -o url-shortener ./cmd # Final stage FROM scratch WORKDIR /app COPY --from=builder /app/url-shortener . CMD ["./url-shortener"]
Só de fazer esta pequena mudança já ganhamos dois pontos bem interessantes quando se trata de desenvolvimento de software, que são:
Menor tempo de build: Se não houver alterações nos arquivos go.mod e go.sum, o Docker reutiliza o cache, evitando o download das dependências e economizando tempo.
Eficiência no CI/CD: Em pipelines de integração contínua, essa técnica reduz o tempo de execução dos pipelines, aumentando a eficiência do desenvolvimento e entrega.
Então bora usar isso a nosso favor no dia-a-dia :)
Docker Scout é uma ferramenta da Docker integrada ao Docker Desktop que analisa suas imagens para identificar vulnerabilidades de segurança. Ele fornece insights sobre as dependências presentes em suas imagens e alerta sobre possíveis problemas, permitindo que você tome medidas corretivas antes de implantar suas aplicações.
Por que éimportante? Manter suas imagens Docker seguras é fundamental para proteger suas aplicações contra ataques e exploração de vulnerabilidades. O Docker Scout automatiza o processo de análise, tornando mais fácil manter suas imagens seguras e atualizadas.
O Scout funciona praticamente com 2 passos, ele examina a imagem Docker, mapeia todas as dependências incluídas na imagem e verifica essas dependências em uma base de dados de vulnerabilidades conhecidas. Por fim, classifica as vulnerabilidades encontradas por severidade e fornece recomendações para corrigir ou mitigar os problemas.




And this way, we will have proactive prevention that will identify and fix vulnerabilities before the image is deployed into production, helps protect against possible security exploits and we also gain operational efficiency, what do I mean by that? We can automate vulnerability analysis, allowing the DevOps or security team to focus on corrective actions rather than manual investigations.
With the practices we've explored, you now have a clear path to building Docker images for your Go applications. Using techniques like Multi-Stage Builds that reduce image size, choosing base images like alpine or scratch to improve security and efficiency, and by using Docker Scout to monitor vulnerabilities, you can ensure your applications are running efficiently and securely.
These practices not only improve technical performance, but also bring direct benefits to your daily life and to the company, saving time and resources.
So the next time you're building a Docker image, keep these strategies in mind. Apply them and observe the results. ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!
Livre de a5 et b5
La différence entre scratch et python
Quelles sont les fonctions des réseaux informatiques
Plateforme de trading personnelle Bitcoin
Solution au code d'erreur d'affichage de l'ordinateur 651
Comment connecter PHP à la base de données mssql
Comment conserver le nombre de décimales en C++
Comment utiliser la bibliothèque Python