takaya030の備忘録

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

Vagrant で ubuntu 18.04 + Docker 環境構築

VagrantVirtualBoxubuntu 18.04 の VM を構築したときの手順メモ

検証環境

Windows10 Home Edition
VirtualBox 6.0.18
Vagrant 2.2.9

Vagrant Box ファイル追加

vagrant box add コマンドで ubuntu 18.04 の Box ファイルを追加します。

C:\>vagrant box add ubuntu/bionic64

vagrant box list コマンドで Box ファイルが追加されているか確認可能です。

C:\>vagrant box list
ubuntu/bionic64   (virtualbox, 20200916.0.0)

Vagrantfile の作成

作業用ディレクトリを作成して vagant init を実行します。

D:\>mkdir vagrant\ubuntu

D:\>cd vagrant\ubuntu

D:\vagrant\ubuntu>vagrant init ubuntu/bionic64

作成された Vagrantfile を下記の内容に変更します。
仮想マシンのメモリを 2014MB にしています。
プロビジョニングでは Docker 関連のセットアップを行っています。

--- a/Vagrantfile Mon Sep 21 18:01:11 2020
+++ b/Vagrantfile Mon Sep 21 18:49:46 2020
@@ -32,7 +32,7 @@

   # Create a private network, which allows host-only access to the machine
   # using a specific IP.
-  # config.vm.network "private_network", ip: "192.168.33.10"
+  config.vm.network "private_network", ip: "192.168.33.10"

   # Create a public network, which generally matched to bridged network.
   # Bridged networks make the machine appear as another physical device on
@@ -49,13 +49,13 @@
   # backing providers for Vagrant. These expose provider-specific options.
   # Example for VirtualBox:
   #
-  # config.vm.provider "virtualbox" do |vb|
-  #   # Display the VirtualBox GUI when booting the machine
-  #   vb.gui = true
-  #
-  #   # Customize the amount of memory on the VM:
-  #   vb.memory = "1024"
-  # end
+  config.vm.provider "virtualbox" do |vb|
+    # Display the VirtualBox GUI when booting the machine
+    vb.gui = true
+
+    # Customize the amount of memory on the VM:
+    vb.memory = "2048"
+  end
   #
   # View the documentation for the provider you are using for more
   # information on available options.
@@ -63,8 +63,30 @@
   # Enable provisioning with a shell script. Additional provisioners such as
   # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
   # documentation for more information about their specific syntax and use.
-  # config.vm.provision "shell", inline: <<-SHELL
-  #   apt-get update
-  #   apt-get install -y apache2
-  # SHELL
+  config.vm.provision "shell", inline: <<-SHELL
+    apt-get remove -y docker docker-engine docker.io containerd runc
+
+    apt-get update -y
+
+    apt-get install -y \
+    apt-transport-https \
+    ca-certificates \
+    curl \
+    gnupg \
+    lsb-release
+
+    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
+
+    echo \
+  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
+  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+
+   apt-get update -y
+   apt-get install -y docker-ce docker-ce-cli containerd.io
+
+   gpasswd -a vagrant docker
+
+   curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
+   chmod 755 /usr/local/bin/docker-compose
+  SHELL
 end

仮想マシン作成

vagrant up コマンドで仮想マシンを作成します。

D:\vagrant\ubuntu>vagrant up

vagrant ssh コマンドで仮想マシンにログインします。

D:\vagrant\ubuntu>vagrant ssh

exit でログアウトします。

vagrant@ubuntu-bionic:~$ exit
logout
Connection to 127.0.0.1 closed.

仮想マシンの停止

vagrant halt仮想マシンを停止します。

D:\vagrant\ubuntu>vagrant halt

Docker の動作確認

プロビジョニングが正常に実行されていれば docker コマンドが使用可能になっています。

vagrant@ubuntu-bionic:~$ docker -v
Docker version 19.03.13, build 4484c46d9d

vagrant@ubuntu-bionic:~$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c

vagrant@ubuntu-bionic:~$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:5122f6204b6a3596e048758cabba3c46b1c937a46b5be6225b835d091b90e46c
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest

vagrant@ubuntu-bionic:~$ docker run --rm hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

参考サイト

takaya030.hatenablog.com

qiita.com

docs.docker.com

変更履歴

  • 2021-06-26 Docker のインストール手順を更新

Laravel の OAuth クライアントを Lumen に移植した

はじめに

下記の条件で Lumen で使える OAuth クライアントを探して手頃なものが見つからなかったので、過去に Laravel を使っていた時によく使った OAuth クライアントを移植してみました

  • Facade を使わない
  • カスタムの OAuth サービスを登録可能

