docker を使ってみる

 docker は container を管理するプラットフォームです。

< 概要 >
 container は仮想化の一形態と言われますが、一般的な仮想マシン ( 以下 virtual machine ) と対比するとわかりやすいです。virtual machine は物理マシンを制御するOSの上にさらに仮想空間ごとにOSが存在するため、異なるOSの環境を構築できる反面、多くのリソースを消費します。一方 docker に代表されるコンテナ型は物理マシンを制御するOSを利用して独立したコンテナ空間を作成しますので linux の環境でのみ動作する代わりに消費するリソースが少なくて済みます。利用するといっても container にはホストOSとは異なるOS ( ディストリビューション ) を指定することもできます。

< 流れ >
 container は image から作られます。つまり、必要な環境が整った image を予め作成し、その image から container を起動することで container を起動する仕組みになっています。
 image は Linux 上に必要な機能をインストールした状態で保存しておきます。

< 目的 >
 docker を使って nginx , ruby ( sinatra ) , mysql を使った web アプリケーション の image を作成し image を作成したPCとは別の Linux で container として実行します。

< 構築 >
 docker のインストールをしてみます。docker docs ( 公式ホームページ ) から環境に合わせて選択します。インストールが完了したらターミナルを起動し、次のコマンドを入力しインストールの完了を確認します。

( 入力 )
% docker -v

( 出力 )
Docker version 24.0.6, build xxxxxxx

 docker -v で docker のバージョンが表示されます。バージョンが表示されればインストール完了とできます。では、早速 container を使ってみます。次のコマンドを入力します。

( 入力 )
% docker run ubuntu:24.04 echo hello world

( 出力 )
Unable to find image 'ubuntu:22.04' locally
24.04: Pulling from library/ubuntu
.....
hello world

( 入力 )
% docker container run ubuntu:24.04 echo hello world

( 出力 )
hello world

 docker run は image を container 化するコマンドです。ここでは image として ubuntu のバージョン 24.04 を指定し、合わせて echo hello world コマンドを実行しています。( 出力 ) にある通りですが、ローカル環境に該当の image が存在しなければ docker hub ( 公式ページ ) に登録されているものは自動でダウンロードしてくれます。
 一度ダウンロードが完了すればローカルに保存されますので、次からはダウンロードは無くなります。ローカルに存在する image は docker image ls コマンドで確認できます。クラスとインスタンスのような関係です。

( 入力 )
% docker image ls

( 出力 )
REPOSITORY   TAG          IMAGE ID       CREATED       SIZE
ubuntu       24.04        e343402cadef   8 weeks ago   69.2MB

( 入力 )
% docker run -it e343 bash

( 出力 )
root@〜:/# 

 container を interactive mode ( 対話モード : -it ) で起動すれば container にログインし bash を起動できます。なお、ローカルに image があれば imageID を指定して起動することもできます。

 docker image をダウンロード使用する方法は上記の通りですが、もちろん image を作成することもできます。
 docker image の作成方法は2つあります。1つは docker run コマンドで起動した container に環境構築してその環境を image として保存する方法。もう一つは Dockerfile に環境構築の手順をスクリプトとして記述しておき docker build コマンドで docker image を作成する方法です。一般的には Dockerfile に手順を記述しておく方法がよく使われます。
 ここではより一般的に使用される Dockerfile へ記述する方法で構築してみます。スクリプトに従って build する方法は、手順が明確になります。インフラの構築をコードで行うとも言えます。

 では $HOME に作業ディレクトリを作成し、その中に Dockerfile を作成します。

( 入力 )
% cd
% mkdir works && cd works
% vi Dockerfile
FROM ubuntu:24.04

 Dockerfile を保存したら image を build してみましょう。

% docker build -t test:001 . 

 -t オプションは作成した image の名称を設定する時につけるものです。文末の . ( period ) は Dockerfile や他に必要なファイルの場所の場所がカレントディレクトリであることを示します。build された docker image を確認します。次のコマンドを入力してください。

( 入力 )
% docker image ls

( 出力 )
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
test         001       86e3117c7720   7 days ago   93.6MB
ubuntu       24.04     b62afbf00f1f   7 days ago   93.6MB

 IMAGE ID などは異なると思いますが、同じような結果になったと思います。次に作成した docker image を container 化してみます。次のコマンドを入力してください。

% docker run -it -v $PWD:/opt/works -w /opt/works test:001 bash

 コマンドの内容を簡単に説明すると -v はボリューム機能を使用し、カレントディレクトリを container の /opt/works にマウント ( 共有 ) します。 共有することで container が停止した後でもファイルを保持できます。-w はワークディレクトリの指定します。これで docker image の作成から container化までの一連の流れができました。次は Dockerfile に内容を追記していきます。

 次の内容の Gemfile の内容を次のように変更してください。

source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "sinatra", "2.2.0"
gem "mysql2", "0.5.2"

 また Dockerfile も次のように変更してください。

FROM ubuntu:24.04
RUN apt update
RUN apt install -y ruby ruby-bundler
COPY Gemfile .
RUN apt install -y ruby-dev build-essential libmariadb-dev
RUN bundle install

 実行する sinatra のコードも次のように変更してください。

require 'sinatra'
require 'mysql2'

get '/' do
  'Hello world!'
end

get '/api/hello' do
  {
    message: 'Hello world!'
  }.to_json
end

get '/api/tasks' do
  client = connect

  result_set = client.query('select id, title, created_at from tasks')
  tasks = result_set.map do |row|
    {
      id: row['id'],
      title: row['title'],
      createdAt: row['created_at']
    }
  end

  client.close

  {
    tasks: tasks
  }.to_json
end

post '/api/tasks' do
  request_body = JSON.parse request.body.read

  title = request_body['title']

  client = connect

  statement = client.prepare('INSERT INTO tasks (title) values (?)')
  statement.execute(title)

  client.close
end

def connect
  Mysql2::Client.new(
    :host => "localhost",
    :database => "mydb",
    :username => "myuser",
    :password => "password",
    :connect_timeout => 5
  )
end

 このあと docker run -it -v $PWD:/opt/works -w /opt/works test2:test2 bash
 を実行し、ruby app.rb を実行すると起動します。これで アプリの container は終了です。

. It specifies the location of the Dockerfile and any other files needed for the build process. In this case, . represents the current directory,Dockerfile のあるディレクトリでdocker ps , docker ps -a で起動している docker の一覧を表示できる

ボリュームを使うことで、ホストとコンテナでファイルを共有できます。
ボリュームに保存したデータは、コンテナを削除してもホストに残ります

docker run -it -v $PWD:/opt/myapp -w /opt/myapp my-ruby:dockerfile bash
これは -v option によって $PWD ( カレントディレクトリを示す変数 ) を container の /opt/myapp にマウントすることを表し -w option によって container のワークディレクトリを /opt/myapp に設定しています。

 まず ubuntu:24.04 をベースOSとしたコンテナを起動します。

% docker run -it ubuntu:24.04 bash

 docker が起動したら ruby と ruby-bundler をインストールします。

% apt update
% apt install -y ruby ruby-bundler

 ruby のバージョンが表示されたら完了です。

docker での開発は
 1.ベースとなる公式イメージを取得する。
 2.取得したイメージからコンテナを起動する。
 3.起動したコンテナで環境を構築する。
 4.構築した環境をイメージ化する。
 5.作成したイメージを実行したい環境にデプロイする。
 6.デプロイしたイメージを元に実行したい環境下でコンテナ化する。
 といった流れで使用します。

 ここでは docker を使って nginx , ruby ( sinatra ) , mysql を使った web アプリケーション のイメージを作成し、開発環境とは別の Linuxマシン で実行してみます。

 当然ですが docker container を起動するコンピュータ ( 本番環境等 ) には dockerd が稼働している必要があります。( 開発環境にも docker のインストールは必要です )

 docker では1つのコンテナに1つの機能を持たせるのが一般的ですので、ここでも nginx の機能を持つコンテナ、 ruby ( sinatra ) の機能を持つコンテナ、 mysql の機能を持つコンテナの3つのコンテナを作成し、それらのコンテナを連携させていきます。

 先述の通り docker のコンテナは docker image から作成されますので、開発環境で docker image を作成し、本番環境にデプロイします。

 具体的な コーディング は visual studio code などのツールを使用すると思いますが docker volume という機能を使うと docker の外部で作成したデータを docker 内部の環境と共有することができます。( docker volume は docker の外部のディレクトリを docker の作業ディレクトリ等にマウントする機能です )

 docker image の元になる環境の構築が完了したら docker build コマンドで docker image を作成します。本番環境で docker run コマンドを使用することで docker build で作成した docker image を元に docker container が作成されます。

 前置きが長くなりました。ではここからは開発環境で実際に docker image を作成していきます。

タイトルとURLをコピーしました