Бесплатная миграция IT-инфраструктуры в облако

Docker: как создавать образы контейнеров и развертывать приложения

Александр Бархатов
Александр Бархатов
Технический писатель
31 октября 2024 г.
139
13 минут чтения
Средний рейтинг статьи: 5

Контейнеризация приложений — удобный и гибкий способ быстрого развертывания приложений, будь то веб-серверы, СУБД, системы мониторинга и так далее. Также контейнеры активно используются при работе с микросервисными приложениями. Для этих целей идеально подходит Docker, который максимально упрощает работу с контейнерными приложениями. Впервые Docker был представлен в 2013 году и с тех пор активно поддерживается и используется. Сегодня мы рассмотрим шаги по созданию своих собственных образов Docker для трех приложений на разных языках программирования, а также запустим их.

Предварительные требования

Для работы с платформой Docker нам понадобится следующее:

  • Сервер или виртуальная машина с любым предустановленным дистрибутивом Linux. Рекомендуем выбрать один из следующих дистрибутивов: Ubuntu, Debian, CentOS, Fedora, RHEL, SLES. Именно они заявлены в качестве поддерживаемых — для них всегда выпускаются стабильные и актуальные версии Docker. Мы будем использовать Ubuntu 22.04.

  • Установленный Docker. Процесс установки Docker на Ubuntu 22.04 можно найти в нашей инструкции. Также можно воспользоваться готовым образом с предустановленным Docker, выбрав его при создании облачного сервера на вкладке «Маркетплейс»

Создание облачного сервера

В первую очередь нужно арендовать облачный сервер. 

1) Переходим на страницу авторизации и входим в аккаунт при помощи логина или адреса электронной почты и пароля или при помощи Passkey, ВКонтакте, GitHub, Google.

2) После успешной авторизации отобразится панель управления текущего проекта. Переходим в раздел «Облачные серверы» и нажимаем «Создать» или «Добавить».

3) Выбираем операционную систему, которая будет установлена на сервер. В нашем случае нам необходима Ubuntu версии 22.04.

Image1

Также в этом же разделе можно выбрать уже готовый образ с Docker перейдя во вкладку «Маркетплейс»:

Image20

4) Выбираем регион, в котором будет находиться наш сервер. Выбирать рекомендуется тот регион, который ближе всего находится к вам физически. У каждого доступного региона справа вверху отображается ping, т.е. время, необходимое для передачи данных с вашего компьютера на сервер. Чем меньше указанное время, тем быстрее будет осуществляться передача данных.

Image16

5) Далее выбираем необходимую конфигурацию для сервера. Так как в данной статье будут рассмотрены только тестовые примеры по работе с образами Docker, то для конфигурации сервера можно выбрать минимальную доступную конфигурацию, включающую в себя одноядерный процессор, 1 ГБ оперативной памяти и 15 ГБ места на NVMe диске. В реальности вам необходимо выбирать именно ту конфигурацию, которая будет удовлетворять вашим потребностям при работе с контейнерными приложениями и их образами.

Стоит отметить, что сам Docker потребляет минимум ресурсов. Расчет необходимой конфигурации производится исходя из той нагрузки и конфигурации, которую будет использовать контейнер. Выбираем соответствующий тариф:

Image22

6) Далее необходимо решить, будет ли сервер доступен из внешний сети или же только из приватной (частной) сети. Если не уверены в настройках, оставьте эти параметры без изменений. 

7) По желанию можно оформить дополнительные услуги, включая резервные копии и защиту от DDoS-атак (последняя доступна только в Санкт-Петербурге и Москве).

8) Также заранее можно загрузить SSH-ключ, чтобы не входить на сервер при помощи пароля.

9) Можно задать необходимое имя для сервера которое будет отображаться в панели управления, а также выбрать проект.

10) Для создания сервера необходимо нажать на кнопку «Заказать»:

Image6

Если на вашем аккаунте недостаточно средств, то будет выведено предупреждение о необходимости пополнить баланс. После оплаты и создания сервера откроется Дашборд сервера, где можно будет найти IP-адрес, логин и пароль для подключения.

vds