作成した OAuth クライアント

こちらが今回作成したパッケージです。oriceon/oauth-5-laravel を fork して Lumen 向けに書き換えています
Lumen 6 以降で動作します

github.com

インストールおよび設定

インストール

Lumen のプロジェクトの composer.json に以下の内容を追加

"repositories": [
    {
        "type": "vcs",
        "url": "https://github.com/takaya030/oauth-lumen"
    }
],
"require": {
  "takaya030/oauth-lumen": "dev-master"
}

その後、 composer update でパッケージをインストール

$ composer update

パッケージ登録

下記内容で OAuth サービスプロバイダを作成

app/Providers/OAuthServiveProvider.php

<?php

namespace App\Providers;

/**
 * @author     Dariusz Prz?da <artdarek@gmail.com>
 * @copyright  Copyright (c) 2013
 * @license    http://www.opensource.org/licenses/mit-license.html MIT License
 */

use Illuminate\Support\ServiceProvider;
use Takaya030\OAuth\OAuth;

class OAuthServiceProvider extends ServiceProvider {
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = false;
    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
    }
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        // Register 'oauth'
        $this->app->singleton('oauth', function ($app) {
            // create oAuth instance
            $oauth = new OAuth();

            // return oAuth instance
            return $oauth;
        });
    }
    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return [];
    }
}

boostrap/app.php に OAuth サービスプロバイダを登録

/*
|--------------------------------------------------------------------------
| Register Service Providers
|--------------------------------------------------------------------------
|
| Here we will register all of the application's service providers which
| are used to bind services into the container. Service providers are
| totally optional, so you are not required to uncomment this line.
|
*/

$app->register(App\Providers\OAuthServiceProvider::class);

設定ファイル

プロジェクトのルートに config フォルダを作成。その下に下記内容で oauth-lumen.php を配置する

config/oauth-lumen.php

<?php

return [

    /*
   |--------------------------------------------------------------------------
   | oAuth Config
   |--------------------------------------------------------------------------
   */

    /**
    * Storage
    */
    'storage' => '\\OAuth\\Common\\Storage\\Session',
    //'storage' => '\\Takaya030\\OAuth\\OAuthLumenSession',

    /**
    * Consumers
    */
    'consumers' => [

        'Google' => [
            'client_id'     => '',
            'client_secret' => '',
            'scope'         => [],
        ],

    ]

];

boostrap/app.php の中で config/oauth-lumen.php を読み込むようにする

/*
|--------------------------------------------------------------------------
| Load Custom Config Files
|--------------------------------------------------------------------------
*/

$app->configure('oauth-lumen');

認証情報

config/oauth-lumen.phpconsumers に追加する

    /**
    * Consumers
    */
    'consumers' => [

        'Google' => [
            'client_id'     => 'Your Google client ID',
            'client_secret' => 'Your Google Client Secret',
            'scope'         => ['OAuth2 scope'],
        ],  
    ]

Session Storage の設定

アクセストークンをセッションに保存するための設定
Lumen はデフォルトではセッションが有効になっていないため、下記サイトの手順で有効化する

qiita.com

config/oauth-lumen.phpstorage の設定を下記に変更

    /**
     * Storage
     */
    'storage' => '\\Takaya030\\OAuth\\OAuthLumenSession',

使い方

基本的な使い方

下記のコードで OAuth サービスクラスのオブジェクト が取得可能

$service = app('oauth')->consumer('Google');

オプションで第2引数に認証時にリダイレクト先 URL が指定できる

$service = app('oauth')->consumer('Google', 'http://url.to.redirect.to');

サンプルプログラム

Google

認証情報を config/oauth-lumen.php に追加

'Google' => [
    'client_id'     => 'Your Google client ID',
    'client_secret' => 'Your Google Client Secret',
    'scope'         => ['userinfo_email', 'userinfo_profile'],
],  

コントローラのサンプルコード

<?php

