Створіть власні Docker-образи за допомогою Dockerfile: покроковий посібник з прикладом на Django

pic

Багато з нас використовують Docker щодня, в основному через його портативність та філософію "plug and play", що забезпечує необхідну гнучкість для запуску програмного забезпечення.

Існує великий каталог Docker-образів на Docker Hub, офіційному репозиторії Docker. Ви можете знайти майже будь-який образ, необхідний для запуску програмного забезпечення.

Але що робити, якщо нам потрібно налаштувати нашу реалізацію на основі цього програмного забезпечення? Тут на допомогу приходять Dockerfile та створення власних Docker-образів. Docker може автоматично створювати образи, читаючи інструкції з Dockerfile. Dockerfile — це текстовий документ, що містить усі команди, які користувач зазвичай виконує в командному рядку для складання образу. Кожна команда користувача слідує такій структурі:

INSTRUCTION 

У цій статті ми надамо короткий огляд інструкцій Dockerfile та створимо Dockerfile з нуля, використовуючи їх.

Загальні інструкції в Dockerfile

COPY: Найпростіший спосіб додати файли або директорії з хост-машини до образу. Зазвичай використовується для додавання файлів або директорій, пов'язаних з проектом, який ми хочемо побудувати. Це просто копіює вказані файли або директорії.

COPY    

# наприклад, ми додаємо поточну директорію "." в образ, в директорію /app  
COPY . /app

ADD: Схоже на інструкцію COPY, але з додатковими можливостями. Вона може розпаковувати стиснуті файли при додаванні їх до образу та може отримувати файли з віддалених джерел (наприклад, URL-адрес).

  • Поведінка для локальних файлів така ж, як і у COPY.
  • Якщо файл стиснутий, він буде розпакований в образі.
  • Також можна отримати та додати файли з URL.
# Поведінка схожа на COPY для локальних файлів  
ADD . /app  

# Якщо файл стиснутий, він буде розпакований в образі  
ADD archive.tar.gz /app  

# Ви можете отримати архів за URL і додати завантажений файл в образ  
ADD https://example.com/file.tar.gz /app/

ARG: Використовується для визначення аргументів, які будуть отримані під час виконання команди побудови. Зазвичай ця інструкція вказується на початку Dockerfile.

ARG APP_ENV=production

Коли ви будуєте образ, ви можете вказати цей аргумент ось так

docker build --build-arg APP_ENV=development -t my-app .

ENV: Використовується для визначення змінних середовища, які можуть використовуватись як під час етапу побудови, так і під час виконання. Різниця з ARG полягає в тривалості: ARG існує лише під час етапу побудови, тоді як ENV змінні зберігаються після етапу побудови і можуть бути доступні під час роботи контейнерів.

# це може бути приклад використання тільки ENV  
ENV APP_ENV=production PORT=8000  

# використовується разом з ARG  
ARG APP_ENV=production  

# Передати значення ARG у змінну середовища  
ENV APP_ENV=$APP_ENV

Вибір між ENV та ARG залежить від вимог та тривалості існування змінної.

ENTRYPOINT: Визначає фіксований виконуваний файл або команду, яка завжди буде виконуватись при запуску контейнера. Призначено для визначення основного процесу для контейнера.

ENTRYPOINT ["python", "app.py"]

CMD: Визначає команду за замовчуванням, яка буде виконуватись при запуску контейнера. Зазвичай використовується для визначення основного процесу або точки входу для контейнера. Це дуже схоже на ENTRYPOINT. У Dockerfile може бути лише одна інструкція CMD. Якщо визначено кілька інструкцій CMD, використовується лише остання.
Це можна поєднати з ENTRYPOINT, де ENTRYPOINT визначає команду, а CMD визначає аргументи для цієї команди.

CMD ["python", "app.py"]  

## це запустить команду CMD за замовчуванням (після ENTRYPOINT, якщо воно визначене)  
docker run    
## це запустить команду, передану, в даному випадку ls  
docker run ls

