fbpx
Trwają zapisy do Szkolenia Automation Maestro ». Obszerne szkolenie DevSecOps. Oferta obowiązuje tylko do 23 lipca do 21:00.
Kubernetes Maestro → sprawdź najnowsze szkolenie »»

Programując w dowolnym języku, staramy się robić to zgodnie z najlepszymi praktykami.

Często posługujemy się dodatkowymi narzędziami takimi jak statyczne analizatory kodu czy lintery, aby nasz kod był jak najlepszy.

Dobrą praktyka jest również, umieszczenia takiej weryfikacji jako krok w pipelinie CI/CD. Szczególnie w przypadku języków interpretowanych takich jak Python czy Javascript.

Linting Dockerfile

Tak samo jak pliki języków programowania, statyczne pliki, o określonej składni, również mogą być „lintowane”.

Dlaczego więc nie weryfikować Dockerfile? 🙂

Na szczęście nie jestem pierwszym, który wpadł na ten pomysł. Ostatnio wpadłem na kilka ciekawych linterów, którymi chciałbym się z Tobą podzielić.

Pierwsza ciekawa opcja to aplikacja webowa

https://www.fromlatest.io/

Zero instalowania, zero konfigurowania.

Otwierasz -> wklejasz twój Dockerfile i widzisz potencjalne zagrożenia/optymalizacje.

Tutaj przykład

Rysunek przedstawiający działanie webowej wersji Docker Lintera
https://www.fromlatest.io/

Porównując jednak to narzędzie z innymi dostępnymi na rynku, stwierdzam że nie jest idealne. Dodatkowo, ciężko o możliwość integracji z procesem CI/CD.

Natomiast, jego zaletą jest dostępność oraz natychmiastowo zwracany rezultat.

Jak zacząć korzystać z Docker Lintera na codzień?

Po pierwsze potrzebujemy jakiegoś narzędzia. Obecnie najpopularniejszym i oferującym możliwość integracji z CI/CD jest Hadolint.

Najszybszym sposobem na przetestowanie go lokalnie będzie użycie… Dockera 🙂

$ docker run --rm -i hadolint/hadolint < Dockerfile

Jeżeli Hadolint nie wykryje żadnych błędów w Twoim Dockerfile, nie zobaczymy żadnych błędów i zostanie zwrócony exit code 0.

Przykład

Mamy następujący Dockerfile

FROM centos:latest

RUN yum -y update && yum -y install \
httpd \
gcc

ADD httpd.conf /etc/httpd/conf/httpd.conf

EXPOSE 80

ENV HOME /root

WORKDIR /root

ENTRYPOINT ["ping"]

CMD ["google.com"]

Pomimo, że build przechodzi bezproblemowo:

Sending build context to Docker daemon  3.072kB                          
Step 1/8 : FROM centos:latest                                            
 ---> 0f3e07c0138f                                                       
Step 2/8 : RUN yum -y update && yum -y install httpd                     
 ---> Using cache                                                        
 ---> eeb8e1b687e1                                                       
Step 3/8 : ADD httpd.conf /etc/httpd/conf/httpd.conf                     
 ---> aa871e319cb2                                                       
Step 4/8 : EXPOSE 80                                                     
 ---> Running in df4c0ed6e26d                                            
Removing intermediate container df4c0ed6e26d                             
 ---> 97c001aba66b                                                       
Step 5/8 : ENV HOME /root                                                
 ---> Running in 84cf5b1b3187                                            
Removing intermediate container 84cf5b1b3187                             
 ---> 09382102ca4f                                                       
Step 6/8 : WORKDIR /root                                                 
 ---> Running in f26cf3622ae7                                            
Removing intermediate container f26cf3622ae7                             
 ---> a85e7876b391                                                       
Step 7/8 : ENTRYPOINT ["ping"]                                           
 ---> Running in 2e0b6bf24e74                                            
Removing intermediate container 2e0b6bf24e74                             
 ---> d8eb3ea955bf                                                       
Step 8/8 : CMD ["google.com"]                                            
 ---> Running in 6e4692726a8c                                            
Removing intermediate container 6e4692726a8c                             
 ---> 94f165a7e99d                                                       
Successfully built 94f165a7e99d                                          
Successfully tagged hadolint-example:latest 

Hadolint wykrył dwa miejsca do poprawy.

damian@szkoladockera:~/halint-example$ docker run --rm -i hadolint/hadolint < Dockerfile
/dev/stdin:1 DL3007 Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag
/dev/stdin:5 DL3020 Use COPY instead of ADD for files and folders

