[Docker] ホストマシンのvolume mountの設定方法

ホストマシンとコンテナのボリュームをマウント

e.g.
ホストマシンの ~/work と コンテナ内の /myapp を同期させる

~/work/file1.txt
/myapp/file2.txt

ファイル名が同じだった場合、ホストマシンがコンテナを上書きする

### Dockerにおけるマウント指定
Dockerによる環境構築をする際、ボリュームをマウントする方法はDockerfile, Composeファイル、コマンドラインの3つがある

### 1. Dockerfileによるマウント
Dockerfile内でVOLUME命令を書く。この命令では、引数としてコンテナ側のディレクトリしか指定することはできない

VOLUME /myapp

Dockerfile

FROM debian
RUN mkdir /myapp && \
	echo "Hello, World" > /myapp/file.txt
VOLUME /myapp

$ sudo docker build -t hello .
$ sudo docker run -it hello bash
# cat /myapp/file.txt
Hello, World

Dockerfileにボリュームのマウント設定をする際は、ホストマシンのディレクトリを指定することができない

### 2. docker-composeによるマウント
composeファイルでは、ホストマシンのディレクトリも指定することができる

volumes:
  - ./work:/myapp

– ホストマシンのディレクトリ: Composeファイルから見た相対パスもしくは絶対パス
– コンテナのディレクトリ: 絶対パス

$ tree
.
├── docker-compose.yml
└── test
└── file.txt
$ cat test/file.txt
hello shinbashi!

docker-compose.yml

version: '3'
services:
  web:
    image: debian
    volumes:
      - ./test:/myapp

$ sudo docker-compose run web bash
Creating network “entrypoint_default” with the default driver
root@e8b020e943ae:/# cat /myapp/file.txt
hello shinbashi!
root@e8b020e943ae:/#

### DockerfileとComposeファイルを同じディレクトリに作成
$ tree
.
├── Dockerfile
├── docker-compose.yml
└── test
└── file.txt

dockerfile

FROM debian
RUN mkdir /myapp && \
	echo "It's a beautiful day." > /myapp/another_file.txt

docker-compose.yml

version: '3'
services:
  web:
    build: . 
    volumes:
      - ./test:/myapp

なるほどー、少し見えなかったものが見えてきた

[Docker] ADDとCOPYの違い

### ADD
– リモートからもファイル追加できる
– 圧縮ファイルが自動解凍

### COPY
– リモートからのファイル追加はできない
– 圧縮ファイルは自動解凍されない

FROM alpine

# auto unarchive
ADD add.txt.gz /tmp

# Can add from remote
ADD https://github.com/github/fetch/blob/master/README.md /tmp

# Not auto unarchive
COPY copy.txt.gz /tmp

なるほど、mountするときは、Add . /tmp を使って、buildする際は COPY を使うのか
少しずつ繋がっていく感じか…

[Docker] ENTRYPOINTは「必ず実行」、CMDは「デフォルト引数」

$ docker run -it centos
bashが起動する理由は、公式イメージで、/bin/bashを実行する命令があるため

CMD [“/bin/bash”]

引数の指定があれば、その引数の実行が優先される

$ docker run -it centos /bin/sh

### ENTRYPOINTが入った場合

FROM centos:latest
ENTRYPOINT ["ping", "-c", "3", "1.1.1.1"]

なるほど、ENTRYPOINTとCMDの違いがなんとなくわかったわ
ENTRYPOINTって言うと、なんか最初の引数みたいだけど、PID1の実行コマンドなのね。
奥が深いにゃー

[Docker] CMD命令とENTRYPOINT命令

CMD命令とENTRYPOINT命令はコンテナ内で実行するPID1のプロセスを指定するもの
このイメージは一体何をするのか、何のためのイメージなのかを決定づける命令

FROM debian:9
CMD ping

$ sudo docker build -t myimage .
$ sudo docker run –rm –name myimage myimage
$ sudo docker run myimage date

CMD命令とは
PID1として実行するプロセスのコマンドを指定できる
※PID1とはinitプロセスであり、起動した時に最初に実行するコマンド
そのコマンドは docker run ${image} ${引数} の引数で上書きできる

### ENTRYPOINT命令のきそ

FROM debian:9
ENTRYPOINT ["ping"]

