Dagger et Dockerfile
On build des packages, on utilise les commandes Dagger, mais on ne va pas réinventer la roue non ? On avait l’habitude des Dockerfile, et tous nos projets les utilisent déjà, donc, on va réutiliser ce code avec Dagger!
On va donc essayer de build notre Dockerfile, et le publish sur un registrie privé type Scaleway.
Dockerfile
Pour l’instant, je vais partir sur un Dockerfile très très simple (Oui ce n’est pas en user node, mais c’est pour la démo)
Le voici :
FROM node:lts
WORKDIR /app
COPY . /app
EXPOSE 8080
CMD [ "npm", "run", "start" ]
Daggerization
Init
Pour daggerizer notre projet, on va déjà init dagger avec le SDK TypeScript.
dagger init --sdk=typescript --source=./dagger
Ensuite, dans mon dagger.json je vais exclure les nodes_modules pour éviter de les copier si je suis en plein dev. Ceci peut poser problème entre les différentes versions d’OS et de node.
"exclude": [ "**/node_modules" ]
Build
On va déjà créer une fonction pour faire une installation des dépendances.
@func() dev(source: Directory): Directory { const nodeCache = dag.cacheVolume("node") const npmInstall = dag .container() // start from a base Node.js container .from("node:lts") // add the source code at /src .withDirectory("/app", source) // mount the cache volume at /root/.npm .withMountedCache("/root/.npm", nodeCache) // change the working directory to /src .withWorkdir("/app") // run npm install to install dependencies .withExec(["npm", "install"]) // Return directory return npmInstall.directory("/app") }
Cette fonction va nous permettre de retourner le répertoire avec le npm install qu’on utilisera plus tard.
On fait déjà un test ?
dagger call dev --source=.
Super ! Maintenant on va build le Dockerfile.
Build
Avant d’essayer de publish, nous allons essayer de tester le container en live depuis dagger.
C’est possible ???
Eh oui, vous pouvez créer des services que vous exposez sur votre hôte, si vous n’exposez pas, vous pouvez utiliser le service comme endpoint http pour vos autres fonctions.
@func() build(source: Directory): Service { const devDirectory = this.dev(source) return dag .container() .withDirectory("/app", devDirectory) .build(devDirectory,{dockerfile: "Dockerfile"}) .asService() }
Je souhaite, exposer en tant que services pour vérifier que ça fonctionne et que le Dockerfile est bien pris en compte.
Si on lance simplement la commande suivante, le service va se lancer mais ne sera pas disponible sur notre hôte.
dagger call build --source=.
Nous allons donc exposer le service avec --ports
dagger call build --source=. up --ports 9002:8080
Notre conteneur répond bien !
*[main][~/Documents/dev-aidalinfo/tmp/node-api-demo]$ curl http://localhost:9002Ready !!! 🔥🔥🔥
Parfait, maintenant on va le remettre en mode container :
@func() build(source: Directory): Container { const devDirectory = this.dev(source) return dag .container() .withDirectory("/app", devDirectory) .build(devDirectory,{dockerfile: "Dockerfile"}) }
Et si on test d’exposer sur notre hôte en mode container ?
Ça fonctionne ! 😲
Conclusion
On a bien notre fonction qui permet le build avec le Dockerfile, pour le publish sur un registre privé, il faudra aller à la page suivante !
Je préfère séparer pour que les informations soient digestes et bien découpées.
Code Dagger
Voici le index.ts de dagger complet :
import { dag, Container, Directory, object, func } from "@dagger.io/dagger"
@object()export class NodeApiDemo {
@func() build(source: Directory): Container { const devDirectory = this.dev(source) return dag .container() .withDirectory("/app", devDirectory) .build(devDirectory,{dockerfile: "Dockerfile"}) }
@func() dev(source: Directory): Directory { const nodeCache = dag.cacheVolume("node") const npmInstall = dag .container() // start from a base Node.js container .from("node:lts") // add the source code at /src .withDirectory("/app", source) // mount the cache volume at /root/.npm .withMountedCache("/root/.npm", nodeCache) // change the working directory to /src .withWorkdir("/app") // run npm install to install dependencies .withExec(["npm", "install"]) // Return directory return npmInstall.directory("/app") }
}
GitHub
https://github.com/Killian-Aidalinfo/node-api-demo-dockerfile