K.Takahashiをフォローする

Dockerのはじめ方|新しいMac(M1)で仮想環境をつくる

開発環境・ツール

数ヶ月前に開発のメインマシンをWindowsからMacに変えたのですが、ここで一つ問題が…

CPUがM1(Apple Chip)につき、今まで使い慣れたVagrantが使えなかったのです。

どうしてもMacを使いたかったApple信者の私は、仕方なくDockerの勉強をはじめたのですが、使っていくうちに「Docker便利!!!」と感激しました。

今回はこれからDockerを使ってみたいという方向けに、Dockerの良さや具体的な使い方をご説明します。

(もちろん、Windowsマシンをお使いの方も同じように作れると思います。)

Dockerの良かったところ

まず、Vagrantと比べて、Dockerの「ここが良い!」と思ったポイントをご紹介します。

サクッと起動する

元々使っていたWindowsマシン(Windows10 Pro/Core i7)と速度比較してみたところ以下のような結果になりました。

Vagrant(Windows)Docker(Mac)
約62秒約15秒

マシンが違うので正確ではないかもしれませんが、なんと4分の1になりました。
毎日使うものなので、この時間短縮はけっこう嬉しいです。

複数の環境の切り分けが簡単

Vagrantで複数のプロジェクトの開発をしようとしたときに、開発環境が異なると結構困ります。

プロジェクトAプロジェクトB
PHP7.4、Node.js、MySQLPHP5.7、PostgreSQL

このような場合、1つの仮想マシン内で分けようとするとなかなか面倒なので、別の仮想マシンをつくると思うのですが、ここで1つ問題が…

仮想マシンが増えるほどにディスク容量がどんどん侵食されていくのです。

Dockerの場合は、後ほどご説明しますが、docker-compose.ymlやDockerfileを分けるだけで簡単に管理できますし、Vagrantよりも消費するディスク容量がかなり少ないです。

「サクッと起動する」でご説明したとおり起動も速いので、環境の切り替えもスムーズに行なえます。

仮想環境が壊れても短時間で直せる

Vagrantを使っていると、時々、原因不明のエラーで起動しなくなることがありました。

新しく仮想環境を作り直すのに30分ほどかかっていたのですが、Dockerだと数回のコマンドで済むので修復も簡単です。

(未だにDockerの仮想環境が使えなくなったことはありませんが)

Dockerの使い方

それでは早速、本題のDockerの使い方に移っていきましょう。

今回はDockerを使って仮想環境をつくり、Laravelのプロジェクトを表示するところまでご紹介します。

よりDockerを使った開発がイメージしやすいように、

  1. インストール]
  2. 設定ファイルの準備
  3. ビルド
  4. Laravelのプロジェクトを表示してみる

の順番でご説明していきます。

インストール

Dockerのインストール方法は、大まかに2種類あります。

Mac / Windowsに直接インストールする

これは説明するまでもありませんが、Dockerの公式サイトからお使いのマシンに直接インストールする方法です。

私のようにM1のMacをご利用の方はこちらの方法でインストールしましょう。

Windowsをお使いの方で、既にVirtualBoxやVagrantをインストールしている場合は、競合を起こす可能性があるので、②の方法をおすすめします。

仮想マシン上にインストールする

Vagrant(WSLでもOK)で仮想マシンをつくって、そこにDockerをインストールする方法です。

簡単にインストール方法をご説明しますと、
①VagrantでCentOSやUbuntuなどの環境を用意する
②ターミナル等でいくつかコマンドを打ってインストールする
という流れになります。

詳しくはDockerの公式ページをご覧ください。

設定ファイル(docker-compose.ymlやDockerfileなど)の準備

見出しにあるdocker-compose.ymlやDockerfileについてざっくり説明しますと、
docker-compose.yml:使用するイメージ(mysql/postgres/nodejsなどなど)やポート番号などを記載する
Dockerfile:仮想環境を作成(ビルド)する際に実行するコマンドを記載する
というイメージです。

私自身、まだ勉強中なので、もっと詳しく知りたい方は公式リファレンスをご覧ください。

仮想環境の構成

今回は汎用的に使えそうな以下の構成にしようと思います。
※バージョンは変わるかもしれないのでご了承ください。

  • Apache:2.4
  • PHP:7.4
  • mySQL:8.0
  • redis:6.2.1
  • composer:1.10.21(2.x.xにLaravelが対応していないため)
  • nodejs:14.16.1
  • yarn:1.22.10

本番環境に合わせて、https://~~~~~で表示されるようにします。

フォルダ構成

設定ファイル(フォルダ?)の構成は、以下のようにします。
※プラスマークの付いている箱がフォルダ、それ以外はファイル。

ファイルの中身

.env

「docker-compose.yml」で使用する変数を定義します。
※ポートは適宜変更してください。

WEB_PORT=8080
DB_PORT=3306
AD_PORT=6080

docker-compose.yml

プロジェクトのフォルダやファイルを追加したら、「laravel-app.local」と書かれているところに適宜ドメインを追加してください。

version: "3"

networks:
  lampnet:
    driver: bridge