$ sudo docker build -t myimage .
$ sudo docker run –rm –name myimage myimage 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=398 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=61 time=67.5 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=61 time=50.9 ms
EXEC形式で書くと、引数を渡すことができる

$ docker container run –entrypoint date myimage
エントリーポイントを上書きできる

### CMD命令とENTRYPOINT命令の組み合わせ

FROM debian:9
CMD ["8.8.8.8"]
ENTRYPOINT ["ping"]

$ sudo docker build -t myimage .
$ sudo docker run –rm –name myimage myimage
これで動く

ENTRYPOINT命令はPID1プロセスのコマンド
CMD命令はコマンドのデフォルト引数を指定できる
–entrypointで上書きできる

これは凄い、1ヶ月くらいやってもまだ理解したとは言い難い
PID1プロセスが大事なのはわかった

[Docker] ShellとExec形式

Shell形式
– 利点: 記述が簡単、シェル変数展開が利用できる
– 欠点: /bin/sh -c を渡して実行するため、イメージに /bin/sh が含まれてなければならない

Exce形式
– 利点: イメージに /bin/sh が必要ないため、イメージサイズと攻撃面を削減できる
– 欠点: 記述が面倒で、シェル変数展開できない

### Shell形式
Dockefile

FROM busybox
ENV COUNT 3
CMD /bin/ping -c $COUNT 8.8.8.8

$ sudo docker build -t test .
$ sudo docker run –rm –name test test

FROM busybox AS source
FROM scratch
COPY --from=source /bin/busybox /bin/pin
ENV COUNT 3
CMD /bin/ping -c $COUNT 8.8.8.8

### Exec形式
Exec形式は、指定のコマンドを直接実行するもの
Shell形式である必要はないが、JSOフォーマットで記述しないといけない

FROM busybox
CMD ["/bin/ping", "-c", "3", "8.8.8.8"]
FROM busybox AS source
FROM scratch
COPY --from=source /bin/busybox /bin/pin
CMD ["/bin/ping", "-c", "3", "8.8.8.8"]

EXECだとシェル変数展開ができないが、/bin/shは必要ないのね
ShellとExec形式の2種類があるってことはわかった。

[Docker] 環境変数を渡す

Dockerfile

FROM ubuntu:latest

ARG hoge
ENV HOGE=${hoge}

$ sudo docker build ./ -t test –build-arg hoge=”abc”
$ sudo docker run -itd –rm –name my_container test:latest
$ sudo docker exec -it my_container /bin/bash
root@1ae829aee3fc:/# echo $HOGE
abc

なるほどー
次はdockerでpostfix

[Docker] CentOS httpdのdocument root変更

FROM centos:centos7
ENV APACHE_DOCUMENT_ROOT /var/www/html/ssl/
RUN yum update -y && yum clean all
RUN yum install -y epel-release
RUN yum -y install install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
RUN yum install -y httpd
RUN yum -y install --enablerepo=remi,remi-php74 php php-devel php-mbstring php-pdo php-xml php-gd php-fpm php-mysqlnd php-opcache php-pecl-zip libzip5
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/sites-available/*.conf
COPY . /var/www/html/
EXPOSE 80 443
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

$ sudo docker build -t mycentos .
$ sudo docker run -dit –name myapp -p 8080:80 mycentos

あれ、うまくいかんな…

[Docker] php:8.0-apacheのdocument root変更

FROM php:8.0-apache
ENV APACHE_DOCUMENT_ROOT /var/www/html/ssl/
COPY . /var/www/html/

RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/sites-available/*.conf

$ sudo docker build -t myapache .
$ sudo docker run -dit –name myapp -p 8080:80 myapache
http://192.168.56.10:8080/api/

ん? これ、CentOSでもいけるのか??

[Docker] CentOSでPHPを動かしたい

Dockerfile

FROM centos:centos7
RUN yum update -y && yum clean all
RUN yum install -y epel-release
RUN yum -y install install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
RUN yum install -y httpd
RUN yum -y install --enablerepo=remi,remi-php74 php php-devel php-mbstring php-pdo php-xml php-gd php-fpm php-mysqlnd php-opcache php-pecl-zip libzip5
COPY . /var/www/html/
EXPOSE 80 443
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

sudo docker build -t mycentos .
sudo docker run -dit –name myapp -p 8080:80 mycentos

なるほど、少し見えてきた
apacheのドキュメントルート変更、環境変数の設定周りをやりたい