Dockerfile vs buildpacki: co wybrać dla Twojej aplikacji?

Karta Dockerfile i karta buildpacków, które prowadzą do jednego obrazu kontenera

W skrócie

  • W Dockerfile samodzielnie opisujesz każdy krok builda; Cloud Native Buildpacks wykrywają Twój język i budują obraz z kodu źródłowego bez Dockerfile.
  • Buildpacki pasują do standardowych aplikacji w obsługiwanych językach i zostawiają utrzymanie obrazu bazowego builderowi; Dockerfile sprawdza się przy niestandardowych pakietach systemowych, nietypowych stackach i pełnej kontroli nad obrazem.
  • Oba podejścia dają obraz kontenera, więc możesz zacząć od jednego i później przejść na drugie.
  • Na Nodion wybierasz Buildpacks albo Dockerfile dla każdej aplikacji: aplikacje z buildpackami nasłuchują na porcie PORT ustawianym przez Nodion, aplikacje z Dockerfile na porcie z EXPOSE lub z zakładki Processes.

Zarówno Dockerfile, jak i buildpacki zamieniają Twój kod źródłowy w obraz kontenera. Różnica polega na tym, kto określa kroki builda: w Dockerfile robisz to Ty, a buildpack ustala je na podstawie Twojego kodu. Wybierz buildpacki dla typowej aplikacji webowej w obsługiwanym języku, a Dockerfile, gdy potrzebujesz pełnej kontroli nad obrazem albo używasz technologii, których nie wykrywa żaden buildpack.

Czym jest Dockerfile

Jak ujmuje to dokumentacja Dockera, Dockerfile to „a text document that contains all the commands a user could call on the command line to assemble an image”, czyli plik tekstowy zawierający polecenia potrzebne do zbudowania obrazu. Wybierasz obraz bazowy, instalujesz pakiety systemowe, kopiujesz kod, instalujesz zależności i ustawiasz polecenie startowe. Każdą instrukcję określasz samodzielnie: masz pełną kontrolę, ale też odpowiadasz za utrzymanie pliku.

FROM node:24-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

W praktyce przy pisaniu Dockerfile znaczenie mają dwie funkcje:

  • Cache warstw: obraz jest budowany warstwami, a Docker zapisuje je w cache. Gdy zmieni się jedna warstwa, wszystkie kolejne też są budowane od nowa. Dlatego przykład kopiuje package.json i instaluje zależności, zanim skopiuje resztę kodu.
  • Buildy wieloetapowe (multi-stage): kilka instrukcji FROM w jednym pliku, z których każda rozpoczyna nowy etap. Kompilujesz w jednym etapie i kopiujesz tylko wynik do małego obrazu końcowego, a kompilatory i narzędzia do builda zostają poza nim.

Czym są buildpacki

Buildpack to oprogramowanie, które analizuje Twój kod źródłowy i ustala, jak go zbudować. Cloud Native Buildpacks to otwarty standard w tym zakresie. Build przechodzi przez stałe fazy: detect znajduje buildpacki pasujące do Twojego kodu, build zamienia kod źródłowy w artefakty gotowe do uruchomienia (na przykład instalując runtime i zależności, a potem kompilując), a export zapisuje końcowy obraz OCI. Nie potrzebujesz Dockerfile; opcjonalne pliki, takie jak Procfile czy project.toml, pozwalają skonfigurować build i procesy.

Buildpacki wyróżniają trzy cechy:

  • Osobne obrazy do builda i do uruchamiania: kompilatory i pliki nagłówkowe są w obrazie build, a aplikacja działa na obrazie uruchomieniowym (run image), już bez nich.
  • Rebase: gdy obraz uruchomieniowy dostaje aktualizację, pack rebase przepina obraz aplikacji na nową bazę bez ponownego budowania aplikacji.
  • Powtarzalność: lifecycle ustawia znaczniki czasu warstw na stałą datę, więc ten sam kod źródłowy, builder i buildpacki dają ten sam obraz, o ile same buildpacki za każdym razem generują ten sam wynik.

Więcej tła znajdziesz w artykule Czym są Cloud Native Buildpacks.

Dockerfile vs buildpacki w skrócie

DockerfileBuildpacki
KontrolaPełna: obraz bazowy, pakiety, użytkownicy, układ plikówW ramach opcji buildpacka: przypięte wersje, Procfile, dodatkowe pakiety
UtrzymanieSamodzielnie aktualizujesz obraz bazowy i każdą instrukcjęOpiekun buildera aktualizuje stack i buildpacki języków
Aktualizacje bezpieczeństwaNowy build z poprawionym obrazem bazowym; musisz tego pilnować samodzielnieAktualizacje buildera wprowadzają poprawione obrazy bazowe do następnego builda; istniejący obraz wymaga nowego builda albo jawnego rebase
PowtarzalnośćZależy od tego, jak ściśle przypinasz obrazy i pakietyWbudowana przy tych samych danych wejściowych, ze stałymi znacznikami czasu warstw
Szybkość buildaSzybki przy dobrze uporządkowanym cache warstw; zmiana na początku przebudowuje wszystko, co po niej następujeWarstwy z cache, np. zależności, są przywracane między buildami
Multi-stageTak, kilka etapów FROMNiepotrzebne: narzędzia do builda zostają w obrazie build
Nietypowe stackiWszystko, co da się zainstalować w obrazieTylko to, co wykrywa builder

