---
# System prepended metadata

title: dockek

---

# dockek

## Что?
![](https://i.imgur.com/sNzKSrQ.png)
![](https://i.imgur.com/uf5GsXT.png)
![](https://i.imgur.com/lnV2w65.png)

### что такое, зачем нужно
- аналог -- виртуальная машина (но докер-контейнеры легче и удобнее в использовани)и
- система контейнеризации приложений, позволяет облегчить развертывание, благодаря тому, что необходимые сервисы "упаковываются" внутрь контейнера вместе с зависимостями
- использует [unionFS](https://habr.com/ru/company/skillfactory/blog/547116/) (не то чтобы нужно знать, но иногда полезно это учитывать при написании докерфайлов)
- кроссплатформенный
- работает как `client - daemon`. У вас поднимается докер-демон, который менеджит локальные контейнеры, в случае чего пуллит недостающие (например). взаимодействе с ним осуществляется через клиента (`docker` в консольке, например)

### установка

- вообще [тут](https://www.docker.com/)
- но! должен быть доступен в вашем пакетном менеджере (про brew не уверен)

## getting started

### container
[тут!](https://docs.docker.com/engine/reference/run/)
- к этому можно относиться как к мини-виртуалке с любым линуксом под капотом на ваш скромный вкус

***потыкаем***:

так, например, можно заспавнить себе убунту:

```
❯ docker run -t -d --name ubunta ubuntu
274f4ee47ac8694939d156c5c6de1fba5fc8f80cd65656477f56d51c746cdb60
```

- `-t` -- заспавнить tty. Примечательно, что если в контейнере нет работающих процессов -- он умирает
- `-d` -- запустить контейнер в бекграунде
- `--name` -- ну вы поняли
- `ubuntu` -- имя образа

а вот так можно развернуть постгрес за 0 секунд:

```
❯ docker run --name postgreskek -e POSTGRES_PASSWORD=mysecretpassword -d postgres                                                           
6e676f8c862f4cb202062518fa5cabe4a2f439971a2ca3247bd5e831e4302a5c
❯ docker ps # так можно посмотреть список запущенных контейнеров                                                   
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS          PORTS      NAMES
6e676f8c862f   postgres   "docker-entrypoint.s…"   4 seconds ago    Up 3 seconds    5432/tcp   postgreskek
274f4ee47ac8   ubuntu     "bash"                   20 minutes ago   Up 20 minutes              ubunta
816667d6b6a4   ubuntu     "bash"                   50 minutes ago   Up 50 minutes              kek

```
- `-e` -- прокидывает в контейнер указанные переменные окружения
- отметим, что постгресс внутри контейнера разворачивается на каком-то порту, который затем пробрасывается на `5432` порт локальной сети (или не локальной). При желании порты можно прокидывать еще, например, так:
-- `-p 127.0.0.1:8080:80/tcp` (здесь 8080 -- порт в контейнере, 80 -- порт который доступен снаружи)
*или так* 
-- `-p 8080:80`
*или так* 
-- `--expose 80` 

**а еще существуют вольюмы!**
![](https://i.imgur.com/8lCsZsE.png)


-- это общие директории, которые делят наша файловая система и фс контейнера (указанная директория банально маунтится внутрь)

```
❯ docker run --name vo -d -t -v /home/whiskey/vol:/vol ubuntu
```
- первый аргумент -- откуда, второй -- куда


***ну и всякое***
- с контейнерами можно делать еще всякие-разные вещи, вот самое банальное и частоиспользуемое
```
exec        docker exec -it <name> <cmd> # запускает ваши команды внутри контейнера
restart     docker restart <name>
rm          docker rm <name>
kill        docker kill <name>
ps/list     docker ps # список всех запущенных контейнеров (вообще всех - с флагом "--all")
```

### image
- "read-only" шаблон для создания контейнера. Зачастую вы не хотите с нуля собирать контейнер (например, когда пишете докерфайл), так как логично взять за основу что-то существующее. Если вы хотите написать что-то на джанге (питон-фреймворк), в таком случае можно использовать образ с установленным питоном, например.


```
FROM python:3.7-alpine <--- образ

COPY marks /marks

COPY requirements.txt requirements.txt
```

***cписок всех образов:***

```
❯ docker image list # список всех образов                                               
REPOSITORY            TAG           IMAGE ID       CREATED         SIZE
wodby/drupal          9-4.40.3      07b70fa30175   12 days ago     484MB
wodby/mariadb         10.7-3.17.1   1a7eb68ce620   2 weeks ago     283MB
wodby/nginx           1.21-5.21.3   35c6896f8513   2 weeks ago     38.8MB
server_bot            latest        6e8ebba19963   9 months ago    1.45GB
exoplanet_exoplanet   latest        02ad170d9f2d   10 months ago   910MB
mysql                 5.7           87eca374c0ed   11 months ago   447MB
mailhog/mailhog       latest        4de68494cd0d   19 months ago   392MB
traefik               v2.0          2874b2a534b9   2 years ago     69.3MB
drupal                8.0.0         0312ffeb007b   6 years ago     571MB
```
***Главное помнить, что спулленные образы занимают место на диске (иногда очень много), поэтому имеет смысл чистить их раз в какое-то время:***

```
❯ docker system prune # удалить неиспользуемые образы
❯ docker system prune -a # удалить вообще все 
```

***Существуют специальные хранилища образов, как глобальные ([докерхаб](https://hub.docker.com/)), так и [локальные](https://docs.docker.com/registry/)***

### dockerfile

* Файл c инструкциями, по которым будет собираться ваш контейнер (или образ)
* каждая строчка докерфайла -- новый слой (см. про unionFS)

***коротко про основной синтаксис:***

```
FROM python:3.7-alpine

COPY marks /marks

COPY requirements.txt requirements.txt

RUN pip3 install -r requirements.txt

WORKDIR /marks

RUN touch db.sqlite3

RUN python3 manage.py makemigrations && python3 manage.py migrate

EXPOSE 8000 

CMD ["gunicorn", "-b", "0.0.0.0:8000", "--workers=2", "--threads=4", "marks.wsgi"]

```

- `FROM ...` -- здесь указывается родительский образ
- `COPY <from> <to>` -- копирует файлы/директории в контейнер. Первый аргумент -- откуда (с вашего компухтера), второй -- куда (внутрь контейнера)
- `WORKDIR <dir>` -- устанавливает директорию, относительно которой будут выполняться последующие команды
- `EXPOSE <port>` -- открывает порт внтури контейнера
- `CMD ["arg1", "arg2", ...]` - аргументы, с которыми будет запускаться контейнер. их можно переопределять в командной строке. 
`docker run --name test test/test-backend /srv/www/bin/gunicorn.sh <-- переопределение CMD`
в докерфайле `CMD` может присутствовать лишь один раз.  

*также еще бывают:*

- `ENV <var>=value` -- делает переменную окружения
- `ADD <from> <to>` -- тоже самое, что и `COPY`, только умнее. Умеет, например, брать файл по ссылке. Но вообще не рекомендуется к использованию.
- `ENTRYPOINT ["arg1", "arg2", ...]` -- похоже на `CMD`, однако не переопределяется

ну и еще много [других](https://docs.docker.com/engine/reference/builder/)

***С помощью докерфайлов можно создавать образы:***

```
❯ docker build <dockerfile_path>
```

***Но что делать, если мы захотим одновременно управлять >1 докер-контейнером?***


### docker-compose !!

- docker-compose используется для одновременного управления несколькими контейнерами, входящими в состав приложения. он предлагает те же возможности, что и докер, но позволяет работать с более сложными приложениями.

***выглядит это как-то так***:

```
# docker-compose.yaml
version: '3.0'   # версия

services:        # список сервисов, в будущем - образов  иконтейнеров
  marks:         # название сервиса 
    build:       # Опции для того, чтобы сбилдить образ
      context: . # директория, содержащая докерфайл, или путь до гит-репозитория с ним
      dockerfile: docker_config/backend/Dockerfile # сам докерфайл, из которого будет билдится образ
    restart: on-failure # опция для рестарта контейнера
    ports: # порты!
      - 10010:8000

  bot:
    build: 
      context: .
      dockerfile: docker_config/bot/Dockerfile
    restart: on-failure

  redis: # редис, в данном случае, не требует докерфайла, его можно билдить просто по образу. Стоит заметить, что наличие секции image не исключает секцию build.
    image: redis:5.0.5-alpine
    restart: on-failure
```

***запускатеся так***

```
❯ docker-compose up --build -d
```

- Появились образы. Почему их больше чем 3? дело в том, что на каждый из двух докерфайлов в docker-compose приходится еще по одному образу, от корого он наследуется.
```
❯ docker image ls                                                     
REPOSITORY     TAG            IMAGE ID       CREATED              SIZE
server_bot     latest         88f300fc75b5   15 seconds ago       1.57GB
server_marks   latest         17325b8078c5   About a minute ago   92.9MB
python         3.7-alpine     c36f68524a0e   8 days ago           46.3MB
python         3.7            b5b74728b4f4   8 days ago           903MB
redis          5.0.5-alpine   ed7d2ff5a623   2 years ago          29.3MB

```
- А вот активные контейнеры:
```
❯ docker ps                                                           
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS         PORTS                                         NAMES
95d803b318d7   server_marks         "gunicorn -b 0.0.0.0…"   2 minutes ago   Up 2 minutes   0.0.0.0:10010->8000/tcp, :::10010->8000/tcp   server-marks-1
31fce1d91e7c   server_bot           "python3 bot.py"         2 minutes ago   Up 2 minutes                                                 server-bot-1
11cf77ab8d84   redis:5.0.5-alpine   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   6379/tcp                                      server-redis-1

```

***выключается так***
```
❯ docker-compose down
```
- флаг `--build` будет ребилдить сервисы каждый раз, если он указан. Запуск приложения без этой опции приведет к продолжению работы (как до выключения (`down`))


***Также еще существуют команды:***
```
docker-compose logs
docker-compose restart
...
```
и [другие](https://docs.docker.com/compose/)

их суть, кажется, понятна, или, по крайней мере, достаточно описана

### кажется, это все..
![](https://i.imgur.com/GnDuqiB.jpg)


