- 1 1. Wstęp
- 2 2. Podstawowa struktura Dockerfile
- 3 3. Praktyka: Tworzenie Dockerfile opartego na Ubuntu
- 4 4. Budowanie i weryfikacja obrazu Dockera
- 5 5. Zastosowanie: Budowanie środowiska Python
- 6 6. Powszechne problemy i rozwiązania
- 7 7. Zakończenie
- 8 8. FAQ (Najczęściej Zadawane Pytania)
- 8.1 P1. Którą wersję Ubuntu powinienem wybrać w moim Dockerfile?
- 8.2 Q2. Dlaczego pojawia się komunikat „Package not found” przy użyciu apt-get install?
- 8.3 Q3. Jak ustawić zmienne środowiskowe w Dockerfile?
- 8.4 Q4. Jaka jest różnica między CMD a ENTRYPOINT w Dockerfile?
- 8.5 Q5. Edytowałem mój Dockerfile, ale zmiany nie są widoczne. Dlaczego?
1. Wstęp
Czym są Docker i Dockerfile?
W ostatnich latach Docker szybko zyskał popularność jako środek do uproszczenia konfiguracji środowisk deweloperskich i wdrażania aplikacji. Docker ma unikalną zdolność do pakowania aplikacji i jej zależności w pojedynczy „kontener”, który może być uruchamiany w tym samym środowisku w dowolnym miejscu. Aby zbudować ten kontener Docker, niezbędny jest plan o nazwie „Dockerfile”. Dockerfile to plik tekstowy, który określa obraz bazowego systemu operacyjnego, oprogramowanie do zainstalowania, ustawienia zmiennych środowiskowych i więcej. Deweloperzy mogą użyć tego pliku do automatycznego budowania spersonalizowanych środowisk.
Powody wyboru Ubuntu jako bazy
Podczas tworzenia Dockerfile pierwszym krokiem jest określenie obrazu bazowego systemu operacyjnego. Spośród wielu opcji Ubuntu jest szczególnie popularne. Ubuntu to dystrybucja Linuksa oparta na Debianie, znana z łatwości użycia i elastyczności w budowaniu różnorodnych środowisk dzięki obszernej bazie pakietów. Dockerfile oparty na Ubuntu oferuje następujące zalety:
- Dostępna jest obfita oficjalna i społecznościowa dokumentacja, co skutkuje niższą krzywą uczenia.
- Wiele pakietów i narzędzi można łatwo zainstalować za pomocą APT (Advanced Package Tool).
- Oficjalnie dostarczane są lekkie minimalne obrazy (takie jak
ubuntu:20.04,ubuntu:24.04).
Cel i grupa docelowa tego artykułu
W tym artykule skupimy się na słowie kluczowym „Dockerfile Ubuntu” i zapewnimy łatwe do zrozumienia wyjaśnienie dla początkujących na temat tworzenia Dockerfile opartych na Ubuntu. Szczegółowo omówimy wszystko, od podstawowej struktury Dockerfile po kroki do faktycznego budowania środowiska Ubuntu, przykłady instalowania środowisk aplikacji jak Python oraz częste błędy z ich rozwiązaniami. Ten artykuł jest polecany dla:
- Osób, które chcą po raz pierwszy zbudować środowisko za pomocą Dockerfile.
- Osób, które chcą stworzyć powtarzalne środowisko deweloperskie na Ubuntu.
- Osób, które chcą pogłębić swoją wiedzę, w tym jak rozwiązywać problemy.
2. Podstawowa struktura Dockerfile
Czym jest Dockerfile? Zrozumienie jego roli
Dockerfile to jak przepis na tworzenie obrazu Docker. Konkretnie, to plik tekstowy, który opisuje, który bazowy system operacyjny użyć, jakie oprogramowanie zainstalować i jakie konfiguracje zastosować.
Poprzez wykonanie polecenia docker build za pomocą tego pliku, możesz łatwo zbudować wysoce powtarzalne środowiska deweloperskie i wykonywania aplikacji.
Korzyści z używania Dockerfile:
- Automatyzacja konfiguracji środowiska (brak potrzeby odtwarzania kroków ręcznych).
- Eliminuje niespójności środowiskowe podczas rozwijania z wieloma członkami zespołu.
- Łatwo integruje się z potokami CI/CD.
Powszechnie używane podstawowe instrukcje (dyrektywy) w Dockerfile
Dockerfile zawiera kilka instrukcji (dyrektyw), z których następujące są najbardziej reprezentatywne. Połączymy je odpowiednio, aby stworzyć Dockerfile oparty na Ubuntu.
| Instruction | Description |
|---|---|
FROM | Specifies the base Docker image. Example: FROM ubuntu:24.04 |
RUN | Executes shell commands. Used for package installation, etc. |
COPY | Copies local files into the image. |
ADD | Similar to COPY, but also allows fetching from URLs and extracting archives. |
WORKDIR | Sets the working directory. |
ENV | Sets environment variables. |
CMD | Defines the command to be executed when the container starts (can be overridden). |
ENTRYPOINT | Similar to CMD, but defines a command that is always executed. |
Minimalny przykład Dockerfile opartego na Ubuntu
Poniżej znajduje się bardzo podstawowy przykład Dockerfile opartego na Ubuntu.
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y
curl
vim
CMD ["/bin/bash"]
Ten Dockerfile jest skonfigurowany do użycia Ubuntu 24.04 jako bazy, zainstalowania dwóch narzędzi (curl i vim) oraz ostatecznie uruchomienia powłoki bash.
O wyborze tagów Ubuntu
Obrazy Docker Ubuntu są dostępne w oficjalnym repozytorium Docker Hub. Chociaż określenie ubuntu:latest użyje najnowszej wersji, zaleca się jawne przypinanie wersji.
Na przykład:
ubuntu:22.04(LTS: wersja z długoterminowym wsparciem, podkreśla stabilność)ubuntu:24.04(Najnowszy kandydat LTS, podkreśla funkcje)
Rozważ, czy priorytetyzować stabilność czy nowe funkcje w zależności od celu.
3. Praktyka: Tworzenie Dockerfile opartego na Ubuntu
Instalowanie niezbędnych pakietów dla środowiska Ubuntu
Gdy budujesz środowisko Ubuntu za pomocą Dockerfile, często będziesz musiał zainstalować dodatkowe pakiety. Na przykład, następujące narzędzia są powszechnie używane do konfiguracji środowiska deweloperskiego:
curl: Do pobierania plików i sprawdzania API.vim: Prosty edytor tekstu.git: Narzędzie do kontroli wersji.build-essential: Zbiór podstawowych narzędzi niezbędnych do kompilacji programów w C/C++.
Aby zainstalować te pakiety w Dockerfile, użyj instrukcji RUN.
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y
curl
vim
git
build-essential
Uruchamiając najpierw apt-get update, zapewniasz, że najnowsze listy pakietów zostaną pobrane przed instalacją.
Konfigurowanie instalacji nieinteraktywnej
W Ubuntu polecenie apt-get install może wymagać wprowadzenia danych przez użytkownika, ale operacje interaktywne nie są możliwe podczas procesu budowania Dockera. Dlatego zaleca się ustawienie zmiennej środowiskowej w następujący sposób, aby wykonać instalację w trybie nieinteraktywnym.
ENV DEBIAN_FRONTEND=noninteractive
To pozwoli pominąć monity, takie jak „Ustawienia regionalne”, które pojawiają się podczas konfiguracji pakietów, umożliwiając płynne przeprowadzenie instalacji.
Redukcja rozmiaru obrazu poprzez usuwanie niepotrzebnego bufora
Podczas używania APT pobierane pliki tymczasowe (bufor) mogą pozostać w obrazie, co zwiększa rozmiar końcowego obrazu Dockera. Możesz zmniejszyć rozmiar obrazu, usuwając ten bufor w następujący sposób:
RUN apt-get update && apt-get install -y
curl
vim
&& rm -rf /var/lib/apt/lists/*
Poprzez łączenie wielu poleceń w jedną instrukcję RUN w ten sposób, możesz również zapobiec tworzeniu niepotrzebnych warstw.
Najlepsze praktyki: Organizacja Dockerfile
W rzeczywistych środowiskach deweloperskich zaleca się następujące najlepsze praktyki pisania Dockerfile:
- Łącz instrukcje
RUNw jak największym stopniu, aby zmniejszyć liczbę warstw. - Definiuj wersje i konfiguracje jawnie za pomocą
ENV. - Używaj komentarzy, aby jasno określić cel każdej operacji.
- Używaj
rmi--no-install-recommends, aby uniknąć pozostawiania niepotrzebnych plików.
Przykład:
RUN apt-get update && apt-get install -y --no-install-recommends
curl
git
&& rm -rf /var/lib/apt/lists/*
Dzięki temu możesz zbudować lżejszy i łatwiejszy w utrzymaniu Dockerfile.
4. Budowanie i weryfikacja obrazu Dockera
Budowanie obrazu Dockera z Dockerfile
Po napisaniu Dockerfile następnym krokiem jest zbudowanie obrazu Dockera. Wykonuje się to za pomocą polecenia docker build. Uruchom następujące polecenie w katalogu, w którym znajduje się twój Dockerfile:
docker build -t my-ubuntu-image .
- Opcja
-tsłuży do nadania nazwy (tagu) obrazowi. W tym przykładzie nadajemy mu nazwęmy-ubuntu-image. .odnosi się do bieżącego katalogu, w którym znajduje się Dockerfile.
Po uruchomieniu tego polecenia Docker odczyta sekwencyjnie instrukcje w Dockerfile i zbuduje nowy obraz odpowiednio.
Weryfikacja zbudowanego obrazu Dockera
Po zakończeniu tworzenia obrazu możesz go zweryfikować za pomocą następującego polecenia:
docker images
To wyświetli listę obrazów Dockera istniejących lokalnie i pozwoli sprawdzić następujące informacje:
- REPOSITORY (nazwa obrazu)
- TAG (tag)
- IMAGE ID (unikalny identyfikator)
- CREATED (data i czas utworzenia)
- SIZE (rozmiar)
Przykład:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-ubuntu-image latest abcd1234abcd 5 minutes ago 189MB
To potwierdza, że utworzony przez ciebie obraz został pomyślnie zarejestrowany.
Uruchamianie kontenera Dockera i weryfikacja działania
Aby zweryfikować, czy utworzony obraz działa poprawnie, uruchommy kontener Dockera. Użyj następującego polecenia:
docker run -it my-ubuntu-image
- Określenie opcji
-itpozwala na uruchomienie terminala w trybie interaktywnym. - Jeśli uruchomi się pomyślnie, pojawi się prompt bash w kontenerze, i będziesz w stanie, jakbyś zalogował się do środowiska Ubuntu.
W kontenerze możesz wykonać polecenia takie jak poniższe, aby sprawdzić, czy zainstalowane narzędzia działają poprawnie:
curl --version
vim --version
Jeśli nie ma problemów, Dockerfile został napisany pomyślnie.
Czyszczenie niepotrzebnych obrazów i kontenerów
W miarę powtarzania budów i eksperymentów, niepotrzebne obrazy Docker i kontenery mogą gromadzić się lokalnie. Zaleca się okresowe ich czyszczenie za pomocą poleceń takich jak poniższe:
- Usuwanie zatrzymanych kontenerów:
docker container prune
- Usuwanie nieużywanych obrazów:
docker image prune
- Usuwanie wszystkich nieużywanych danych (Uwaga!):
docker system prune
Te operacje pomagają oszczędzać miejsce na dysku i zapobiegać problemom.
5. Zastosowanie: Budowanie środowiska Python
Uczynienie Pythona użytecznym w Dockerfile opartym na Ubuntu
Poprzez dodanie środowiska wykonawczego Pythona podczas budowania środowiska Ubuntu za pomocą Dockerfile, możesz wspierać szeroki zakres zastosowań, takich jak rozwój, testowanie i uczenie maszynowe. Chociaż Ubuntu może mieć preinstalowanego Pythona, powszechną praktyką jest jawne budowanie go samodzielnie z perspektywy zarządzania wersjami i pakietami.
Jak zainstalować Python za pomocą apt
Najprostszy sposób to instalacja Pythona za pomocą pakietów APT. Oto przykład:
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y
python3
python3-pip
&& rm -rf /var/lib/apt/lists/*
Za pomocą tej metody możesz używać stabilnej wersji Pythona zainstalowanej w systemie (zazwyczaj Python 3.10 lub 3.12 itp.). Ponadto możesz dodawać pakiety Pythona za pomocą polecenia pip.
Zarządzanie wersjami Pythona za pomocą pyenv
Jeśli chcesz używać konkretnej wersji Pythona lub przełączać się między wieloma wersjami, korzystanie z pyenv jest wygodne. Poniżej znajduje się przykład użycia pyenv do zainstalowania Pythona 3.11.6 w Dockerfile:
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y
git
curl
make
build-essential
libssl-dev
zlib1g-dev
libbz2-dev
libreadline-dev
libsqlite3-dev
wget
llvm
libncurses5-dev
libncursesw5-dev
xz-utils
tk-dev
libffi-dev
liblzma-dev
&& rm -rf /var/lib/apt/lists/*
# Install pyenv
RUN git clone [https://github.com/pyenv/pyenv.git](https://github.com/pyenv/pyenv.git) ~/.pyenv
ENV PYENV_ROOT="$HOME/.pyenv"
ENV PATH="$PYENV_ROOT/bin:$PATH"
RUN echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
# Install a specific Python version
RUN pyenv install 3.11.6 && pyenv global 3.11.6
To pozwala na bardziej elastyczne budowanie i zarządzanie środowiskiem Pythona.
Zarządzanie pakietami za pomocą requirements.txt
W rzeczywistych projektach często będziesz potrzebować wielu bibliotek Pythona. requirements.txt służy do zarządzania nimi.
Najpierw przygotuj plik requirements.txt w katalogu głównym swojego projektu:
flask==2.3.2
requests>=2.25.1
pandas
Następnie opisz to w Dockerfile w następujący sposób:
COPY requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install --no-cache-dir -r requirements.txt
To pozwala na zainstalowanie niezbędnych bibliotek naraz, zwiększając powtarzalność twojego środowiska deweloperskiego.
Najlepsze praktyki
- Podczas używania Pythona, budowanie środowiska wirtualnego za pomocą
virtualenvlubvenvmoże pomóc zapobiec konfliktom zależności. - Możesz zmniejszyć rozmiar obrazu Docker, usuwając pamięć podręczną (
--no-cache-dir). - Instalacja najnowszej wersji pip za pomocą
pip install --upgrade pipprzed instalacją pakietów Pythona może zapobiec błędom.
6. Powszechne problemy i rozwiązania
Błędy uprawnień
Przykład:
Permission denied
To występuje, gdy skopiowany plik nie ma uprawnień do wykonywania lub gdy właściciel/pliku/uruchamiający użytkownik nie jest odpowiedni.
Rozwiązania:
- Ustaw plik jako wykonywalny:
RUN chmod +x script.sh
- Zmień użytkownika, jeśli to konieczne:
RUN chown root:root /path/to/file
Pakiet nie został znaleziony lub nie może zostać zainstalowany
Przykład:
E: Unable to locate package xxx
Ten błąd pojawia się, gdy nie uruchomiono apt-get update lub podano nieprawidłową nazwę pakietu.
Rozwiązania:
- Zawsze wykonuj
apt-get updateprzedinstall:RUN apt-get update && apt-get install -y curl
- Sprawdź nazwę pakietu pod kątem literówek i upewnij się, że jest poprawna.
Błędy związane z siecią
Przykład:
Temporary failure resolving 'deb.debian.org'
Ten typ błędu występuje, gdy rozwiązywanie DNS nie powodzi się podczas procesu budowania.
Rozwiązania:
- Ponowne uruchomienie demona Docker może rozwiązać problem:
sudo systemctl restart docker
- Przejrzyj ustawienia DNS Dockera (dodaj specyfikacje DNS do
/etc/docker/daemon.json):{ "dns": ["8.8.8.8", "8.8.4.4"] }
Budowanie pozostaje w starej wersji z powodu efektów pamięci podręcznej
Docker używa pamięci podręcznej warstwa po warstwie w celu przyspieszenia. W rezultacie, nawet jeśli zmodyfikujesz Dockerfile, może on nie budować się zgodnie z oczekiwaniami, ponieważ ponownie wykorzystywane są zbuforowane warstwy.
Rozwiązanie:
- Przebuduj bez użycia pamięci podręcznej:
docker build --no-cache -t my-image .
Polecenie startowe w kontenerze nie wykonuje się lub kończy natychmiast
Przyczyny:
- Polecenie określone w
CMDlubENTRYPOINTnapotyka błąd. - Nawet jeśli w
CMDpodasz `[„/ zakończy się ono natychmiast, jeśli nie zostanie uruchomione interaktywnie.
Rozwiązania:
- Uruchom kontener w trybie debugowania i sprawdź:
docker run -it my-image /bin/bash
- Zrozum różnicę między
CMDaENTRYPOINTi używaj ich odpowiednio do swojego celu.
Doświadczając tych problemów, Twoje umiejętności projektowania Dockerfile z pewnością się poprawią. Gdy napotkasz problem, spokojnie przeczytaj komunikat błędu i dokładnie prześledź, która warstwa lub instrukcja przyczyną.
7. Zakończenie
Potwierdzenie kluczowych punktów przy tworzeniu Dockerfile opartych na Ubuntu
W tym artykule wyjaśniliśmy krok po kroku, od podstaw po zastosowania, jak zbudować środowisko Ubuntu przy użyciu Dockerfile. Powtórzmy tutaj najważniejsze kwestie.
- Zrozumienie podstawowej struktury Dockerfile to pierwszy krok.
Możesz zautomatyzować konfigurację środowiska, łącząc instrukcje takie jak
FROM,RUN,CMDiENV. - Ubuntu jest stabilnym i bardzo elastycznym obrazem bazowym. Jego bogate repozytorium paków, duża baza użytkowników oraz dostępność wersji LTS sprawiają, że jest idealnym fundamentem dla środowisk deweloperskich.
- Możesz instalować niezbędne narzędzia i biblioteki poprzez praktyczne zarządzanie pakietami.
Znajomość użycia
apt-get, usuwania pamięci podręcznej i instalacji nieinteraktywnych to kluczowe elementy. - Budowanie praktycznych środowisk, jest również możliwe przy pomocy Dockerfile.
Narzędzia takie jak
pyenv,pipirequirements.txtumożliwiają tworzenie wysoce powtarzalnych środowisk deweloperskich. - Umiejętności rozwiąwania problemów bezpośrednio przekładają się na stabilną pracę. Zrozumienie typowych pułapek, takich jak problemy z uprawnieniami, kwestie sieciowe i pamięć podręczna budowania, może znacząco zwiększyć efektywność pracy.
Kolejne kroki w nauce Dockerfile
Umiejętność pracy z Dockerfile pozwala wspierać szeroki zakres zastosowań, nie tylko w rozwoju, ale także w testowaniu i wdrażaniu do środowisk produkcyjnych. W dalszej nauce warto przejść do następujących tematów:
- Zarządzanie konfiguracjami wielokontenerowymi przy użyciu Docker Compose.
- Integracja z narzędziami CI/CD (GitHub Actions, GitLab CI, itp.).
- Współpraca z narzędziami orkiestracji kontenerów, takimi jak Kubernetes.
8. FAQ (Najczęściej Zadawane Pytania)
P1. Którą wersję Ubuntu powinienem wybrać w moim Dockerfile?
A1. Zasadniczo, jeśli priorytetem jest stabilność i długoterminowe wsparcie, powszechnie wybiera się wersję LTS (Long Term Support). Na przykład ubuntu:22.04 i ubuntu:20.04 są używane w wielu środowiskach dewelopers i można z nich korzystać z pewnością dzięki 5‑letniemuowi wsparcia.
Z drugiej strony, jeśli chcesz korzystać z najnowszych pakietów i wersji języków, możesz wybrać nowsze wydanie, takie jak ubuntu:24.04, ale zalecamy przetestowanie go wcześniej.
Q2. Dlaczego pojawia się komunikat „Package not found” przy użyciu apt-get install?
A2. Najczęstszą przyczyną jest brak wcześniejszego uruchomienia apt-get update. Jeśli spróbujesz zainstalować pakiet bez odświeżenia listy, otrzymasz błąd, ponieważ odpowiedni pakiet nie zostanie znaleziony w przestarzałej liście.
Poprawny przykład użycia:
RUN apt-get update && apt-get install -y curl
Również zwracaj uwagę na literówki w nazwach pakietów oraz przestarzałe nazwy pakietów (np. python3 zamiast python).
Q3. Jak ustawić zmienne środowiskowe w Dockerfile?
A3. Zmienne środowiskowe ustawia się za pomocą instrukcji ENV. Ta zmienna będzie dostępna zarówno podczas budowania obrazu, jak i w czasie działania kontenera.
Przykład:
ENV DEBIAN_FRONTEND=noninteractive
Jest to typowe ustawienie używane do wyłączania interaktywnych podpowiedzi podczas instalacji APT. Służy także do definiowania konfiguracji aplikacji oraz kluczy API w Dockerfile.
Q4. Jaka jest różnica między CMD a ENTRYPOINT w Dockerfile?
A4. Obie instrukcje określają polecenia, które mają być wykonane przy uruchomieniu kontenera, ale różnią się sposobem użycia i zachowaniem.
| Item | CMD | ENTRYPOINT |
|---|---|---|
| Overridable | Can be overridden by the docker run command | Basically not overridden (treated as arguments) |
| Usage | Sets the default execution command | Defines a command that should always be executed |
Przykład:
CMD ["python3", "app.py"]
# vs
ENTRYPOINT ["python3"]
CMD ["app.py"]
W drugim przypadku możesz przekazać CMD jako argument w formie docker run my-image another_script.py.
Q5. Edytowałem mój Dockerfile, ale zmiany nie są widoczne. Dlaczego?
A5. Docker używa pamięci podręcznej podczas procesu budowania, więc nawet przy małych zmianach w Dockerfile mogą być użyte zbuforowane warstwy.
Rozwiązanie:
docker build --no-cache -t my-image .
Spowoduje to wykonanie nowego budowania bez użycia pamięci podręcznej, a wszystkie zmiany zostaną uwzględnione.