public function loginWithGoogle(Request $request)
{
    // get data from request
    $code = $request->get('code');
    
    // get google service
    $googleService = app('oauth')->consumer('Google');
    
    // check if code is valid
    
    // if code is provided get user data and sign in
    if ( ! is_null($code))
    {
        // This was a callback request from google, get the token
        $token = $googleService->requestAccessToken($code);
        
        // Send a request with it
        $result = json_decode($googleService->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
        
        $message = 'Your unique Google user id is: ' . $result['id'] . ' and your name is ' . $result['name'];
        echo $message. "<br/>";
        
        //Var_dump
        //display whole array.
        dd($result);
    }
    // if not ask for permission first
    else
    {
        // get googleService authorization
        $url = $googleService->getAuthorizationUri();
        
        // return to google login url
        return redirect((string)$url);
    }
}

カスタムの OAuth サービスの使い方

例として Google サービスDatastore API が使えるよう拡張してみます

OAuth サービスクラスの定義

Google サービスDatastore API を使うとエラーになりますが、原因はサービスクラスにスコープが定義されていないためなので Datastore のスコープを定義したサービスクラスを作成します

app/OAuth/Service/MyGoogle.php

<?php

namespace App\OAuth\Service;

use \OAuth\OAuth2\Service\Google;

class MyGoogle extends Google
{
    const SCOPE_DATASTORE = 'https://www.googleapis.com/auth/datastore';
}

OAuth サービスクラスの登録

作成したサービスクラスをサービスプロバイダで登録します

app/Providers/OAuthServiveProvider.php

<?php

namespace App\Providers;

/**
 * @author     Dariusz Prz?da <artdarek@gmail.com>
 * @copyright  Copyright (c) 2013
 * @license    http://www.opensource.org/licenses/mit-license.html MIT License
 */

use Illuminate\Support\ServiceProvider;
use Takaya030\OAuth\OAuth;

class OAuthServiceProvider extends ServiceProvider {
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = false;
    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
    }
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        // Register 'oauth'
        $this->app->singleton('oauth', function ($app) {
            // create oAuth instance
            $oauth = new OAuth();

            // register custom service
            $oauth->registerService('MyGoogle', \App\OAuth\Service\MyGoogle::class);

            // return oAuth instance
            return $oauth;
        });
    }
    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return [];
    }
}

OAuth サービスの設定追加

config/oauth-lumen.php

<?php

return [

    /*
   |--------------------------------------------------------------------------
   | oAuth Config
   |--------------------------------------------------------------------------
   */

    /**
    * Storage
    */
    //'storage' => '\\OAuth\\Common\\Storage\\Session',
    'storage' => '\\Takaya030\\OAuth\\OAuthLumenSession',

    /**
    * Consumers
    */
    'consumers' => [

        'MyGoogle' => [
            'client_id'     => 'Your Google client ID',
            'client_secret' => 'Your Google Client Secret',
            'scope'         => ['https://www.googleapis.com/auth/datastore'],
        ],

    ]

];

OAuth サービスオブジェクトの取得

下記のコードで Datastore API が使用可能な MyGoogle サービスオブジェクトが取得可能

$service = app('oauth')->consumer('MyGoogle');

参考

github.com

qiita.com

Lumen 8 で APP_KEY を作る

Lumen の artisan コマンドには key:generate が無いので、代わりに APP_KEY を作成する方法についてメモ

検証環境

Windows10 Home Edition
XAMPP 7.4.9

