# Решения ### 1. Установка Docker Инструкции доступны на https://docs.docker.com/engine/install/debian/ #### Добавление GPG ключа официального репозитория Docker ````bash sudo apt-get update sudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg ```` #### Добавление репозитория в apt ````bash echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update ```` #### Установка пакетов Docker ````bash sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin ```` ### 2. Базовые команды #### 1. ````bash sudo docker run hello-world ```` #### 2. ````bash sudo docker pull busybox ```` #### 3. ````bash sudo docker run busybox echo 'Hello, World!' ```` #### 4. ````bash sudo docker run -it busybox ```` Внутри контейнера: ````bash echo 'Hello, World!' exit ```` Вообще, под "интерактивным режимом" здесь понимается именно два флага: `-i` и `-t`.\ Флаг `-i`, или собственно `--interactive`, означает, что stdin контейнера открыт и идет с хоста.\ А вот флаг `-t`, хотя и не обязателен, создает для контейнера псевдо-TTY. Чем чревато его отсутствие -\ студентам надо погуглить или напороться на это самим. #### 5. ````bash sudo docker run --name hello_world busybox echo 'Hello, World!' ```` После этого: ````bash sudo docker start -a hello_world ```` Здесь важен флажок `-a`, т.е. чтобы stdout контейнера приаттачился, чтобы 'Hello, World!' вывелся на экран. #### 6. ````bash sudo docker create --name hello_world_delayed_start busybox echo 'Hello, World!' sudo docker start -a hello_world_delayed_start ```` #### 7. ````bash sudo docker run -d --name infinite_print busybox ash -c 'while true; do date +%T; sleep 1; done' ```` Для просмотра логов: ````bash sudo docker logs infinite_print ```` #### 8. Для вывода работающих контейнеров: ````bash sudo docker ps ```` или ````bash sudo docker container ls ```` Для вывода всех контейнеров: ````bash sudo docker ps -a ```` или ````bash sudo docker container ls -a ```` Для вывода остановленных контейнеров: ````bash sudo docker ps -a -f status=exited -f status=created ```` или ````bash sudo docker container ls -a -f status=exited -f status=created ```` #### 9. ````bash sudo docker container prune -f ```` или же ````bash sudo docker rm $(docker ps -a -q -f status=exited -f status=created) ```` #### 10. ````bash sudo docker attach infinite_print ```` В параллельном терминале, для паузы: ````bash sudo docker pause infinite_print ```` Для возобновления работы: ````bash sudo docker unpause infinite_print ```` Для детача надо нажать комбинацию C-p C-q, но тут есть хитрость: Для того, чтобы это было возможно, надо чтобы контейнер, запущенный с -d был запущен еще с -it Т.е. ````bash sudo docker run -dit --name infinite_print busybox ash -c 'while true; do date +%T; sleep 1; done' ```` Для остановки(мгновенно): ````bash sudo docker kill infinite_print ```` или (если главный процесс не отвечает, придется немного подождать, прежде чем ему придет SIGKILL) ````bash sudo docker stop infinite_print ```` или (но тогда контейнер будет не только остановлен но и удален) ````bash sudo docker rm -f infinite_print ```` #### 11. ````bash echo 'Hello, World!' > ~/hello.txt sudo docker run -it --name hello_with_file busybox ```` В параллельном терминале: ````bash sudo docker cp ~/hello.txt hello_with_file:/ ```` В терминале с интерактивным контейнером: ````bash cat /hello.txt ```` #### 12. Листинг корневой директории: ````bash sudo docker exec hello_with_file ls / ```` Дифф файловой системы: ````bash sudo docker diff hello_with_file ```` Удаление файла: ````bash sudo docker exec hello_with_file rm /hello.txt ```` ### 3. Volumes #### 1. Для монтирования директории: ````bash docker run --mount type=bind,source=/home/stud,target=/home/stud -it busybox ```` Внутри контейнера ````bash ls /home/stud ```` #### 2. ````bash docker volume create my-volume ```` Для просмотра свойств: ````bash docker volume inspect my-volume ```` #### 3. Вывод всех томов: ````bash docker voume ls ```` #### 4. ````bash docker run -it --mount type=volume,source=my-volume,target=/data busybox ```` #### 5. Внутри контейнера: ````bash echo 'Hello, world!' > /data/hello.txt ```` Потом - остановить контейнер, далее сделать например `docker container prune`, повторить запуск как на \ предыдущем шаге, и внутри контейнера сделать: ````bash cat /data/hello.txt ```` #### 6. ````bash docker container prune -f && docker volume prune -a -f ```` ### 4. Сеть #### 1. ````bash docker network create -d bridge --subnet=172.168.0.0/16 --gateway=172.168.0.1 my-network ```` #### 2. Просмотр всех сетей: ````bash docker network ls ```` Просмотр свойств: ```bash docker network inspect my-network ``` #### 3. ````bash docker run --name cats_app --mount type=bind,source=./cats_app,target=/app --network my-network -it python:3.12 /bin/bash ```` #### 4. Внутри контейнера: ````bash cd /app && ./install.sh && ./run.sh ```` #### 5. ````bash docker run --network my-network --publish 8080:80 --mount type=bind,source=./cats_app/nginx.conf,target=/etc/nginx/nginx.conf nginx ```` #### 6. ````bash docker run --name cats_app --mount type=bind,source=./cats_app,target=/app --network my-network -p 127.0.0.1:5001:5000 -it python:3.12 /bin/bash ```` Внутри контейнера: ````bash cd /app && ./install.sh && ./run.sh ```` #### 7. ````bash docker run --mount type=bind,source=./cats_app,target=/app --network host -it python:3.12 /bin/bash -c 'cd /app && ./install.sh && ./run.sh' ```` ### 5. Работа с образами #### 1. ````Dockerfile from busybox entrypoint /bin/echo 'Hello, World!' ```` #### 2. В директории с Dockerfile: ````bash docker build -t hello . ```` #### 3. ````bash docker image ls ```` Для просмотра свойств: ````bash docker image inspect hello ```` #### 4. ````bash docker run hello ```` #### 5. ````Dockerfile from busybox env name 'World' entrypoint /bin/echo "Hello, $world!" ```` В директории с Dockerfile: ````bash docker build -t hello . && docker run -e name=Student hello ```` Здесь будет интересно если студенты наткнутся на разницу в ````Dockerfile entrypoint /bin/echo "Hello, $world!" ```` и ````Dockerfile entrypoint ["/bin/echo", "Hello, $world!"] ```` #### 6. ````bash docker tag hello hello:1.0.0 ```` #### 7. Сохранение: ````bash docker save hello -o hello.tar ```` Удаление: ````bash docker rmi -f $(docker images -q -f 'reference=hello:*') ```` Восстановление: ````bash docker load -i hello.tar ```` #### 8. Предположим что Dockerfile находится в этой же директории, а исходники \ приложения лежат в `./cats_app` ````Dockerfile from python:3.12 copy ./cats_app /app workdir /app run ./install.sh entrypoint ["python3", "app.py"] ```` Создание образа: ````bash docker build -t cats_app . ```` Запуск: ````bash docker run -p 5000:5000 cats_app ```` 9. ````bash docker run --name registry --detach -p 127.0.0.1:12345:5000 --mount type=bind,source=./registry,target=/var/lib/registry registry:2 ```` Инструкции для более сложного сетапа можно посмотреть тут: https://medium.com/@ManagedKube/docker-registry-2-setup-with-tls-basic-auth-and-persistent-data-8b98a2a73eec 10. Создание тегов для локального реестра: ````bash docker tag hello localhost:12345/hello docker tag hello:1.0.0 localhost:12345/hello:1.0.0 docker tag cats_app localhost:12345/cats_app ```` Загрузка образов: ````bash docker push -a localhost:12345/hello docker push -a localhost:12345/cats_app ```` Удаление из локальной инсталляции докера: ````bash docker rmi -f $(docker images -q -f 'reference=*/hello:*') docker rmi -f $(docker images -q -f 'reference=hello:*') docker rmi -f $(docker images -q -f 'reference=*/cats_app:*') docker rmi -f $(docker images -q -f 'reference=cats_app:*') ```` Запуск: ````bash docker run -p 8080:5000 localhost:12345/cats_app ```` ````bash docker run localhost:12345/hello ````