takaya030の備忘録

PHP、Laravel、Docker などの話がメインです

Docker で sinatra の開発環境を構築

Docker で sinatra の開発環境を構築したときの手順メモ

検証環境

Windows10 Home Edition
VirtualBox 6.1.10

# Docker Host OS (CoreOS)
$ uname -a
Linux default 4.9.93-boot2docker #1 SMP Thu Jul 19 18:29:50 UTC 2018 x86_64 GNU/Linux

Docker version 18.06.1-ce, build e68fc7a
docker-compose version 1.20.1, build 5d8c71b

sinatra インストール手順の概要

  1. 最初に sinatra の初期プロジェクトが入った Docker イメージを作成する ( base イメージと呼ぶ)
  2. base イメージからコンテナを作成し、初期プロジェクトのフォルダを docker cp でホストOS側にコピーする
  3. base イメージを元にホストOS側のプロジェクトを上書きするイメージを作成する ( app イメージと呼ぶ)
  4. 以後の開発作業はホストOS上のプロジェクトのソースコードを変更し、 app イメージを作り直すこととなる

初期のディレクトリ構成

初期は sinatra フォルダの中は docker-compose.ymlDockerfile のみ

sinatra
|   docker-compose.yml
|   Dockerfile

docker-compose.yml

base イメージを作成するための内容

version: "3.4"
services:
  base: 
    build:
      context: .
      dockerfile: ./Dockerfile
      target: "sinatra-base"
    image: takaya030/sinatra-base

Dockerfile

こちらも base イメージを作成するための内容

FROM ruby:2.7.1 as sinatra-base
LABEL maintainer "takaya030"

RUN apt-get update -qq && \
    apt-get install -y build-essential libpq-dev nodejs && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# insall sinatra
RUN mkdir /myapp
WORKDIR /myapp
RUN bundle init && \
    echo 'gem "sinatra"' >>Gemfile && \
    echo 'gem "sinatra-contrib"' >>Gemfile && \
    bundle config set path 'vendor/bundle' && \
    bundle install

CMD ["true"]

base イメージのビルド

$ cd sinatra
$ docker-compose build base

プロジェクトフォルダをホストOS側へコピー

下記のコマンドで base イメージからコンテナを起動します
(コンテナ内で true コマンドを実行しているだけなのですぐに終了します)

$ docker-compose up -d

コンテナの中のプロジェクトフォルダをホストOS側へコピーします
これが実際の開発環境になります

$ docker cp sinatra_base_1:/myapp .

# "sinatra_base_1" は先ほど起動したコンテナの名前

コピーが完了すると sinatra/myapp/ フォルダ以下に開発環境が作成されます

sinatra
|   docker-compose.yml
|   Dockerfile
|   
\---myapp

コピーが完了したらコンテナを削除します

$ docker-compose rm

app イメージ作成のための設定追加

docker-compose.yml

下記の内容に変更します

version: "3.4"
services:
  base: 
    build:
      context: .
      dockerfile: ./Dockerfile
      target: "sinatra-base"
    image: takaya030/sinatra-base
  app: 
    build:
      context: .
      dockerfile: ./Dockerfile
      target: "sinatra-app"
    image: takaya030/sinatra-app
    ports: 
      - "3000:3000"
    volumes:
      - ./myapp:/myapp
    working_dir: /myapp
    command: "bundle exec ruby myapp.rb -o 0.0.0.0 -p 3000"

Dockerfile

下記の内容に変更します

FROM ruby:2.7.1 as sinatra-base
LABEL maintainer "takaya030"

RUN apt-get update -qq && \
    apt-get install -y build-essential libpq-dev nodejs && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# insall sinatra
RUN mkdir /myapp
WORKDIR /myapp
RUN bundle init && \
    echo 'gem "sinatra"' >>Gemfile && \
    echo 'gem "sinatra-contrib"' >>Gemfile && \
    bundle config set path 'vendor/bundle' && \
    bundle install

CMD ["true"]

#=========================================
FROM sinatra-base as sinatra-app

COPY ./myapp /myapp
WORKDIR /myapp

CMD ["bundle","exec","ruby","myapp.rb","-o","0.0.0.0","-p","3000"]

app イメージのビルド

$ docker-compose build app

app イメージの動作確認

myapp.rb 追加

下記の内容で myapp/myapp.rb を追加

Bundler.require
get '/' do
    "Hello world!" 
end

Docker コンテナの起動

$ docker-compose up -d

アクセス

web ブラウザで http://192.168.99.100:3000/ にアクセスして下の画像のように表示されば正常動作しています

f:id:takaya030:20200607161005p:plain

gem パッケージの追加方法

現在インストールされているパッケージを確認

$ docker-compose run --rm app bundle list
Gems included by the bundle:
  * backports (3.17.2)
  * multi_json (1.14.1)
  * mustermann (1.1.1)
  * rack (2.2.2)
  * rack-protection (2.0.8.1)
  * ruby2_keywords (0.0.2)
  * sinatra (2.0.8.1)
  * sinatra-contrib (2.0.8.1)
  * tilt (2.0.10)
Use `bundle info` to print more detailed information about a gem

myapp/Gemfile に追加したいパッケージを記述

--- a/Gemfile     Sun Jun 07 13:28:41 2020
+++ b/Gemfile     Sun Jun 07 21:10:26 2020
@@ -7,3 +7,5 @@
 # gem "rails"
 gem "sinatra"
 gem "sinatra-contrib"
+gem "omniauth"
+gem "omniauth-twitter"

下記のコマンドでパッケージをインストール

$ docker-compose run --rm app bundle install

正常にインストールされたか確認
( omniauth 関連のパッケージが追加されているのを確認)

$ docker-compose run --rm app bundle list
Gems included by the bundle:
  * backports (3.17.2)
  * hashie (4.1.0)
  * multi_json (1.14.1)
  * mustermann (1.1.1)
  * oauth (0.5.4)
  * omniauth (1.9.1)
  * omniauth-oauth (1.1.0)
  * omniauth-twitter (1.4.0)
  * rack (2.2.2)
  * rack-protection (2.0.8.1)
  * ruby2_keywords (0.0.2)
  * sinatra (2.0.8.1)
  * sinatra-contrib (2.0.8.1)
  * tilt (2.0.10)
Use `bundle info` to print more detailed information about a gem

参考サイト

qiita.com

qiita.com