$ php --version
PHP 7.4.9 (cli) (built: Aug  4 2020 11:52:41) ( ZTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.9, Copyright (c), by Zend Technologies
    with Xdebug v2.8.1, Copyright (c) 2002-2019, by Derick Rethans

$ php artisan --version
Laravel Framework Lumen (8.2.1) (Laravel Components ^8.0)

APP_KEY 作成方法

コマンドラインから下記のコマンドを入力する

$ php -r "require 'vendor/autoload.php'; echo \Illuminate\Support\Str::random(32);"
TNhuSsgqtiH8W7mhP7OUAptueW6KjP0X

備考

str_random を使った方法は現在は使用できない

$ php -r "require 'vendor/autoload.php'; echo str_random(32).PHP_EOL;"
PHP Fatal error:  Uncaught Error: Call to undefined function str_random() in Command line code:1
Stack trace:
#0 {main}
  thrown in Command line code on line 1

Fatal error: Uncaught Error: Call to undefined function str_random() in Command line code on line 1

Error: Call to undefined function str_random() in Command line code on line 1

Call Stack:
    0.2188     359392   1. {main}() Command line code:0

参考

VirtualBox + docker-machine で作成した VM の IP を変更する

docker-machine create で作成した VM (boot2docker) の IP アドレスを変更する手順メモ

検証環境

Windows10 Home Edition
VirtualBox 6.1.10

# Docker Host OS (CoreOS)
$ uname -a
Linux default 4.14.154-boot2docker #1 SMP Thu Nov 14 19:19:08 UTC 2019 x86_64 GNU/Linux

# Docker Toolbox 19.03.1
Docker version 19.03.1, build 74b1e89e8a
docker-machine.exe version 0.16.1, build cce350d7

発生した問題について

Docker Toolbox 18.06.1-ce の環境から 19.03.1 にアップデート後、 docker-machine createVM を作り直したところ VM の IP アドレスが 192.168.99.101 になった。
(VM は 1 台しか動かしていない)
恐らく新しい VM を作るときに古い VM のホストオンリーネットワークアダプタが残っていたのが原因と考えられる。

$ docker-machine.exe ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default   -        virtualbox   Running   tcp://192.168.99.101:2376           v19.03.5

特に実害はないが、以前の環境では 192.168.99.100 だったので可能ならば戻したい。
合わせて VM を複数作成したときに、各 VM の固定 IP 化も行いたい。
(VM の起動順で IP が変わるのを防ぐため)

解決方法

boot2docker の起動スクリプト作成

VM/var/lib/boot2docker/bootsync.sh に下記内容でスクリプトを作成。

#!/bin/sh

/etc/init.d/services/dhcp stop
ifconfig eth1 192.168.99.100 netmask 255.255.255.0 broadcast 192.168.99.255 up

実行属性を付与

$ sudo chmod 755 /var/lib/boot2docker/bootsync.sh

VM の再起動と TLS 証明書の更新

$ docker-machine restart default
$ docker-machine regenerate-certs default

動作確認

VM の IP アドレスが 192.168.99.100 に変更されたことを確認する。

$ docker-machine.exe ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default   -        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.5

参考サイト

qiita.com

stackoverflow.com

qiita.com

Docker Toolbox をアップデートしたらホストOS(CoreOS)の VM が起動しなくなった

Docker Toolbox 18.06.1-ce から 19.03.1 にアップデートしたときに docker-machine start で Docker ホストOS (CoreOS) が起動しなくなったときに行った作業メモ。

検証環境

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 Toolbox 18.06.1-ce
Docker version 18.06.1-ce, build e68fc7a
docker-machine version 0.15.0, build b48dc28d

発生した問題について

Docker Toolbox 18.06.1-ce の環境から 19.03.1 にアップデート後、 docker-machine upgrade を実行してから docker-machine start したときに以下のエラーが発生してホスト OS の VM が起動しなかった。

$ docker-machine start default
Starting "default"...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.
(default) Waiting for an IP...
Maximum number of retries (5) exceeded

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
default   -        virtualbox   Running                 Unknown   ssh command error:
command : ip addr show
err     : exit status 127
output  : bash: ip: command not found

解決方法について

GitHub の docker/toolbox の Issue で自分と同じ問題が出た人がいて、その方は VM を作り直すことで解決した模様。
Docker Toolbox 18.06.1-cedocker-machine0.15.0 だが、 18.09.0 以降は 0.16.0 に変更されたことが原因と考えられる。
Docker Toolbox 19.03.1docker-machineVM を作り直して解決するか検証する。

検証作業

イメージ、コンテナのバックアップ

現在使用している VM は削除するため、新しい環境でも使用したいイメージやコンテナはあらかじめバックアップしておく。

# 以下のコマンドは Windows 側で実行する

# Windows の docker コマンドを VM に接続
$ eval $(docker-machine env --shell sh default)

# イメージのエクスポート例
$ docker save centos:8 > centos-8.image.tar

# コンテナのエクスポート例
$ docker export busybox_1 > busybox_1.container.tar

現在の VM の削除

$ docker-machine stop default
$ docker-machine rm default

Docker Toolbox 19.03.1 のインストール

下記のサイトから DockerToolbox-19.03.1.exe をダウンロード、インストールする。

github.com

インストール後、docker および docker-machine のバージョンを確認。

$ docker -v
Docker version 19.03.1, build 74b1e89e8a

$ docker-machine -v
docker-machine.exe version 0.16.1, build cce350d7

VM の作成

docker-machine createVM を作成する。

$ docker-machine create --driver virtualbox --virtualbox-memory 2048 --virtualbox-disk-size 40000 default

VM の確認

$ docker-macine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default   -        virtualbox   Running   tcp://192.168.99.101:2376           v19.03.5

docker-machine ssh でログイン

$ docker-machine ssh default
   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

docker@default:~$ docker -v
Docker version 19.03.5, build 633a0ea838

イメージ、コンテナのインポート

新しく作成した VM にイメージ、コンテナをインポートする。

# 以下のコマンドは Windows 側で実行する

# Windows の docker コマンドを VM に接続
$ eval $(docker-machine env --shell sh default)

# イメージのインポート例
$ docker load < centos-8.image.tar

# コンテナのインポート例
$ cat busybox_1.container.tar | docker import - busybox_1:latest

まとめ

  • docker-machine upgrade した後、VM が起動しなくなった場合は docker-machine のバージョン違いを確認する
  • docker-machine のバージョンが変わっていたら docker-machine createVM を作り直す

参考サイト

takaya030.hatenablog.com

github.com

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

Vagrant で CentOS8 + Docker 環境構築

VagrantVirtualBox に CentOS8 の VM を構築したときの手順メモ

検証環境

Windows10 Home Edition
VirtualBox 6.0.16
Vagrant 2.2.5

Vagrant Box ファイル追加

vagrant box add コマンドで CentOS8 の Box ファイルを追加します。
provider は 5) virtualbox を選択します。

