Docker - Dockerfile


Основное

FROM - Задать базовый образ

FROM debian, FROM ubuntu:18.04

Всегда обязателен и должен находиться первой строкой в Dockerfile

MAINTAINER - Метаданные об авторе


MAINTAINER Orlov Yaroslav <orlov.avis@yandex.ru>

RUN - Выполнить команду во время сборк образа


RUN apt-get update && apt-get install -y cowsay fortune

Добавление файлов в контейнер

ADD - Добавить файлы в контейнер

Копирует файлы из контекста создания или из удаленных URL-ссылок в создаваемый образ.

COPY - Скоприровать локальный файл (или диру) внутрь образа

Проще чем ADD т.к. не поддерживает URL, распаковку архивов и т.п.

Нельзя копировать вне контекста. Т.е. нельзя скопировать вне директори где Dockerfile

Пример


COPY entrypoint.sh /tmp

Если есть пробелы то нужно использовать формат json


$ ls -1
Dockerfile
hello world.txt

$ cat Dockerfile 
FROM ubuntu:bionic

COPY ["hello world.txt", "/hello world.txt"]

CMD cat "/hello world.txt"

$ docker run --rm docker_copy
hello world

VOLUME - Объявляет каталог или файл как том

Запуск команд в контейнере

ENTRYPOINT - Выполнить команду при запуске контейнера

Например - эта инструкция позволяет определить выполняемый файл, который будет вызываться для обработки любых аргументов, переданных в команду docker run .


$ cat Dockerfile 
FROM ubuntu

RUN apt-get update && apt-get install -y cowsay fortune

ENTRYPOINT ["/usr/games/cowsay"]

$ docker build -t cowsay/cowsay .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM ubuntu
 ---> 549b9b86cb8d
Step 2/3 : RUN apt-get update && apt-get install -y cowsay fortune
 ---> Using cache
 ---> 27a568a9fd69
Step 3/3 : ENTRYPOINT ["/usr/games/cowsay"]
 ---> Using cache
 ---> 3a274fbc0357
Successfully built 3a274fbc0357
Successfully tagged cowsay/cowsay:latest

$ docker run --rm cowsay/cowsay
 __
<  >
 --
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


Также можно создать скрипт для обработки параметров


$ cat entrypoint.sh
#!/usr/bin/env bash

if [ $# -eq 0 ]; then
    /usr/games/fortune | /usr/games/cowsay;
else
    /usr/games/cowsay "$@";
fi

$ cat Dockerfile 
FROM ubuntu

RUN apt-get update && apt-get install -y cowsay fortune

COPY entrypoint.sh /

ENTRYPOINT ["/entrypoint.sh"]

$ docker build -t avis20/my_cowsay .
Sending build context to Docker daemon  4.096kB
Step 1/5 : FROM ubuntu
 ---> 549b9b86cb8d
...

$ docker run --rm avis20/my_cowsay hello world
 _____________
< hello world >
 -------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

$ docker run --rm avis20/my_cowsay
 ________________________________
/ You may get an opportunity for \
\ advancement today. Watch it!   /
 --------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

CMD - Выполнить команду по умолчанию

Запускает инструкцию во время инициализации контейнера.

ENTRYPOINT VS CMD

В отличии от entrypoint, cmd можно переопределить

CMD


$ cat Dockerfile.cmd 
FROM ubuntu:bionic

CMD echo "hello"

$ docker build -t docker_cmd . -f Dockerfile.cmd 
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM ubuntu:bionic
 ---> 549b9b86cb8d
Step 2/2 : CMD echo "hello"
 ---> Using cache
 ---> 2df6050a0055
Successfully built 2df6050a0055
Successfully tagged docker_cmd:latest

$ docker run --rm docker_cmd
hello
$ docker run --rm docker_cmd echo hi
hi

entrypoint


$ cat Dockerfile.entrypoint 
FROM ubuntu:bionic

ENTRYPOINT echo 1

$ docker build -t docker_entrypoint . -f Dockerfile.entrypoint 
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM ubuntu:bionic
 ---> 549b9b86cb8d
Step 2/2 : ENTRYPOINT echo 1
 ---> Running in cdf959322499
Removing intermediate container cdf959322499
 ---> 862e875a4f63
Successfully built 862e875a4f63
Successfully tagged docker_entrypoint:latest

$ docker run --rm docker_entrypoint
1
$ docker run --rm docker_entrypoint echo dsadsa
1

Разное

ENV - Задает переменные окружения внутри контейнера

Переменные можно использовать внутри Dockerfile


$ ls -1
Dockerfile
file.txt

$ cat Dockerfile 
FROM ubuntu:bionic

ENV MYFILE file.txt

COPY $MYFILE /$MYFILE

CMD cat $MYFILE

$ docker build -t docker_env .
Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM ubuntu:bionic
 ---> 549b9b86cb8d
Step 2/4 : ENV MYFILE file.txt
 ---> Running in 8cc505125c07
Removing intermediate container 8cc505125c07
 ---> 6486c21fe929
Step 3/4 : COPY $MYFILE /$MYFILE
 ---> 7e5862a3aa2d
Step 4/4 : CMD cat $MYFILE
 ---> Running in 8a7610bc82ae
Removing intermediate container 8a7610bc82ae
 ---> 51f90ec36b62
Successfully built 51f90ec36b62
Successfully tagged docker_env:latest

$ docker run --rm docker_env 
1

Так и внутри контейнера


$ docker run --rm docker_env env 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=369515ff8f20
MYFILE=file.txt
HOME=/root

EXPOSE - Задать порт которые будет слушать контейнер

Задает порты которые контейнер слушает снаружи

WORKDIR - Задает рабочую директорию

USER - Задает пользователя для использования в инструкциях RUN, CMD, ENTRYPOINT и т.п.