Технологии программирования
Docker. Переменные окружения.
Переменные окружения
class Temp {
public static void main(String[] args) {
Map<String, String> env = System.getenv();
}
}
Задать в windows (см ссылку):
set VAR_NAME=VAR_VALUE
Задать в linux/macos
export VAR_NAME=VAR_VALUE
или в файле .bashrc
Переменные окружения
- Локальные
- Пользовательские
- Системные
В linux пользовательские и системные переменные окружения можно задать в специальных файлах конфигурации:
- .bashrc
- .bash_profile
- /etc/environment (для всех файлов, даже при удаленном подключении)
- /etc/bash.bashrc
- /etc/profile
Почитать подробнее можно тут
Основные компоненты Docker
-
Dockerfile. Текстовый файл с последовательно расположенными инструкциями для создания образа Docker. Файл создаётся по принципу «одна строка — одна команда».
-
Daemon. Фоновая служба на хосте, которая отвечает за создание, запуск и уничтожение контейнеров.
-
Image. Неизменяемый файл (образ), из которого можно неограниченное количество раз развернуть контейнер.
-
Client. Утилита командной строки в Docker для управления демоном. Любое взаимодействие с контейнером проходит через Daemon.
-
Container. Запущенное приложение, которое развернули из образа.
-
Registry. Служба в Docker, выполняющая функции репозитория (хранилища). Позволяет следить за версиями образов, создавать приватные репозитории.
-
Docker Hub. Популярный публичный репозиторий, используемый по умолчанию в Docker. Обеспечивает интеграцию с GitHub и BitBucket.
-
Docker Desktop. Приложение, позволяющее локально собирать, выполнять и тестировать контейнеры. Работает на Windows и macOS.
-
Docker volumes. Тома для постоянного хранения информации. По умолчанию в Docker папки хранилищ создаются на хост-машине, но предусмотрена и возможность подключения удаленных хранилищ. Использование томов позволяет лучшим образом настроить хранение данных.
Как устроен образ Docker
Базовый образ — главный элемент контейнеризации в Docker. В нем содержатся процессы и зависимости, необходимые для нормальной работы приложения.
Если образ — это набор доступных только для чтения слоев, то контейнер представляет собой тот же образ, но с еще одним слоем сверху — с возможностью записи. Информация записывается в контейнер, а когда он уничтожается, верхний слой и содержащиеся в нем данные пропадают. В случае необходимости создается новый (чистый) контейнер из старого образа.
Как развернуть образ
docker run image_name: tag_name
Dockerfile
- FROM — задаёт базовый (родительский) образ.
- LABEL — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ.
- ENV — устанавливает постоянные переменные среды.
- RUN — выполняет команду и создаёт слой образа. Используется для установки в контейнер пакетов.
- COPY — копирует в контейнер файлы и папки.
- ADD — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы.
- CMD — описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен. Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция CMD.
- WORKDIR — задаёт рабочую директорию для следующей инструкции.
- ARG — задаёт переменные для передачи Docker во время сборки образа.
- ENTRYPOINT — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются.
- EXPOSE — указывает на необходимость открыть порт.
- VOLUME — создаёт точку монтирования для работы с постоянным хранилищем.
Пример докер-файла:
FROM python:3.7.2-alpine3.8
LABEL maintainer="jeffmshale@gmail.com"
ENV ADMIN="jeff"
RUN apk update && apk upgrade && apk add bash
COPY ./myUserService.jar ./app
CMD ["java", ".app/myUserService.jar"]
Обычно сборка и деплой автоматизируют в таких системах, как teamcity или jenkins
Чуть более сложный вариант:
FROM python:3.7.2-alpine3.8
LABEL maintainer="jeffmshale@gmail.com"
# Устанавливаем зависимости
RUN apk add --update git
# Задаём текущую рабочую директорию
WORKDIR /usr/src/my_app_directory
# Копируем код из локального контекста в рабочую директорию образа
COPY . .
# Задаём значение по умолчанию для переменной
ARG my_var=my_default_value
# Настраиваем команду, которая должна быть запущена в контейнере во время его выполнения
ENTRYPOINT ["python", "./app/my_script.py", "my_var"]
# Открываем порты
EXPOSE 8000
# Создаём том для хранения данных
VOLUME /my_volume
Пример, который мы билдили на лекции:
# базовый образ
FROM ubuntu:20.04
# установка желаемых пакетов и зависимостей
RUN apt-get update
RUN apt-get install -y wget && echo "We installed wget!"
# создание каталога /mytest
WORKDIR /mytest
# создание файла testfile
RUN touch testfile
# ls и echo будут выполняться при запуске контейнера
CMD ls && echo "Show me mytest"
Создадим образ по нашему докерфайлу:
docker build -f </путь/до/Dockerfile> -t <имя_создаваемого_образа> </путь/до/контекста>
Посмотреть список всех контейнеров:
docker ps -a
Запустить наш образ
docker run <our image> <command>
Мы можем сохранить образ, чтобы передать его:
sudo docker save --output <имя_файла_образа> <ID_исходного_образа>
Удалить неиспользуемые контейнеры, сети и образы:
docker system prune
Больше информации можно прочитать туть
Docker-compose
Для запуска нескольких контейнеров можем использовать docker-compose. Также в нем можем конфигурировать запуск контейнеров и взаимосвязи между контейнерами (например, пробрасывать порты, создавать volume) Из чего состоит docker-compose файл:
version: "3.7"
services:
...
volumes:
...
networks:
...
services:
network-example-service:
image: karthequian/helloworld:latest
ports:
- "80:80"
...
my-custom-app:
image: myapp:latest
ports:
- "8080:3000"
...
my-custom-app-replica:
image: myapp:latest
ports:
- "8081:3000"
...
volumes:
my-named-global-volume:
services:
database:
image: "postgres:${POSTGRES_VERSION}"
environment:
DB: mydb
USER: "${USER}"
Как запустить?
docker-compose up
Как свернуть?
docker-compose down