Что такое образ Docker

В основе концепции Docker лежит понятие образа. Под образом понимают шаблон, по сути представляющий собой исполняемый файл, из которого из которого можно запустить Docker-контейнер. Внутри образа находится все, что необходимо для запуска готового приложения: исходный код, конфигурационные файлы, сторонние программы, утилиты и библиотеки.

Архитектура образов основана на слоях. Каждый слой — это какое-либо действие, совершенное внутри образа, например, создание файлов и каталогов или установка программ. В качестве файловой системы для Docker-образов используется OverlayFS, которая основана на объединении нескольких точек монтирования в одну, благодаря чему создается единая структура каталогов.

Созданный образ Docker можно переносить между системами и использовать сразу в нескольких местах по аналогии с исполняемыми файлами .exe для Windows-систем.

Создание собственных образов Docker

Рассмотрим, как создать образы для приложений Flask, Node.js и Go.

Создание Docker-образа для Flask-приложения

Для создания образов используется Dockerfile — текстовый файл без расширения? в котором указаны команды (инструкции) для создания образа контейнера. С инструкциями Dockerfile можно ознакомиться более подробно в официальной документации.

В качестве первого примера мы создадим и запустим Docker-образ, содержащий код на языке программирования Python с использованием фреймворка Flask, который используется для создания веб-приложений. В качестве приложения будет использоваться обычная HTML-страница, отображающая текущую дату.

Перед созданием приложения нам нужно установить пакетный менеджер pip, с помощью которого производится установка дополнительных Python зависимостей — пакетов, а также пакет python3-venv для создания виртуальных окружений. При помощи виртуальных окружений можно работать с разными версиями пакетов, тем самым избегая конфликтов при работе с двумя или более версиями разных пакетов. Команда установки будет следующей:

apt -y install python3-pip python3-venv

1) Создадим и перейдем в директорию, в которой будут храниться файлы проекта:

mkdir dockerfile-flask && cd dockerfile-flask

2) Далее создаем новое виртуальное окружение с именем env:

python -m venv env

После этого в корневой директории будет создана папка с именем env, где хранятся конфигурационные файлы виртуального окружения:

Image28

3) Для начала работы с виртуальным окружением его необходимо активировать при помощи команды:

source env/bin/activate

Image8

После активации слева от строки приглашения будет отображаться слово (env), которое говорит нам о том, что мы находимся в виртуальном окружении. Теперь при установке пакетов с помощью пакетного менеджера pip они будут устанавливаться на уровне виртуального окружения, не влияя на функционал системы.

4) Установим пакет flask при помощи pip:

pip install flask

Image7

Также необходимо отдельно установить пакет MarkupSafe версии 2.1.5:

pip install MarkupSafe==2.1.5

5) Переходим к процессу создания нашего тестового приложения. Внутри директории создаем файл с именем app.py, в котором будет храниться исходный код сервиса.

from flask import Flask
import datetime

app = Flask(__name__)

@app.route('/')
def display_current_date():
    current_date = datetime.datetime.now().date()
    return f"Current date is: {current_date}"

if __name__ == '__main__':
    app.run(debug=True)

6) Протестируем наш сервис. Для этого запустим приложение на любом адресе и на 80 порту при помощи команды: 

flask run --host=0.0.0.0 --port=80

Image9

Открываем приложение в браузере используя, IP-адрес сервера. Порт указывать не надо, так как  используется 80 порт по умолчанию:

Image12

Приложение успешно работает — при открытии страницы отображается текущая дата.

8) Последним шагом необходимо сохранить все зависимости (в нашем случае это только один пакет flask) в специальный текстовый файл под названием requirements.txt, где перечислены все сторонние пакеты, используемые в проекте и установленные при помощи pip. Для этого необходимо выполнить команду:

pip freeze > requirements.txt

Итоговая структура проекта изображена на скриншоте ниже:

Image19

Теперь можно переходить к созданию образа Docker.

7) Создаем Dockerfile со следующим содержимым:

FROM python:3.8-slim-buster

WORKDIR /app

COPY requirements.txt requirements.txt

RUN pip3 install -r requirements.txt