Każdy wykryty błąd reprezentowany jest jako klucz DL (błąd Hadolinta) lub SC (błąd ShellCheck).

Dokumentację najczęstszych błędów można znaleźć: https://github.com/hadolint/hadolint#rules

Wtyczka do Visual Studio Code

Obecnie Visual Studio Code bije rekordy popularności. Jak wynika z ankiety przeprowadzonej przez Stack Overflow, na rok 2019, ponad 50% badanych wykorzystuje to narzędzie do codziennej pracy. W przypadku Web Developerów jest to aż 55.6 %.

Rysunek przedstawiający najpopularniejsze edytory/IDE dla developerów w ankiecie przeprowadzonej przez StackOverflow w roku 2019.

Dlatego też, nie mogło się obejść bez wtyczki do Hadolinta 🙂

Wtyczka Hadolinta do Visual Studio Code
źródło: https://github.com/hadolint/hadolint/blob/master/docs/INTEGRATION.md

UWAGA 1:
Oprócz zainstalowania wtyczki w VS Code, potrzebujesz mieć fizycznie na dysku plik wykonywalny Hadolinta w katalogu, który jest dodany zmiennej $PATH. Można go pobrać TUTAJ.

UWAGA 2:  
W przypadku Windowsa, po pobraniu pliku „hadolint-Windows-x86_64.exe” należy zmienić nazwę na „hadolint.exe„. Inaczej wtyczka nie będzie działać.

Czy warto dodawać Docker Linter do pipelinu CI/CD?

Zdecydowanie TAK.

Tak samo, jak uruchamiamy testy jednostkowe, testy integracyjne, by sprawdzić czy nowo wprowadzona zmiana, nie zepsuła czegoś po drodze, tak samo walidowanie Dockerfile w procesie CI/CD zweryfikuje nam, czy postępujemy zgodnie z najlepszymi praktykami lub czy nie popełniliśmy błędu.

Dodatkowo, gdy pracujemy w zespole, zmiana wprowadzona przez Juniora, (nie mam nic do juniorów) czy osobę początkująca w świecie konteneryzacji, może być od razu zweryfikowana.
Dobrym rozwiązaniem może byc skonfigurowanie procesu CI/CD, by otrzymywać powiadomienia, w momencie gdy Hadolint coś wykryje.

Nawet jeśli jesteśmy już doświadczeni, to przecież nikt nie jest nieomylny. Warto to zrobić, nawet gdy w pojedynkę pracujemy nad projektem.

Jak zintegrować Hadolint z popularnymi narzędziami CI/CD?

1. GitLab

Dodaj następujący krok do pliku .gitlab-ci.yml

lint_dockerfile:
  image: hadolint/hadolint:latest-debian
  script:
    - hadolint Dockerfile

2. Jenkins

Możesz dodać krok podczas procesu CI/CD w następujący sposób

stage ("lint dockerfile") {
    agent {
        docker {
            image 'hadolint/hadolint:latest-debian'
        }
    }
    steps {
        sh 'hadolint dockerfiles/* | tee -a hadolint_lint.txt'
    }
    post {
        always {
            archiveArtifacts 'hadolint_lint.txt'
        }
    }
}

3. Bitbucket Pipelines

Utwórz plik konfiguracyjny bitbucket-pipelines.yml:

pipelines:
  default:
    - step:
        image: hadolint/hadolint:latest-debian
        script:
          - hadolint Dockerfile

Wszystkie dostępne integracje Hadolinta znajdziesz TUTAJ.

Gorąco zachęcam by korzystać z Hadolinta, czy tez innego dowolnego Docker Lintera na co dzień. Zarówno lokalnie np. wykorzystując wtyczkę do Visual Studio Code oraz jako krok w procesie CI/CD.

Jeżeli uważasz, że istnieje jakieś lepsze narzędzie niz Hadolint, koniecznie podziel się nim w komentarzu!

Dziękuje!

.

Damian Naprawa

Software Architect, Docker Certified Associate, praktykujący entuzjasta konteneryzacji. Lubi dzielić się wiedzą na swoim blogu https://szkoladockera.pl oraz w podkaście "Więcej Niż Konteneryzacja". Uczestnik globalnego programu partnerskiego Docker Enablement. Od kilku lat używa kontenerów na produkcji oraz mówi w języku #docker & #kubernetes. Fan automatyzacji oraz podejścia "As a Code"

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *