Docker環境構築

🐳概要

✅特徴

  • コンテナ型の仮想環境を作成、配布、実行するためのプラットフォーム
  • Linux、Windows、Macどれでも動く
  • Dockerがインストールされていれば、どのマシンでも同じように動作する
  • 「ビルド1回、どこでも動かす」
  • 開発環境、テスト環境、本番環境どこでもシームレスに動かせる
  • 仮想マシンと違い軽量
  • Docker Hubというサービスから、様々なソフトウェアのDockerイメージをダウンロードして使うことができる

✅イメージ

用語

  • イメージ
    実行可能なDockerコンテナの設定や依存関係を含むテンプレート。イメージはベースとなるOSやソフトウェアがプレインストールされた状態で、これを基にコンテナが作成されます。
  • コンテナ
    Dockerイメージから実行されるインスタンス。各コンテナは独立した環境を提供し、それぞれのアプリケーションやサービスが動作します。

✅参考サイト

🐳インストール

Windows

  • WSL2のインストールが必須となる
  • Windows 10 Home 向けがあるらしいが、最近はないっぽい?

Mac

🐳使い方

✅コマンドについて

  • Docker v1.13以降から新コマンドが推奨されるようになった
    ⚠ネットで調べると古いコマンドも出てくるので注意
    docker run → docker container run
  • ライフサイクルに沿ったコマンド一覧
    • 作成:docker image build -t sample/webrick:latest .
    • 起動:docker container run -d -p 8000:8000 –name webrick samole/webrick:latest
    • 停止:docker container stop webrick
    • 削除:docker container rm webrick
  • 起動中に使うコマンド
    • ログ:docker container logs webrick
    • 一覧:docker container ls -a
    • コマンド実行:docker container exec webrick ruby -v
  • 大掃除(コンテナ停止しているもの全部削除)
    • docker system prune -a

✅その他併用して使うDocker以外のコマンド💡超重要💡

  • code .:カレントフォルダをVSCodeで開く(VSCodeのCLI)
  • \\wsl.localhost\:エクスプローラで仮想マシン内にアクセスできる。
  • sudo rm -r -I <folderName>:実験失敗したときの残骸を削除するときにどうぞ。

🐳チュートリアル1(デモの実行)

Docker超入門講座 合併版 | ゼロから実践する4時間のフルコース(アプリを作成・実行しよう)

  • 動作の確認を兼ねてデモを実行してみよう!
  • webrickというRuby標準のWebサービスを使ったデモです
  • 環境構築用にsample1フォルダを作成してファイルを配置します

フォルダ構成とファイルの作成

sample1フォルダを作成して、2つのファイルを作成していきます。

/home/yuichi/docker
└── sample1
    ├── Dockerfile
    └── main.rb

アプリケーションコードの作成(main.rb)

require 'webrick'

server = WEBrick::HTTPServer.new(
    DocumentRoot: './',
    BindAddres: '0.0.0.0',
    Port: 8000
)

server.mount_proc('/') do |req, res|
    res.body = "hello ruby"
end

server.start

Dockerfileを作る(Dockerfile)

FROM ruby:2.7

RUN mkdir /var/www
COPY main.rb /var/www

CMD ["ruby", "/var/www/main.rb"]

イメージの作成と確認

イメージの作成

docker image build -t sample/webrick:latest .

イメージが作成されたかの確認

docker image ls
docker image ls -a

-a:停止中のものも含めて表示

コンテナの作成と起動

コンテナの起動

  • 今回はこちらのパターンで起動(コンソール占拠)
docker container run -p 8000:8000 --name webrick sample/webrick:latest
  • バックグラウンド(デーモン)で実行する場合は-dを追加
docker container run -d -p 8000:8000 --name webrick sample/webrick:latest

確認

  • ブラウザでlocalhost:8000にアクセスしてみる

停止と削除

停止

  • バックグラウンドで実行していないため、Ctrl+Cで停止させる

削除

  • 下記のコマンドで削除
docker container rm webrick
  • 削除されたかの確認
docker image ls -a
  • イメージやキャッシュなどの削除
docker system prune -a

🐳チュートリアル2(ライフサイクルを体験)

Docker超入門講座 合併版 | ゼロから実践する4時間のフルコース(Dockerfileを作ろう)

Dockerfileを自分で作ってみよう。Rubyの開発環境を想定してDockerfileの作成、imageの作成、コンテナの作成と実行までを操作してみる。

Dockerfileにはアプリの設計書を記述する。アプリコード+ライブラリ+ベースイメージ

チュートリアル1ではwebrickというRuby標準の機能を使ったため、ライブラリは使用していなかった。今回はsinatraというRubyのライブラリを使用する。

ちなみにRuby未経験であったためよくわからない部分が多数あった。Rubyにおけるgemという概念や、Bundler(bundle)という依存関係管理ツールなど。

フォルダ構成とファイルの作成

/home/yuichi/docker/sample02
├── Dockerfile
└── src
    ├── Gemfile
    └── app.rb(起動後に作成)

Rubyのライブラリ設定ファイルを作る(Gemfile)

RubyではライブラリのことをGemと読んでいます。設定ファイルにはインストールしたいライブラリを記述します。Bundlerというツールが設定ファイルを読み込みインストールを行います。

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "sinatra"

初期のDockerfileを作る(Dockerfile)

FROM ruby:2.7

WORKDIR /var/www

COPY ./src /var/www

CMD ["/bin/bash"]

イメージの作成

docker image build -t sample/sinatra:latest .

コンテナの作成と起動

コンテナの起動

docker container run -it -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest
  • -it:インタラクティブモード
  • -v:ローカルとコンテナのフォルダを同期
  • ${PWD}:シェル環境変数で、現在、作業しているディレクトリのフルパスを表す

起動の確認

Dockerfileの最後でコンテナ内のシェルが起動するように設定したので、コンソールがコンテナ内に変わっているはず。

root@IN-WIN-A1-Prime:~/docker/sample2# 
↓
root@da3f8259d0ce:/var/www#

同期設定の確認

-vオプションが効いているか確認してみよう。

  • コンテナ内でファイル内容を表示:cat Gemfile
  • ローカルでファイルを修正
    エクスプローラで下記のフォルダにアクセス
    \wsl.localhost\Ubuntu\root\docker\sample2\src
    VSCodeでGemfileに何か変更を加える
  • コンテナ内でファイル内容を表示:cat Gemfile
  • 変更が反映されていることを確認

開発

インタラクティブモードで色々実験しながら開発を進める

ライブラリのインストール(Ruby)

bundleを使うと、先ほど作成したGemfileを参照して、ライブラリがインストールされる。

bundle config --local set path 'vendor/bundle'
bundle install

サンプルアプリケーションコードの作成

srcフォルダ内にアプリケーションコード(app.rb)を作成する。

ローカルのsrcフォルダ内にapp.rbを(VSCodeを使って)作成すると、同期されてサーバーのsrcにも作成される。

require 'sinatra'

configure do
    set :bind, '0.0.0.0'
end

get '/' do
    'Hello world!'
end

アプリケーションの実行

bundle exec ruby app.rb
  • ruby app.rbではない理由
    先程インストールしたgemの上で実行したいからっぽい?
  • 確認:ブラウザでlocalhost:4567にアクセスしてみる
  • Hello world!が表示されればOK

アプリケーションの停止とコンテナの削除

  • バックグラウンドで実行していないため、Ctrl+Cで停止させる
  • コンテナを削除する
docker container rm sinatra

実験したことをDockerfileに反映させていく

実験用にCMD ["/bin/bash"]としていた部分を実験結果に書き換える

FROM ruby:2.7

WORKDIR /var/www

COPY ./src /var/www

RUN bundle config --local set path 'vendor/bundle'
RUN bundle install

CMD ["bundle", "exec", "ruby", "app.rb"]

⚠RUNとCMDの違い

  • RUN:Dockerイメージがビルドされる際に1度だけ実行される
  • CMD:Dockerコンテナが起動されるときに実行される。1つしか記述できない

再実行

  • 再度イメージを作成
docker image build -t sample/sinatra:latest .
  • 再度コンテナを起動(今回はインタラクティブモードで実験するわけではないのでitオプションはない)
docker container run -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest
  • 確認:ブラウザでlocalhost:4567にアクセスしてみる
  • コンソールに上記のアクセスしたログが表示されればOK

停止と削除

停止

  • バックグラウンドで実行していないため、Ctrl+Cで停止させる

削除

docker system prune -a
  • または、個別に
    • コンテナを削除する:docker container rm sinatra
    • イメージを削除する:docker image rm sample/sinatra:latest

🐳チュートリアル3(Railsを例に環境を構築しよう)

Docker超入門講座 合併版 | ゼロから実践する4時間のフルコース(Docker ComposeでRailsを構築しよう)

Docker Composeを使うことによって複数のアプリケーションをまとめて操作。

いままでこんかい
イメージの作成docker image builddocker-compose build
コンテナの作成と起動docker container rundocker-compose up
コンテナの停止docker container stopdocker-compose down
コンテナの削除docker container rm
コンテナ作成とコマンド実行docker-compose run
起動中コンテナでコマンド実行docker-compose exec

フォルダ構成とファイルの作成

/home/yuichi/docker/sample3
├── Dockerfile
├── docker-compose.yml
└── src
    └── Gemfile

Dockerfileを作る

  • nodejsとyarnのインストール
  • 作業ディレクトリの指定
  • ソースのコピー
  • Rubyライブラリのインストール

⚠動画での提示ソース(エラーが発生して動かない)

WSL2+Ubuntuの影響により、下記の方法だとUbuntuに入っているNode.jsのv12.22.12がインストールされてしまい、v14.0.0以上をインストールしなさいとの指示が出てしまう。

FROM ruby:2.7
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update -qq \
    && apt-get install -y nodejs yarn
WORKDIR /app
COPY ./src /app
RUN bundle config --local set path 'vendor/bundle' \
    && bundle install

⚠修正版(node.jsのバージョンを指定してインストール)

ChatGPTに相談しながら修正版を作ってみた。

FROM ruby:2.7

# Node.jsとYarnのインストール
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
    && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update -qq \
    && apt-get install -y nodejs yarn

WORKDIR /app
COPY ./src /app

RUN bundle config --local set path 'vendor/bundle' \
    && bundle install

Rubyのライブラリ設定ファイルを作る(Gemfile)

source 'http://rubygems.org'

gem 'rails', '~> 6.1.0'

Docker Composeの設定ファイルの記述(docker-compose.yml)

  • yaml形式:詳しくは yamlファイルの構造
  • これによってdbとwebのコンテナを一気に起動することができる
  • 自分の環境では下記のymlファイルだとエラーが出てしまった。該当箇所はdbのvolumes。パーミッション関連のエラーが出た。これはWSL2における権限設定の問題だった。Ubuntuのデフォルトユーザーをrootにすることによって解決。詳しくは DockerでWSL2を使った場合の権限問題
version : '3'
services:
  db:
    image: mysql:8.0

    # 認証形式に関する設定(8.0から認証形式が変更されている)
    command: --default-authentication-plugin=mysql_native_password

    # コンテナを削除してもDBのデータが残るようにローカルと同期させる
    volumes:
      - ./src/db/mysql_data:/var/lib/mysql

    environment:
      MYSQL_ROOT_PASSWORD: password
  web:
    #カレントディレクトリのDockerfileを使用する
    build: .

    # Railsサーバーを起動
    command: bundle exec rails s -p 3000 -b '0.0.0.0'

    # 同期
    volumes:
      - ./src:/app

    # ポートの接続
    ports:
      - "3000:3000"

    # 連携設定
    depends_on:
      - db

初期設定

Railsの雛形を作る

rails new . --force --database=mysqlを実行する。

docker-compose run web rails new . --force --database=mysql
  • rails newすることにより必要ファイルがインストールされる
  • また、Gemfileに必要項目が追記される

再度、ビルドし直す

GemfileやDockerfileに変更があった場合は、イメージをビルドし直す

docker-compose build

設定ファイルの編集

src/config/database.yml のデータベースのパスワードとホストを変更する。

  password:
  host: localhost

  ↓

  password: password
  host: db

再度、ビルドし直す

 docker-compose build

データベースを作る

rails db:createを実行してデータベースを作る

 docker-compose run web rails db:create

起動と追加の操作

バックグラウンド(-d)で起動

docker-compose up -d

ログの表示

docker-compose logs

停止

docker-compose down

コンテナ内で操作したい場合

docker-compose exec web /bin/bash

DockerfileやJemfileを修正して反映したい場合

docker-compose build
docker-compose up -d

🐳本番環境でDockerコンテナを公開しよう

ここはどうしよう。mixhostではできないからとばすか?

🐳【本命】Laravel環境をDockerで構築しよう

下記の2記事を参考にやってみた。

しかし、現在と記事が書かれた時期の違いによりエラーが多発?1つ目はstorageフォルダのパーミッションの問題。2つ目はHelloWorldしようとしたときに遭遇したroutes/web.phpへの記述方法の違い(Laravel7までと、Laravel8以降の違い)であった。

ちなみに下記の方法は、動作したが、内容の解釈ができなかったので、やめることにした。

フォルダ構成とファイルの作成

.
|-- docker
|   |-- db(起動後に作成)
|   |-- nginx
|   |   `-- default.conf
|   `-- php
|       |-- Dockerfile
|       `-- php.ini
|-- docker-compose.yml
`-- laravel-project(起動後に作成)

php.iniを作る

docker/php/php.ini

[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
[opcache]
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1

Dockerfileを作る

docker/php/Dockerfile

FROM php:8.0-fpm
COPY php.ini /usr/local/etc/php/

RUN apt-get update \
  && apt-get install -y zlib1g-dev mariadb-client vim libzip-dev \
  && docker-php-ext-install zip pdo_mysql

#Composer install
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer

ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin

WORKDIR /var/www

RUN composer global require "laravel/installer"

default.confを作る

docker/nginx/default.conf

server {
  listen 80;
  root /var/www/laravel-project/public;
  index index.php;
  location / {
    root /var/www/laravel-project/public;
    index index.php;
    try_files $uri $uri/ /index.php$query_string;
  }
  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass app:9000; 
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

コンテナの作成と起動

docker-compose up -d

確認

docker-compose ps

Laravelプロジェクトの作成

コンテナの中に入る

docker-compose exec app bash

プロジェクトの作成

ここでお手本のHPではプロジェクトのバージョンが6.*を指定していたので、mixhostに合わせて8.*にすることにした。

composer create-project --prefer-dist laravel/laravel laravel-project "8.*"

/var/www以下にプロジェクトファイルが作成される。

プロジェクトの作成は下記のようにもできるらしいが、バージョンとかどうなるのか?未確認。

laravel new laravel-project

パーミッションの変更

larabel-project/storageフォルダ以下の権限を変える。これをしないと以降の操作をしたときにLaravelのエラーが出てしまう。

chmod -R 777 storage

-R:内包するフォルダーを再帰的に同様のパーミッション設定にする

確認

ブラウザでlocalhost:8000にアクセスし、Laravelの初期画面が表示されればOK

開発

ここからは

を参考にした。

テスト用のHelloディレクトリを実装する。

web.php の編集

routes/web.php

最後にRoute::get('hello', 'App\Http\Controllers\HelloController@index');を追加

<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::get('hello', 'App\Http\Controllers\HelloController@index');

コントローラーの作成(雛形)

php artisan make:controller HelloController

HelloController.php の編集

作成された、app/Http/Controllers/HelloController.phpを編集する。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    public function index()
    {
      // 配列の初期化
      $data = array();

      // データ格納
      $data['name'] = 'ななしさん';
      $data['message'] = 'こんにちは';

      // 現在日時
      date_default_timezone_set('Asia/Tokyo');
      $data['today'] = date('Y年m月d日 H:i:s');

      return view('hello', $data);
    }
}

hello.blade.php の作成

resources/views/下にhello.blade.phpを作成。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Hello!!!</title>
</head>
<body>
  <h1>Hello!!!</h1>
  <p>{{$name}}さん</p>
  <p>{{$message}}</p>
  <p>現在は {{$today}} です</p>
  <p>やったね!</p>
</body>
</html>

確認

ブラウザでlocalhost:8000/helloにアクセスし、設定した内容が表示されればOK!

コメントする