COPY . .

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0", "--port=80"]

Разберем данный Dockerfile:

  • FROM python:3.8-slim-buster

На данном этапе задается базовый образ. В данном примере мы выбрали образ с Python версии 3.8, который в свою очередь основан на slim-версии дистрибутива Debian Buster. Slim-образы меньше по размеру, чем обычные образы (например, по сравнению с обычным Debian Buster). 

  • WORKDIR /app

Команда для создания директории внутри образа. Является аналогом команды mkdir в Linux-дистрибутивах. В данном примере файлы проекта будут сохранены внутри директории app.

  • COPY requirements.txt requirements.txt

Команда COPY копирует файлы внутрь образа. В нашем примере мы копируем файл requirements.txt в образ, сохранив его с тем же именем.

  • RUN pip3 install -r requirements.txt

Команда RUN запускает команду внутри образа. При помощи RUN можно создавать файлы и папки, устанавливать пакеты, запускать сторонние утилиты и т.д. Для работы нашего Flask-приложения нам необходимо установить сторонние пакеты, перечисленные в файле requirements.txt, поэтому мы используем инструкцию RUN, задав ей необходимую команду.

  • COPY . .

Как уже было упомянуто ранее, команда COPY копирует файлы внутрь образа. Первая точка означает, что в образ будут скопированы рекурсивно все файлы из текущей директории, откуда запускается Dockerfile, в тот каталог, который был указан в команде WORKDIR (вторая точка).

  • CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0", "--port=80"]

Команда CMD предназначена для указания команд и параметров приложения, которые будут использованы при запуске контейнера. 

8) Также стоит упомянуть про использование файла .dockerignore, где можно указать те файлы и папки, которые не будут скопированы в образ. Это может быть полезно, чтобы уменьшить итоговый размер образа.

В нашем случае у нас есть директория env, которая не имеет отношения к запуску приложения, а также директория __pycache__.

Исключим данные директории из итого образа. Для этого создадим файл .dockerignore в корневой директории проекта и добавим необходимые файлы:

env
__pycache__

Image18

Обратите внимание, что файл .dockerignore является скрытым — перед именем файла необходимо указать символ точки.

Итоговая структура проекта выглядит следующим образом:

Image26

10) После того как Dockerfile был создан, можно приступать к сборке образа. Для этого используется команда docker build. При сборке образа необходимо использовать тег — уникальный идентификатор образа. В качестве имени можно задать имя приложения, а также указать версию. Например, запустим сборку образа, присвоив тег flask-app:01. Точка в конце команды означает, что Dockerfile находится в текущей директории, из которой выполняется команда:

docker build -t flask-app:01 .

Image3

После завершения сборки будет создан Docker-образ:

docker images

Image13

11) Готовый образ можно запустить при помощи команды docker run:

docker run -d -p 80:80 flask-app:01

Image5

Где:

  • -d — запускает контейнер в режиме «демона», то есть в фоновом режиме. 
  • -p 80:80 — ключ -p отвечает за проброс портов. По умолчанию доступ до контейнера из внешней сети отсутствует (доступ до контейнера можно получить только локально). Чтобы получить доступ до контейнера из сети интернет, необходимо пробросить порты. Сначала указывается порт, по которому будет доступен контейнер, далее указывается порт самого сервиса, который запущен в контейнере.   
  • flask-app:01 — имя образа и тег, который был задан на этапе сборки образа.

Проверим что образ был успешно запущен:

docker ps

Image14

В столбце STATUS должен отображаться статус Up.

Чтобы получить доступ до нашего приложения, необходимо использовать IP-адрес сервера и ранее заданный порт (так как у нас был задан 80 порт, его можно не указывать):

Image23

Как можно увидеть на скриншоте выше приложение успешно открылось.

Создание Docker-образа для Node.js-приложения

В качестве следующего примера создадим образ для приложения, которое написано на языке программирования JavaScript с использованием платформы Node.js. Приложение будет выводить на веб-странице фразу «This app was created using Node.js!».

Перед тем как приступить к работе с платформой Node.js, ее необходимо установить. Инструкция по установке Node.js в Ubuntu 22.04 приведена в нашей статье.