Приклад, поєднаний з ENTRYPOINT:

ENTRYPOINT ["python"]  
CMD ["app.py"]

Приклад, поєднаний з ENTRYPOINT та ARG:

ARG SCRIPT_NAME=app.py  
ENV SCRIPT_NAME=$SCRIPT_NAME  
ENTRYPOINT ["python", "sh", "-c"]  
CMD ["$SCRIPT_NAME"]

Цей варіант дозволяє налаштувати команду побудови для визначення окремого образу, який при запуску контейнера запустить інший python файл:

# для запуску скрипта other_script при старті контейнера  
docker build --build-arg SCRIPT_NAME=other_script.py -t other-script-app .  
# для запуску скрипта my_script при старті контейнера  
docker build --build-arg SCRIPT_NAME=my_script.py -t my-script-app .

FROM: Використовується для визначення базового образу, який буде використовуватися для етапу налаштування.

FROM python:3.12.8

RUN: Використовується для виконання команд під час процесу побудови Docker-образу. Зазвичай використовується для встановлення залежностей та налаштування образу Docker.

# встановити pip  
RUN pip install --upgrade pip

WORKDIR: Використовується для зміни робочої директорії. Зазвичай використовується для того, щоб уникнути постійного використання повного шляху.

# без робочої директорії   
COPY . /app  
COPY another_files /app  
RUN /app/file  

# з робочою директорією  
WORKINGDIR /app  
COPY . .   
COPY another_files .  
RUN ./file

Це найпоширеніші інструкції, що використовуються в Dockerfile. Повний список інструкцій можна знайти в документації до Dockerfile.

Повний приклад Dockerfile

Давайте побудуємо повний приклад Dockerfile, використовуючи описані вище інструкції. Приклад створить образ для простого серверу Django.

FROM: Як приклад, ми використаємо офіційний образ Python 3.12.8.

FROM python:3.12.8

Порада: Рекомендується відвідати Docker Hub і знайти потрібний образ. Ви повинні перевірити, чи сумісний образ, який ви плануєте використовувати, з усіма архітектурами/ОС, які ви або ваша команда будете використовувати.

pic

ARG: ми визначимо список аргументів, які має наш додаток

FROM python:3.12.8  
# значення за замовчуванням = production  
ARG APP_ENV=production  
ARG APP_PORT=8000  
ARG APP_HOST=localhost

ENV: Аргумент APPENV повинен існувати лише під час процесу побудови, але APPPORT та APP_HOST, ймовірно, будуть використовуватися в додатку під час виконання. Тому ми також повинні оголосити їх як змінні ENV.

FROM python:3.12.8  
# значення за замовчуванням = production  
ARG APP_ENV=production  
ARG APP_PORT=8000  
ARG APP_HOST=localhost  

ENV APP_PORT=$APP_PORT  
ENV APP_HOST=$APP_HOST

WORKDIR: Ми встановлюємо WORKDIR на /app, щоб уникнути постійного використання повного шляху.

FROM python:3.12.8  
# значення за замовчуванням = production  
ARG APP_ENV=production  
ARG APP_PORT=8000  
ARG APP_HOST=localhost  

ENV APP_PORT=$APP_PORT  
ENV APP_HOST=$APP_HOST  

WORKDIR /app

COPY: Ми використовуємо COPY, оскільки припускаємо, що всі необхідні файли для проекту знаходяться локально. Якщо файли стиснуті або потрібно завантажити їх з URL, то використовуємо ADD.

FROM python:3.12.8  
# значення за замовчуванням = production  
ARG APP_ENV=production  
ARG APP_PORT=8000  
ARG APP_HOST=localhost  

ENV APP_PORT=$APP_PORT  
ENV APP_HOST=$APP_HOST  

WORKDIR /app  
COPY . . # Копіюємо всі файли з поточної директорії в директорію /app всередині образу

RUN: Оскільки ми використовуємо сервер Django як приклад, нам потрібно встановити залежності, необхідні для проекту.
У цьому випадку ми використовуватимемо pip для цього.

