Forum Linux.debian/ubuntu Empaqueter une appli dans docker

Posté par  . Licence CC By‑SA.
Étiquettes :
3
17
oct.
2017

Bonjour à tous,

Je fais parti des développeurs de YaDICs. Ce soft n'aura plus d'améliorations car il répond au besoin. La chaîne de compilation est super chiante à remettre au goût du jour à chaque fois qu'une nouvelle version d'un distribution sort on a peur de ne plus réussir à compiler. Nous n'arrivons plus à compiler sur la dernière debian par exemple.

Nous n'avons plus vraiment les ressources internes en ce qui concerne le C++ et CMake ainsi nous aimerions faire une version statique qui fonctionne sans se poser de question.

Du coup j'ai regardé et docker semble être une solution intéressante. Je ne l'ai jamais utilisé aussi je me tourne vers vous pour avoir un retour d'expérience.

Est-ce possible d'installer une base de ubuntu 16.04 puis toutes les dépendances et ainsi compiler le prgramme dans l'environnement ubuntu-docker, pour finalement en faire une image docker que l'on pourrait distribuer et ainsi figer le soft ?

Quelqu'un a il déjà utilisé docker pour cela, et est ce que c'est approche valable ?

Si oui, auriez vous une documentation, des tutoriels ou même de simples conseils pour m'aider dans cette tache ?

  • # Oui ?

    Posté par  (site web personnel) . Évalué à 6.

    Est-ce possible d'installer une base de ubuntu 16.04 puis toutes les dépendances et ainsi compiler le prgramme dans l'environnement ubuntu-docker, pour finalement en faire une image docker que l'on pourrait distribuer et ainsi figer le soft ?

    Sur le principe, oui c'est bien le genre de choses qu'on fait avec Docker. En gros tu vas faire un Dockerfile qui ressemble à :

        FROM ubuntu:xenial
        MAINTAINER Toi <ton.mail@example.com>
        RUN apt-get update -q && apt-get install -qy \
            les \
            dependances \
            de ton \
            outil
        RUN script-d-install.sh
    

    et lancer docker build dessus.

    Après, la difficulté est de faire communiquer ton conteneur avec le reste du monde. Y'a plusieurs options :

    • Le classique chez les utilisateurs de Docker: ton appli est une appli web, tu lui parles par le réseau.

    • Les volumes Docker, i.e. un répertoire partagé entre la machine hote et le conteneur. Ça peut s'activer par exemple avec docker run -v /repertoire/local:/point/de/montage/dans/le/conteneur. Un bel exemple est là : https://github.com/blang/latex-docker, c'est une image qui contient une install latex et qui permet de compiler du code sur le host en utilisant un pdflatex dans le conteneur.

    Un gros défaut de Docker pour distribuer un outil comme ça : la personne qui lance l'outil doit grosso-modo être root pour pouvoir l'exécuter. L'application s'exécute dans un conteneur, mais le lancement demande au moins d'être dans le groupe docker (et quelqu'un qui est dans le groupe docker peut facilement passer root).

    • [^] # Re: Oui ?

      Posté par  . Évalué à 5. Dernière modification le 17 octobre 2017 à 23:02.

      très bonne réponse, cependant, concernant les aspects docker, il faut éventuellement distinguer les 2 aspects :

      • build (compilation) qui permet en général de créer un ou plusieurs binaires éventuellement encapsulés dans des paquets ; sur gitlab, on parle d'artifact (produit de l’exécution d'un job)
      • l’exécution de ces binaires qui pourra aussi s'appuyer sur Docker avec une bonne partie commune à l'environnement build.
      • on peut aussi s'appuyer lorsque cela a du sens sur docker-compose afin d'assembler plusieurs containers Docker.

      concernant les aspects sécurité lié à Docker : on peut invoquer des commandes Docker sans être root (par configuration). Mais il devient assez facile de monter la racine du système hôte dans un container Docker et de compromette le système. Il faut donc considérer les utilisateurs Docker comme des acteurs coopératifs.

    • [^] # Re: Oui ?

      Posté par  . Évalué à 2.

      j'ai créé un Dockerfile ici : https://gist.github.com/mqu/403cf77e0b0688c421c6bb3c69e9ea6e

      • le téléchargement des dépendances ne fonctionne pas avec ubuntu/xenial, ni ubuntu trusty (les 2 dernières LTS)
      • est-ce que tu sais avec quelle version de ubuntu ou debian cela fonctionne ?
      • [^] # Re: Oui ?

        Posté par  . Évalué à 2.

        pareil pour la jessie :

        Reading package lists...
        + apt-get install -qy build-essential cmake gcc-4.9-base gfortran imagemagick ipython lib64gomp1 libatlas3-base libatlas-dev liblapack-dev libc6 libc6-amd64 libfftw3-dev libgcc1 libgraphicsmagick++1-dev libnetcdf-dev libnetcdf-c++4 libnetcdf-c++4-dev libnetcdf-cxx-legacy-dev libtiff5-dev ncview netcdf-bin python-matplotlib python-netcdf4 python-numpy python-scipy dvipng texlive-full ghostscript ghostscript
        Reading package lists...
        Building dependency tree...
        Reading state information...
        Package libc6-amd64 is not available, but is referred to by another package.
        This may mean that the package is missing, has been obsoleted, or
        is only available from another source
        However the following packages replace it:
          libc6
        
        E: Unable to locate package lib64gomp1
        E: Package 'libc6-amd64' has no installation candidate
        E: Unable to locate package libnetcdf-c++4
        E: Couldn't find any package by regex 'libnetcdf-c++4'
        E: Unable to locate package libnetcdf-c++4-dev
        E: Couldn't find any package by regex 'libnetcdf-c++4-dev'
        E: Unable to locate package libnetcdf-cxx-legacy-dev
        E: Unable to locate package python-netcdf4
        
        
        • [^] # Re: Oui ?

          Posté par  (site web personnel) . Évalué à 2.

          Effectivement, les noms de packages n'existent pas sous Ubuntu. Par exemple, pour la lib gomp, le nom du package est libgomp1.

          Le package lib64gomp1 existe sous Debian par contre : https://packages.debian.org/search?keywords=lib64gomp1, mais les instructions d'install échouent sur Jessie et Stretch avec des packages manquants différents à chaque fois :-(.

          • [^] # Re: Oui ?

            Posté par  . Évalué à 3.

            si quelqu'un me donnes une liste de dépendances et un mécanisme de compilation qui fonctionne sur une distribution précise, je veux bien prolonger l'exercice. Mais, là maintenant, je suis un peu à bout de forces.

            • [^] # Re: Oui ?

              Posté par  . Évalué à 2.

              Salut,

              Merci beaucoup pour l'essai !!

              Ca fonctionne sous Ubuntu 16.04, la dernière LTS.

              Sur la 14.04 le paquet libnetcdf-cxx-legacy-dev n'était pas nécessaire.

            • [^] # Re: Oui ?

              Posté par  . Évalué à 2.

              Toute cette partie :
              ncview netcdf-bin python-matplotlib python-netcdf4 python-numpy python-scipy dvipng texlive-full ghostscript ghostscript

              est pour le post traitement en python, la partie texlive-full est très lourde et elle permet juste de pouvoir afficher du code latex dans matplotlib, je pense qu'il ne vaut mieux pas la mettre dans une image docker …

            • [^] # Re: Oui ?

              Posté par  . Évalué à 3.

              Pour la liste de dépendances :

              apt-get install -qy build-essential cmake gcc-4.9-base gfortran imagemagick lib64gomp* libatlas3-base libatlas-dev liblapack-dev libc6 libfftw3-dev libgcc1 libgraphicsmagick++1-dev libnetcdf-dev libnetcdf-c++4 libnetcdf-c++4-dev libnetcdf-cxx-legacy-dev libtiff5-dev wget unzip

              fait le job sur une ubuntu vierge dans un conteneur docker.

              ensuite je crée un répertoire dans le home YaDICs.

              je dezippe dans ce répertoire,
              je vais dans : ./YaDICs_V04.14.a/build/
              je fais un cmake ../

              puis un make et ça marche.

              Par contre, je ne sais pas comment sauver l'état du conteneur, ni lui faire accéder aux répertoires du pc hôte.

  • # et bien fait le

    Posté par  . Évalué à 4.

    ainsi nous aimerions faire une version statique qui fonctionne sans se poser de question.

    et bien tu le fais, tu compiles en static, tu obtiens alors un binaire deployable partout en 32 ou 64bits

    meme pas besoin de faire un docker qui ne fait qu'ajouter une couche supplementaire de "virtualisation" entre ton appli et le systeme

    • [^] # Re: et bien fait le

      Posté par  . Évalué à 3.

      Ok, mais je n'ai pas les compétences pour réécrire toute la chaîne de compilation en statique, sinon je l'aurais déjà fait …

      • [^] # Re: et bien fait le

        Posté par  . Évalué à 1.

        c'est sur qu'entre apprendre à compiler en statique
        ou apprendre à faire un docker pour ensuite compiler en dynamique dedans,

        doit y en avoir un plus simple que l'autre

        • [^] # Re: et bien fait le

          Posté par  . Évalué à 3.

          Et bien écoute, si c'était si simple, peut être que je ne posterais pas ici, non ?

          J'ai essayé de voir avec cmake et les tutos de base, mais cela ne marche pas et les messages de compilation sont tout sauf simple. Donc oui utiliser un conteneur peut être plus simple pour moi que de refaire la chaine de compilation avec mon niveau en ingénierie logicielle. Alors tu as le droit de penser que c'est regrettable mais c'est comme ça. Je saurais le faire rapidement avec une virtualbox mais j'ai trouvé que c'était moins élégant qu'avec docker.

          De plus, bien souvent lorsque tu compiles en statique, il reste des libs qui ne le sont pas et dont le numéro change. Il faut ainsi faire des liens symboliques qui des foi résolvent les problèmes mais d'autres fois engendrent une erreur au niveau de l'ABI. Donc, ce n'est pas un sujet si simple que ça …

          Avec une image docker, je suis certain que même dans 5 ans mon image fonctionnera encore. Cela me semble être un bon moyen de figer un logiciel, non ?

          Après si tu sais m'expliquer comment passer le CMakeList en version statique, je serais très heureux d'essayer.

          • [^] # Re: et bien fait le

            Posté par  . Évalué à 2.

            De plus, bien souvent lorsque tu compiles en statique, il reste des libs qui ne le sont pas et dont le numéro change.

            c'est que le code source (ou le .h) n'est pas statique pour cette librairie là

            Il faut ainsi faire des liens symboliques qui des foi résolvent les problèmes mais d'autres fois engendrent une erreur au niveau de l'ABI

            le probleme de l'ABI tu risques de l'avoir aussi avec un programme completement statique, car justement tu vas embarquer des librairies pour une ABI et ton kernel en aura une autre :/

            • [^] # Re: et bien fait le

              Posté par  . Évalué à 2.

              D'où l'intérêt de docker non ?

              Étant donné que l'on ne va plus développer sur cette base mais que le soft n'a pas vraiment d'équivalent sur les aspects traitement 3D, pouvoir le conserver fonctionnel avec Docker me semble un bon moyen de ne plus jamais avoir à gérer les changements de distribution !

              • [^] # Re: et bien fait le

                Posté par  . Évalué à 2.

                parce que docker sait convertir les appels ABI entre plusieurs versions ?

          • [^] # Re: et bien fait le

            Posté par  (site web personnel) . Évalué à 1.

            Avec une image docker, je suis certain que même dans 5 ans mon image fonctionnera encore.
            Cela me semble être un bon moyen de figer un logiciel, non ?

            Heu non, dans 5 ans docker aura pris 50 versions à la vitesse à laquelle ils vont, les layers sources ubuntu actuels n'existeront plus forcement, ou auront été mis à jours (sécu/autre), …

            Utiliser docker pour vouloir figer un logiciel sur 5 ans c'est tout aussi illusoire que via une compilation statique d'ailleurs

            • [^] # Re: et bien fait le

              Posté par  . Évalué à 2.

              Donc en gros, il ne reste que la machine virtuelle, c'est ça ?

              • [^] # Re: et bien fait le

                Posté par  . Évalué à 4.

                si le but c'est de continuer à compiler ou utiliser le logiciel => oui,
                mais il ne faudra plus mettre à jour cette machine.

                si le but c'est de compiler puis de distribuer le logiciel, tu auras toujours des problemes avec les evolutions non maitrisées, externes à ton programme comme l'ABI du noyau.

                il n'y a pas de miracle, il faut suivre les evolutions, et donc tu peux

                • continuer à compiler en dynamique, faut suivre regulierement, plusieurs distribs
                • faire de la compilation statique, une fois la methode apprise, il ne reste alors puis qu'à suivre les changements d'ABI
                • laisser faire les autres en mettant ton projet sur une forge, en ne fournissant que les sources, et c'est les utilisateurs dans leur besoin qui vont compiler pour telle ou telle distrib

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.