Kiedy wybrać buildpacki

  • Twoja aplikacja jest napisana w języku obsługiwanym przez builder, np. Node.js, Python, Ruby, PHP, Go, Rust, Java, .NET lub Elixir, albo jest stroną statyczną.
  • Nie chcesz samodzielnie utrzymywać obrazów bazowych i pakietów systemu operacyjnego.
  • Uruchamiasz wiele usług i chcesz, żeby wszystkie były budowane w ten sam sposób.
  • Twój zespół zna język programowania, ale nie zna Dockera.

Kiedy wybrać Dockerfile

  • Potrzebujesz konkretnego obrazu bazowego, pakietów systemowych wykraczających poza to, co instaluje buildpack, albo własnego użytkownika.
  • Builder nie wykrywa Twojego języka ani frameworka.
  • Projekt ma już działający Dockerfile, jak wiele aplikacji open source.
  • Chcesz uzyskać bardzo mały obraz dzięki buildowi wieloetapowemu albo używać dokładnie tego samego obrazu lokalnie, w CI i na produkcji.

Jak Nodion obsługuje oba podejścia

W Applications → New łączysz repozytorium Git i wybierasz Buildpacks albo Dockerfile. Jeśli skanowanie znajdzie Dockerfile, wybiera go w pierwszej kolejności. Strategię możesz później zmienić w Settings; zmiana obowiązuje od następnego wdrożenia. Jeśli budujesz gdzie indziej, wdróż zamiast tego gotowy obraz.

Buildpacki na Nodion

  • Własne Cloud Native Buildpacks Nodion na stacku nodion-26 (Ubuntu 26.04 LTS). Wykrywają Node.js, Python, Ruby, PHP, Go, Rust, Elixir, Java, .NET i strony statyczne.
  • Proces działa jako użytkownik bez uprawnień roota. Dodatkowe pakiety Debiana deklarujesz w project.toml albo w Aptfile; ich skrypty instalacyjne nie są uruchamiane.
  • Procfile definiuje typy procesów; bez niego proces web dostaje domyślne polecenie dla danego języka.
  • Port: Nodion ustawia PORT. Nasłuchuj na nim; większość domyślnych poleceń używa portu 8080, jeśli zmienna nie jest ustawiona.
web: gunicorn myapp.wsgi --bind 0.0.0.0:$PORT
worker: python worker.py

Dockerfile na Nodion

  • Katalog ustawiony jako Base directory jest kontekstem builda, a znajdujący się w nim .dockerignore jest uwzględniany.
  • Pliki multi-stage działają. Nie ma wyboru etapu, więc uruchamiany jest ostatni etap.
  • Zmienne środowiskowe oznaczone jako Build są przekazywane jako build args (ARG). Sekrety BuildKit nie są przekazywane.
  • Port: Nodion nie ustawia PORT dla aplikacji z Dockerfile. Powiąż aplikację z portem procesu web, który jest wstępnie uzupełniany na podstawie EXPOSE i który możesz zmienić w zakładce Processes; jeśli ta lista jest pusta, Nodion używa EXPOSE z obrazu, a w ostateczności portu 8080. Nasłuchuj na wszystkich interfejsach, nie tylko na localhost.
  • Health check: gotowość (readiness) sprawdza żądanie HTTP GET na ścieżkę health checka ustawioną w Settings (domyślnie /). Odpowiedź 2xx lub 3xx oznacza, że aplikacja działa poprawnie. HEALTHCHECK w obrazie jest ignorowany.
  • USER z obrazu jest respektowany.

Wszystkie szczegóły znajdziesz w dokumentacji buildpacków i w dokumentacji Dockerfile. Nie wiesz jeszcze, co wybrać? Zacznij od buildpacków, a Dockerfile dodaj wtedy, gdy będziesz potrzebować czegoś, czego one nie potrafią.

Najczęściej zadawane pytania

Czy do wdrożenia kontenera potrzebuję Dockerfile?

Nie. Buildpacki budują obraz kontenera bezpośrednio z kodu źródłowego, bez Dockerfile w repozytorium. Możesz też wdrożyć gotowy obraz z rejestru (registry).

Czy buildpacki są lepsze od Dockerfile?

Żadne z tych rozwiązań nie jest lepsze w każdym przypadku. Buildpacki wymagają mniej utrzymania przy standardowych aplikacjach w obsługiwanych językach, a Dockerfile daje Ci pełną kontrolę nad obrazem i działa z każdym stackiem.

Czy mogę użyć wieloetapowego Dockerfile (multi-stage) na Nodion?

Tak. Wieloetapowe Dockerfile działają. Nie ma wyboru etapu, więc uruchamiany obraz to ostatni etap.

Na jakim porcie powinna nasłuchiwać moja aplikacja?

Z buildpackami nasłuchuj na porcie ze zmiennej środowiskowej PORT, którą ustawia Nodion. Przy Dockerfile Nodion nie ustawia PORT: powiąż aplikację z portem procesu web, pobranym z EXPOSE lub ustawionym w zakładce Processes, i nasłuchuj na wszystkich interfejsach.

Daj swojemu agentowi chmurę.

Zyskaj do 15 € środków na start przy rejestracji.

Kontynuuj z GitHub

lub przez e-mail

Bądź na bieżąco.

Nowości produktowe, bez spamu. Możesz zrezygnować w każdej chwili.