5分でできる!超実践Doker入門

8 min読了の目安(約7600字TECH技術記事

はじめに

この記事は駆け出し、伸び悩みエンジニア向けの記事です。
しかも超実践なので、細かい理論とかは説明しません。
(かくいう私もさして理解していないのでね)

  • Dockerの理解を深めたい!
  • 仕組みを知って、商用環境で使いたい!

みたいな人は、お帰りいただくほうが身のためです。
ということで、Dokerで「LAMP環境 + α」を爆速で作ってみましょう。

5分でできるというタイトルですが、5分で読めるわけではありません。
つまり、5分で習得できるということではなく、5分で実行まで持っていけるということです。

なお、コピペで環境作成は可能ですが、コピペして「やったー」は良くないです。
環境が作れただけで、あなたのスキルにはなりません。
その理由は、なぜコピペコードがダメなのかを読んでみてください。

前提

環境

  • macOS Catalina 10.15.7
  • Docker version 19.03.13, build 4484c46
  • docker desktop 2.4.0.0(48506) stable

ちなみに、インストールはしておいてください。
「 docker インストール mac」とかで調べればそれくらいすぐわかるっしょ。

答え

全体像

ディレクトリ構成

.
├── ap
│   ├── Dockerfile
│   ├── httpd
│   │   ├── conf
│   │   │   └── httpd.conf
│   │   └── conf.d
│   │       └── 877-example-ap.conf
│   └── www
│       └── index.php
├── docker-compose.yml
└── lb
    └── nginx.conf

各種ファイル内容

Dockerfile

個人的に入れておきたいものは入れています
単にPHP動かすだけなら、もう少し絞ってもいいかと

ap/Dockerfile
FROM centos:7

RUN yum install -y iproute \
                   net-tools \
                   bind-utils \
                   vim-enhanced \
                   epel-release http://rpms.famillecollet.com/enterprise/remi-release-7.rpm \
                   httpd \
                   mysql \
                   zip \
                   unzip \
 && yum install -y --enablerepo=remi-php72 \
                   php72 \
                   php72-php \
 && ln -s /usr/bin/php72 /usr/bin/php \
 && sed -i -e '/override_install_langs/s/$/,ja_JP.utf8/g' /etc/yum.conf \
 && yum update -y \
 && echo 'LANG="ja_JP.UTF-8"' > /etc/locale.conf

ENV LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja"

RUN rm -f /etc/localtime \
 && ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RUN useradd -u 1000 -m -d /home/mr.877 mr.877 \
 && chmod 755 /home/mr.877 \
 && mkdir -p /home/mr.877/www

EXPOSE 80
CMD /usr/sbin/httpd -D FOREGROUND

LB設定

lb/nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    upstream 877-docker-example.m877778m-example.com {
        server 877-docker-example-ap:80;
    }

    server {
        listen 80;
        server_name localhost;
        location / {
            proxy_pass http://877-docker-example.m877778m-example.com;
        }
    }

    include /etc/nginx/conf.d/*.conf;
}

AP設定(apache)

httpd.conf

ほぼデフォルトなので、読み飛ばしてもOK

ap/httpd/conf/httpd.conf
ServerRoot "/etc/httpd"
Listen 80
Include conf.modules.d/*.conf
User apache
Group apache
ServerAdmin root@localhost
ServerName 877-docker-sample-ap.m877778m-example.com

<Directory />
    AllowOverride none
    Require all denied
</Directory>

DocumentRoot "/var/www/html"
<Directory "/var/www">
    AllowOverride None
    Require all denied
</Directory>
<Directory "/var/www/html">
    AllowOverride None
    Require all denied
</Directory>

<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>

<Files ".ht*">
    Require all denied
</Files>

ErrorLog "logs/error_log"
LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "logs/access_log" combined
</IfModule>

<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>

<Directory "/var/www/cgi-bin">
    Require all denied
</Directory>

<IfModule mime_module>
    TypesConfig /etc/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml
</IfModule>

AddDefaultCharset UTF-8

<IfModule mime_magic_module>
    MIMEMagicFile conf/magic
</IfModule>

EnableSendfile on

IncludeOptional conf.d/*.conf

conf.d/*.conf

Dockerfileで作成したディレクトリ(マウントするところ)にドキュメントルートを変更

ap/httpd/conf.d/877-example-ap.conf
<VirtualHost *:80>
    ServerName 877-docker-sample-ap.m877778m-example.com
    DocumentRoot /home/mr.877/www/
    <Directory "/home/mr.877/www/">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.html index.php
        <LimitExcept GET POST>
            Order deny,allow
            Deny from all
        </LimitExcept>
    </Directory>
</VirtualHost>

docker-compose.yml

version: '3.8'

services:
  #
  # LB container(Nginx)
  #
  877-docker-example-lb:
    image: nginx
    container_name: 877-docker-example-lb
    ports:
      - "10080:80"
    volumes:
      - ./lb/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - 877-docker-example-ap

  #
  # AP container(apache)
  #
  877-docker-example-ap:
    build:
      context: .
      dockerfile: ./ap/Dockerfile
    container_name: 877-docker-example-ap
    volumes:
      - ./ap/httpd/conf/httpd.conf:/etc/httpd/conf/httpd.conf
      - ./ap/httpd/conf.d/877-example-ap.conf:/etc/httpd/conf.d/877-example-ap.conf
      - ./ap/www:/home/mr.877/www
    depends_on:
      - 877-docker-example-db

  #
  # DataBase container(MariaDB)
  #
  877-docker-example-db:
    image: mariadb
    container_name: 877-docker-example-db
    environment:
      MYSQL_ROOT_PASSWORD: 877877877
    ports:
      - "13306:3306"

コマンド実行で、はいできました〜〜

起動(docker-compose up)

バックグラウンドでコンテナの起動を行います
問題なく起動できれば、「どん!ど !!どん!!!」ってなるはずです

$ docker-compose up -d
Creating 877-docker-example-db ... done
Creating 877-docker-example-ap ... done
Creating 877-docker-example-lb ... done

確認(docker-compose ps)

$ docker-compose ps
         Name                       Command               State            Ports
-----------------------------------------------------------------------------------------
877-docker-example-ap   /bin/sh -c /usr/sbin/httpd ...   Up      80/tcp
877-docker-example-db   docker-entrypoint.sh mysqld      Up      0.0.0.0:13306->3306/tcp
877-docker-example-lb   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:10080->80/tcp

めちゃくちゃ雑に解説

まずDockerって何?

説明すると長くなる(はず、知らんけど)ので、ここでは3点のみ押さえておけばとりあえずOKです。

  • コンテナ技術のデファクトスタンダード
  • VM(仮想マシン)とことなり、ゲストOSを必要としない
  • 特定のアプリケーションを実行する環境を提供するもの

ついでと言ってはなんですが、これも覚えておきましょう。

1つのコンテナにつき、サービスは1つまで

複数サービスの起動も、やろうと思えばできると思いますが、このルールを守って環境を作っておいたほうがいいと思います。

DockerFileって何!?

イメージの定義ファイルです。

いやいやいや、それDockerHubからpullしてくればいいじゃない。
うん、そうだよ。

うん、そうだよ??

でも実際は、動作環境とぴったり合うとは限りません。
なので、自分の会社のいつもの設定みたいなのを定義しておきたいなーというときに使います。

docker-compose.ymlってなんなんだよぉぉぉぉ!!!

複数コンテナを一元管理するための設定ファイルです。
そうですか。
そうです。

システムというのは、APがあって、DBがあって、あれがあって、これがあって...
というのが普通です。
「マイクロサービス化してますから!!」と言っても、連携先は必ず存在するので、それを一元管理したほうがいいですよね。
そういうとき、docker-composeで管理できると楽です。

ちなみに、私はdocker-compose.ymlをプロジェクト内に含めないようにしています。
ポート番号変えたいとか、DBは自分が持ってるコンテナでやりたいとかそれぞれ要望があると思うので、サンプルファイルとして含め、READMEなどで使い方を補完するようにしています。

GithHubにアップしておきました。

m877778m/877-samples-for-blogにサンプルを転がしておきます。
(いろいろなサンプルをここに転がしていきたいが、できるんだろうか...)

最後に

TL;DR書かなかったことに感動。
ってかこういう記事では書けねぇか!!