services:
  web:
    build: ./docker/web/
    logging:
      driver: json-file
    networks:
      - lampnet
    ports:
      - "${WEB_PORT:-8080}:80"
    volumes:
      # DocumentRoot
      - ./www/:/var/www/
      # 設定ファイル
      - ./docker/web/conf/000-default.conf:/etc/apache2/sites-available/000-default.conf
      - ./docker/web/conf/php.ini:/usr/local/etc/php/conf.d/php.ini
    environment:
      # MySQL接続設定
      MYSQL_HOST: db
      MYSQL_PORT: 3306
      MYSQL_USER: root
      MYSQL_PASSWORD: root
      # TimeZone設定
      TZ: Asia/Tokyo
      # VirtualHost
      VIRTUAL_HOST: laravel-app.local
      VIRTUAL_PORT: 82
      CERT_NAME: default # ローカル環境用SSL証明書

  db:
    image: mysql@sha256:2878ca7ca986b54c948966b7103aeceb747f50b9ecf34ecf934036cca58274db
    logging:
      driver: json-file
    ports:
      - "${DB_PORT:-3306}:3306"
    networks:
      - lampnet
    volumes:
      # データの永続化
      - ./docker/db/mysql:/var/lib/mysql
      # MySQLの設定ファイル
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf:ro
      # ダンプデータのマウント用
      - ./docker/db/dump/:/var/dump/
      # 初期データのマウント用
      - ./docker/db/initdb.d/:/docker-entrypoint-initdb.d/
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      # TimeZone設定
      TZ: Asia/Tokyo

  redis:
    image: redis:latest
    logging:
      driver: json-file
    networks:
      - lampnet

  proxy:
    image: steveltn/https-portal:1
    logging:
      driver: json-file
    networks:
      - lampnet
    ports:
      - '82:80'
      - '443:443'
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock/:ro
    environment:
      STAGE: local
      DOMAINS: 'laravel-app.local -> http://web:80'

/docker/web/conf/000-default.conf

Apacheのバーチャルホストの設定ファイルです。

# laravel-appの設定
<VirtualHost *:80>
    ServerName adminer.local
    DocumentRoot /var/www/laravel-app/public/

    <Directory /var/www/laravel-app/public/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

/docker/web/conf/php.ini

[Date]
date.timezone = "Asia/Tokyo"

[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

/docker/web/Dockerfile

PHPの拡張モジュールをインストールしたい場合は、こちらに適宜追加してください。

FROM php:7.4-apache

# composerのインストール
COPY --from=composer:1 /usr/bin/composer /usr/bin/composer
ENV PATH $PATH:~/.composer/vendor/bin

RUN apt-get update && \
    apt-get install -y vim zip unzip && \
    apt-get install -y libpq-dev libonig-dev libxml2-dev && \
    docker-php-ext-install pdo_mysql mysqli xml && \
    a2enmod rewrite

# nodejs,yarnのインストール
RUN apt-get update && \
    # nodejs,npmをインストール
    apt-get install -y nodejs npm &&\
    # n,yarnをインストール
    npm install --global n yarn &&\
    # nodejs,npmを安定版の最新にして、古いnodejs,npmを削除
    n stable &&\
    apt-get purge -y nodejs npm

WORKDIR /var/www/

/docker/db/my.cnf

MySQLの設定ファイルです。

[mysqld]
character-set-server = 'utf8mb4'

[client]
default-character-set = 'utf8mb4'

ビルド

各種設定ファイルの準備が終わったら、ターミナル等でコマンドを打ってビルドします。

# 設定ファイルの親フォルダに移動
$ cd {設定ファイルの親フォルダ}

# ビルド
$ docker-compose build

# バックグラウンドで起動
$ docker-compose up -d

# ビルド後にDockerfileを編集した場合は、こちらで起動します
$ docker-compose up -d --build

私のように「docker-compose ~」と毎回打つのが面倒な方は、aliasに登録しておくと楽ちんです。

de='docker-compose exec'
ds='docker-compose stop'
dup='docker-compose up'
dupb='docker-compose up -d --build'
dupd='docker-compose up -d'

Laravelのプロジェクトを表示してみる

まずローカルのhostsにドメインを登録しておきます。

$ sudo -i
$ vi /etc/hosts

# hostsには、このように書く
127.0.0.1 laravel-app.local
※Vagrant上にインストールした場合は、「127.0.0.1」の部分をVagrantの設定に合わせます。

あとは、Laravel側の初期設定をして、https://laravel-app.localにアクセスするとLaravelの初期画面が表示されます。

MacのGoogleChromeを使用していると、「この接続ではプライバシーが保護されません」が出るので、その場合は下記の記事を参考にして証明書をキーチェーンに登録してください。

Mac Chromeでプライバシーブロックされ「詳細設定」からもページが表示できない 

Mac Chromeでプライバシーブロックされ「詳細設定」からもページが表示できない - Qiita
〜宣伝〜個人開発でエンジニア専門マッチングサービスを開発しましたので、是非未経験からエンジニア目指している人!現役エンジニアで教えたい人!使ってみてください!β版リリース記念キャンペーン中です!10名様限定、抽選でお好きな技術本1冊プレゼン...

おまけ

仮想環境にSSH接続(ログイン)したいときは下記のようなコマンドを使います。

# WEB
docker-compose exec web bash

# DB
docker-compose exec db bash

# Laravelでマイグレーションとかするとき
docker-compose exec web php {arisanファイルの絶対パス:/var/www/laravel-app/artisan} migrate 

また、Laravelの.envでHOSTを指定するときは、下記のように記載しましょう。

DB_CONNECTION=mysql
DB_HOST=db #docker-compose.ymlで指定したサービス名
DB_PORT=3306 #同じく指定したポート番号
DB_DATABASE=laravel-app
DB_USERNAME=root
DB_PASSWORD=root

まとめ

私自身、もともとは「Dockerを使わなくてもVagrantでよくね?」と考えていましたが、使ってみるとかなり便利ですし、実際のプロジェクトでも仮想環境でDockerを指定される場合が多いです。

ぜひ今のうちから慣れておきましょう。