1) Создадим и перейдем в директорию, в которой будут храниться файлы проекта:

mkdir dockerfile-nodejs && cd dockerfile-nodejs

2) Инициализируем новый проект: 

npm init --yes

Image25

3) Далее установим дополнительный пакет под названием Express для создания веб-приложений:

npm install express --save

Image24

4) Создаем файл с именем app.js и используем следующий код для веб-приложения:

const express = require("express");
const app = express();

app.get("/", function(req, res) {
    return res.send("This app was created using Node.js!");
});

app.listen(3000, '0.0.0.0', function(){
    console.log('Listening on port 3000');
});

5) Убедимся, что приложение отрабатывает корректно. Для этого запускаем приложение при помощи команды:

node app.js

Image15

Далее открываем браузер и переходим по IP-адресу сервера, указав также порт приложения 3000:

Image11

Приложение успешно открывается.

6) Создаем Dockerfile со следующим содержимым:

FROM node:20

WORKDIR /app

COPY package.json /app

RUN npm install

COPY . /app

CMD ["node", "app.js"]

7) Как и при работе с Flask-приложением, у Node.js присутствуют файлы, которые не нужны для запуска самого приложения. В данном случае это директория node_modules, где хранятся сторонние библиотеки, которые можно использовать в вашем проекте при необходимости. Создадим скрытый файл .dockerignore в директории проекта со следующим содержимым:

**/node_modules/

Image17

8) Далее можно запускать сборку образа:

docker build -t nodejs-app:01 .

Image30

9) После того как процесс сборки образа будет завершен, можно запустить контейнер при помощи команды:

docker run -d -p80:3000 nodejs-app:01

Image10

В качестве порта приложения (источника) мы задали порт 3000, так как он был указан в коде приложения.

Для проверки работоспособности приложения перейдем в браузере по IP-адресу сервера и порту:

Image4

Приложение успешно работает.

Создание Docker-образа для Go-приложения

В качестве еще одного языка программирования мы рассмотрим Go, который часто используется для создания как многочисленных сетевых утилит, так и для написания микросервисов. В качестве теста будем использовать простое приложение которые выводит фразу «Hello from GO!».

Для начала необходимо установить сам язык Go. Процесс установки Go на Ubuntu приведен в нашей инструкции.

1) Создадим и перейдем в директорию, в которой будут храниться файлы проекта:

mkdir dockerfile-go && cd dockerfile-go

2) Инициализируем новый модуль Go:

go mod init go-test-app

Image29

3) Создаем файл с именем main.go и вставляем следующий код:

package main

import "fmt"

func main() {
    fmt.Println("Hello from GO!")
}

Проверим, что приложение запускается корректно:

go run .

Image31

4) Переходим к созданию Dockerfile:

FROM golang:1.23-alpine

WORKDIR /app

COPY go.mod ./
RUN go mod download

COPY *.go ./

RUN go build -o /go-test

CMD [ "/go-test" ]

В Dockerfile были использованы директивы:

  • COPY go.mod ./

Копирует файл go.mod внутрь образа, в котором перечислены зависимости проекта.

  • RUN go mod download

Скачивает зависимости, указанные в файле go.mod.

  • COPY *.go ./

Копирует все остальные файлы, расширение которых заканчивается на .go.

  • RUN go build -o /go-test

Запускает процесс компиляции.

5) Запускаем процесс сборки Docker-образа для нашего Go-приложения:

docker build -t go:01 .

Image2

6) Запустим созданный образ. Так как у нас простое приложение, которое выводит только одну фразу, ключ -d для запуска не нужен:

docker run go:01

Image27

В выводе программы отобразилась фраза «Hello from GO!».

Разворачивайте приложения на VDS/VPS в Timeweb Cloud

Заключение

В данной статье мы рассмотрели процесс создания своих собственных образов Docker для трех разных приложений на трех разных языках программирования. При помощи Docker можно легко «упаковать» любое приложение и также легко его развернуть.

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
31 октября 2024 г.
139
13 минут чтения
Средний рейтинг статьи: 5
Пока нет комментариев