Minimal #Docker + #Golang et le téléversement Multipart

Pour réduire la taille d’un container Docker, on peut créer l’image en partant de rien, ou plus précisément, en partant de “scratch”, qui ne contient rien. On obtient à la fin un container beaucoup plus léger que si l’on partait de Debian, ou pire, d’Ubuntu.

Afin de mettre un binaire Go à l’intérieur, quelques précautions sont nécessaires. Nous verrons rapidement comment faire. Mais si vous voulez avoir plus d’infos, vous pouvez consulter la page en anglais de Codeship : Building Minimal Docker Containers For Go Applications

Compiler statiquement votre programme Go :

CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -a -installsuffix cgo -o server

Votre fichier Dockerfile doit ressembler à ça :

FROM scratch
ADD static /static
ADD server /server
CMD /server

Mais si vous avez besoin d’une fonctionnalité de téléversement (upload), cela ne va pas marcher. Le téléversement a besoin d’un dossier temporaire pour traiter les gros fichiers envoyés depuis un formulaire multipart.

Regardons directement dans le code du package Go os.file_unix :

// TempDir returns the default directory to use for temporary files.
func TempDir() string {
  dir := Getenv("TMPDIR")
	if dir == "" {
		if runtime.GOOS == "android" {
			dir = "/data/local/tmp"
		} else {
			dir = "/tmp"
		}
	}
	return dir
}

Comme on est sous Linux, on voit que le dossier temporaire se trouve dans /tmp.

Oui mais notre container, qu’on a construit à partir de scratch, ne contient pas de dossier /tmp. D’où plantage du téléversement 🙁

C’était un bug difficile à trouver, mais la solution est simple. Modifions notre fichier Dockerfile pour ajouter une entrée :

FROM scratch
VOLUME /tmp
ADD static /static
ADD server /server

Maintenant on peut lier notre container avec un dossier qui servira de dossier temporaire comme suit :

docker run -P -v /tmp:/tmp your_image 

Et voilà ! Une image Docker minimale, avec un binaire Go dedans et rien d’autre.

Comments are closed.