FROM python:3.12.8  
# значення за замовчуванням = production  
ARG APP_ENV=production  
ARG APP_PORT=8000  
ARG APP_HOST=localhost  

ENV APP_PORT=$APP_PORT  
ENV APP_HOST=$APP_HOST  

WORKDIR /app  
COPY . . # Копіюємо всі файли з поточної директорії в директорію /app всередині образу  
RUN pip install --upgrade pip && pip install -r ./requirements.txt # встановлюємо залежності

ENTRYPOINT: Після того, як залежності будуть встановлені, ми можемо запустити наш сервер. Ми визначаємо ENTRYPOINT як фіксовану команду, яку ми завжди використовуємо для запуску Django-сервера.

FROM python:3.12.8  
# значення за замовчуванням = production  
ARG APP_ENV=production  
ARG APP_PORT=8000  
ARG APP_HOST=localhost  

ENV APP_PORT=$APP_PORT  
ENV APP_HOST=$APP_HOST  

WORKDIR /app  
COPY . . # Копіюємо всі файли з поточної директорії в директорію /app всередині образу  
RUN pip install --upgrade pip && pip install -r ./requirements.txt # встановлюємо залежності   
ENTRYPOINT ["python", "manage.py"] # ми завжди використовуємо "python" та "manage.py" для запуску нашого сервера

CMD: Ми використаємо директиву runserver як команду за замовчуванням. Це можна змінити на будь-яку команду Django під час виконання команди docker run.

FROM python:3.12.8  
# значення за замовчуванням = production  
ARG APP_ENV=production  
ARG APP_PORT=8000  
ARG APP_HOST=localhost  

ENV APP_PORT=$APP_PORT  
ENV APP_HOST=$APP_HOST  

WORKDIR /app  
COPY . . # Копіюємо всі файли з поточної директорії в директорію /app всередині образу  
RUN pip install --upgrade pip && pip install -r ./requirements.txt # встановлюємо залежності  
ENTRYPOINT ["python", "manage.py"] # ми завжди використовуємо "python" та "manage.py" для запуску нашого сервера або будь-якої команди в django  
CMD ["runserver", "localhost:8000"] # запускає runserver за замовчуванням, якщо не вказано іншої команди

Ось і все! Ми вже створили свій власний Docker-образ для запуску Django-сервера. Для того, щоб побудувати його, потрібно виконати наступну команду:

docker build \  
 --build-arg APP_ENV=development \  
 --build-arg APP_PORT=8080 \  
 --build-arg APP_HOST=0.0.0.0 \  
 -t django-app .

Після створення образу, ми можемо його запустити:

docker run -p 8080:8080 django-app

І тепер ми запускаємо Django-сервер за допомогою кастомного Docker-образу.

Висновок

У цьому пості ми розглянули основні інструкції Dockerfile, які дозволяють створювати кастомні Docker-образи. Використовуючи простий приклад з Django-сервером, ми продемонстрували, як налаштувати змінні середовища, встановити залежності, визначити робочі директорії та налаштувати точки входу. Dockerfile надають гнучкість для налаштування вашого образу відповідно до потреб вашого додатку, що робить процес розгортання та управління легшим та ефективнішим. Незалежно від того, чи ви будуєте додаток на Django або будь-яке інше програмне забезпечення, розуміння того, як створити індивідуальний Dockerfile, є важливим кроком до оптимізації вашого робочого процесу контейнеризації.

Якщо вам сподобався цей посібник:

  • Слідкуйте за мною на Medium для інших посібників з Docker, Django та Golang.
  • Поділіться своїми відгуками в коментарях і дайте знати, чи був цей посібник корисним!
  • Не забудьте поділитися цим постом з вашою мережею.

Перекладено з: Create Your Own Docker Images Using Dockerfile: A Step-by-Step Guide with a Django Example

Leave a Reply

Your email address will not be published. Required fields are marked *