C:\>vagrant box add generic/centos8
==> box: Loading metadata for box 'generic/centos8'
    box: URL: https://vagrantcloud.com/generic/centos8
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1) docker
2) hyperv
3) libvirt
4) parallels
5) virtualbox
6) vmware_desktop

Enter your choice: 5

vagrant box list コマンドで Box ファイルが追加されているか確認可能です。

C:\>vagrant box list
generic/centos8   (virtualbox, 2.0.6)

Vagrantfile の作成

作業用ディレクトリを作成して vagant init を実行します。

D:\>mkdir vagrant\centos8

D:\>cd vagrant\centos8

D:\vagrant\centos8>vagrant init generic/centos8

作成された Vagrantfile を下記の内容に変更します。
仮想マシンのメモリを 2014MB にしています。
プロビジョニングでは Docker 関連のセットアップを行っています。

--- a/Vagrantfile Sat Feb 01 18:11:48 2020
+++ b/Vagrantfile Sun Feb 02 00:27:02 2020
@@ -32,7 +32,7 @@

   # Create a private network, which allows host-only access to the machine
   # using a specific IP.
-  # config.vm.network "private_network", ip: "192.168.33.10"
+  config.vm.network "private_network", ip: "192.168.33.10"

   # Create a public network, which generally matched to bridged network.
   # Bridged networks make the machine appear as another physical device on
@@ -49,13 +49,13 @@
   # backing providers for Vagrant. These expose provider-specific options.
   # Example for VirtualBox:
   #
-  # config.vm.provider "virtualbox" do |vb|
-  #   # Display the VirtualBox GUI when booting the machine
-  #   vb.gui = true
-  #
-  #   # Customize the amount of memory on the VM:
-  #   vb.memory = "1024"
-  # end
+  config.vm.provider "virtualbox" do |vb|
+    # Display the VirtualBox GUI when booting the machine
+    vb.gui = true
+
+    # Customize the amount of memory on the VM:
+    vb.memory = "2048"
+  end
   #
   # View the documentation for the provider you are using for more
   # information on available options.
@@ -63,8 +63,18 @@
   # Enable provisioning with a shell script. Additional provisioners such as
   # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
   # documentation for more information about their specific syntax and use.
-  # config.vm.provision "shell", inline: <<-SHELL
-  #   apt-get update
-  #   apt-get install -y apache2
-  # SHELL
+  config.vm.provision "shell", inline: <<-SHELL
+    dnf -y update
+
+    dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
+    dnf -y --nobest install docker-ce
+
+    gpasswd -a vagrant docker
+
+    systemctl start docker
+    systemctl enable docker
+
+    curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
+    chmod 755 /usr/local/bin/docker-compose
+  SHELL
 end

仮想マシン作成

vagrant up コマンドで仮想マシンを作成します。

D:\vagrant\centos8>vagrant up

仮想マシンへログイン

仮想マシン起動後、vagrant ssh コマンドでログインできます。

D:\vagrant\centos8>vagrant ssh

exit でログアウトします。

[vagrant@centos8 ~]$ exit
logout
Connection to 127.0.0.1 closed.

仮想マシンの停止

vagrant halt仮想マシンを停止します。

D:\vagrant\centos8>vagrant halt

Docker の動作確認

プロビジョニングが正常に実行されていれば docker コマンドが使用可能になっています。

[vagrant@centos8 ~]$ docker -v
Docker version 19.03.5, build 633a0ea

[vagrant@centos8 ~]$ docker-compose -v
docker-compose version 1.25.3, build d4d1b42b

[vagrant@centos8 ~]$ docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
bdbbaa22dec6: Pull complete
Digest: sha256:6915be4043561d64e0ab0f8f098dc2ac48e077fe23f488ac24b665166898115a
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest

[vagrant@centos8 ~]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              6d5fcfe5ff17        5 weeks ago         1.22MB

[vagrant@centos8 ~]$ docker run --rm busybox echo Hello,World
Hello,World

参考サイト

takaya030.hatenablog.com sig9.hatenablog.com qiita.com