20191101のdockerに関する記事は9件です。

Windows 10 Pro上にLinuxのwebcam開発環境をDockerで構築する

 ラップトップを新調してWindows環境が手に入ったので、10年ぶりにWindowsに戻ってきました。
思えばOSX/Ubuntu時代は開発環境が対応していない問題で、組込み・FPGA・メカCADから遠ざかってしまっていたので、これから戻していければいいなと思っています。
 さて、とは言えソフトウェアを開発する環境としては慣れ親しんだLinuxを離れる気はないので、そちらもできるようにWindows上に環境を構築しました。チャレンジして初めて知ったんですけど、話題になってたWindows上でLinuxが走るというWSL(無印)とか仮想環境のHyper-Vとか、USB外部デバイスの接続に対応してないんですね。自分はロボット屋で、PCにわちゃわちゃデバイスくっつけて現実環境にサービスを具現化するのが主戦場なので、これでは使い物にならない。来年に出るというWSL2はそのへん改善されてるらしいので期待してますが、とりあえず現状でなんとかする仕組みを構築しました。構築したプロジェクト全体はGitHubに上げてあります。

使ったもの

  • Windows 10 Pro
  • Vagrant 2.2.6
  • VirtualBox 6.0.14
  • Ubuntu 18.04 (bento/ubuntu-18.04)
  • Docker 19.03.4
  • docker-compose 1.24.1

手順

 以下の手順ですが、基本的に偉大な「 Windows環境でDockerコンテナにUSBウェブカメラを認識させてみる1」のページに記載されている手順がベースとなっており、その中に私がハマった部分をチョコチョコ加筆していった構成となっています。

 注. 以下、黒背景のカコミ内で > はホストの Windows への入力で、 $ はゲストのUbuntuへの入力を表しています。

VagrantとVirtualBoxのインストール

 VagrantとVirtualBoxは、それぞれ公式ページから最新版(2019年10月時点)をダウンロードしてきてインストールしました。
- Vagrant
- VirtualBox

Hyper-V無効化

 WindowsのHyper-Vも仮想環境を作成する機能で、実際にHyper-V上にUbuntuをインストールすることは可能なのですが、Hyper-V上の仮想マシンはUSBデバイスに対応しておらず、この方法でwebcamを認識することはできないようです。まったく同じ理由で、WSL上のUbuntuもWindows on Dockerも候補から外れました。2020年に登場するというWSL2ではそのあたり改善されるらしいので、期待したいですね。現在、Windows上でUSBデバイスを認識できる仮想マシンを作成する方法でお手軽なのはVirtualBoxを使う方法のようです。ただ、VirtualBoxを使うためにはHyper-Vの機能を切る必要があります。Windows on DockerはHyper-Vを利用するので両方使う人はいちいち切り替えがめんどくさそうですね。
 Hyper-Vの機能を切る方法は、「Windows featureのダイアログでHyper-Vのチェックボックスからチェックを外す」と色々なところに書いてあるんですが、実際やってみたところ、それだけだと何か足りなかったらしくうまくいきませんでした。最終的には、「Windows10上のVirtualBoxがエラー吐いた時の備忘録のページ2」に書いてあったとおり、PowerShellから管理者権限で

> Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All

を実行した後、再起動することでようやくVirtualBoxが動作するようになりました。

 確認するためには、PowerShellとかで

> systeminfo

としたときに、末尾の"Hyper-V の要件"が、

Hyper-V の要件:         VM モニター モード拡張機能: はい
                        ファームウェアで仮想化が有効になっています: はい
                        第 2 レベルのアドレス変換: はい
                        データ実行防止が使用できます: はい

とずらずら要件が出てきていればOKで、「ハイパーバイザーが検出されました」と出ている状態だとダメなようです。

Vagrantによる仮想マシン生成

 Vagrant boxesにUbuntu 18.04用のboxも色々あるんですが、 generic/ubuntu1804 だけは使っちゃダメです。更新頻度も高くダウンロード数も多いので最初は試してたんですが、こいつはaptのrepositoryがusのサーバーを向いてるので、検索はミスるわダウンロードはエラるわ散々でした。"generic"て書いてあるくせに米国人仕様だと・・・。
 次に、 ubuntu/bionic64 を試してみたんですが、こちらで使用されているカーネルにはuvcvideoのモジュールが読み込まれておらず、USBカメラを接続しても /dev/ 以下にvideoデバイスが組み込まれませんでした。結局、 bento/ubuntu-18.04 を選択することで解決しました。

 それでは、Vagrantfileがあるフォルダに移動して、

> vagrant up

で仮想マシンを作成します。
 * ちなみにこの仮想マシン作成なんですが、途中で apt update & apt upgrade をやっているため、これがエラーになるとそこでvagrant自体も終了してしまいます。こういう場合、何度か vagrant up することでできるようになったりします。。

 このVagrantfileには、「 Windows環境でDockerコンテナにUSBウェブカメラを認識させてみる1」のページを真似て、webcamを自動で仮想マシンに接続するスクリプトを仕込んであります。
 このスクリプトが正常に動作するためには、VirtualBoxのフォルダにパスを通す必要があります。具体的には C:\Program Files\Oracle\VirtualBox にパスを通してください。

 * 初回up時のみ、このタイミングでは仮想マシンが作成されておらず、マシンidがなくてwebcamの接続に手動操作を必要とするので、以下のコマンドで仮想マシンを再起動してください。

> vagrant reload

仮想マシンの設定

 まずは起動した仮想マシンの中にsshで入ります。

> vagrant ssh

 * 以下で説明している手順は、今は Vagrantfile に記述しているので、最初に上げたGitHubリポジトリのプロジェクトを使用する場合は必要ありません。

ユーザーをvideoグループに追加

 デフォルトの状態では、作成された仮想マシン上でユーザー(vagrant)がvideoグループに所属しておらず、videoデバイスを開けなかったので、

$ sudo usermod -aG video vagrant

でグループに追加しました。
 手動でユーザーをvideoグループへ追加した直後は、一旦

$ exit
> vagrant ssh

して、仮想マシンに再ログインするとグループが適用されます。

APTのリポジトリを国内サーバーにする

 また、「Dockerのイメージビルド中でapt-getを高速化するたった1つの方法」のページ3を参考に、 apt のsources リポジトリを日本国内のサーバーを参照するようにして、apt 関連が高速になるように設定しました。

$ sudo sed -i 's@archive.ubuntu.com@ftp.jaist.ac.jp/pub/Linux@g' /etc/apt/sources.list

docker-composeを入れなおす

 あと、なぜかprovisionでインストールしたはずのdocker-composeがSegmentation fault になるので、結局、「 Vagrantアップデートを乗り越える」のページ4を参考にdocker-composeを入れ替えました。

$ curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

Dockerによるビデオキャプチャープロセス起動

 次に、docker-compose経由でdockerコンテナを作成して起動します。

$ cd webcam_test
$ docker-compose up

 初回はDockerイメージの作成が入るので、起動にとても時間がかかると思いますが、2度目以降は作成済のイメージを使うので早いです。これで、Windowsのwebcam_testフォルダに webcam_test.mp4 という動画が作成されているはずです!!
 ちなみに、こちらの mp4 なんですが、Windows Media Playerだと再生できなくて、結局 VLC を使って再生を確認しました。

終了処理

 さて、用事は済んだので、以下で、作成したdockerコンテナを削除してバーチャルマシンから抜けます。

$ docker-compose rm -f
$ exit

 最後に、仮想マシンをシャットダウンします。

> vagrant halt

 以上です。お疲れさまでした。

参考にさせていただいたページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

F# SuaveをHerokuデプロイ

最近F#を触り始め、HerokuにWebアプリをデプロイしてみた。
色々調べたので手順をまとめておく。

完成物

https://github.com/dyoshikawa/heroku-suave-getting-started

環境

OSX Mojave
.NET Core 3.0
Heroku CLI 7.33.3

.NET Coreのインストール

https://dotnet.microsoft.com/download

インストーラで簡単に導入できる。
dotnetコマンドも自動で入る。

ソリューション・プロジェクト作成

ソリューション作成

dotnet new sln -o heroku-suave-getting-started

プロジェクト作成

cd heroku-suave-getting-started
dotnet new console -lang F#
dotnet sln add heroku-suave-getting-started.fsproj

Hello World

dotnet run
Hello World from F#!

Suave導入

https://github.com/SuaveIO/suave

SuaveはF#における (たぶん) デファクトのWEBフレームワーク。
Expressのようなマイクロフレームワーク。

パッケージインストール

サードパーティのパッケージマネージャなど不要で、dotnetコマンドでパッケージインストールが行える。

dotnet add package Suave --version 2.5.6

サーバを起動してみる

先程のHello Worldの記述がされているProgram.fsというファイルがあるので下のように書き換える。

Program.fs
open Suave

[<EntryPoint>]
let main _argv =
    startWebServer defaultConfig (Successful.OK "Hello World!")
    0

dotnet run でビルドと実行を行える。

dotnet run
[20:00:56 INF] Smooth! Suave listener started in 45.809ms with binding 127.0.0.1:8080

この状態でブラウザを開き http://localhost:8080/ を見ると 「Hello World!」が確認できる。

Herokuで動作するコードに変更

Herokuの仕様でポートは環境変数 $PORT から読み取るようにしなければいけない。
そのため下記のように変更する。

Program.fs
open System
open Suave
open Suave.Sockets
open YoLo

[<EntryPoint>]
let main _argv =
    let portByEnv =
        match Env.var ("PORT") with
        | Some(x) -> x
        | None -> "8080"

    let ip : Net.IPAddress = Net.IPAddress.Parse("0.0.0.0")
    let port : Port = uint16 portByEnv

    let socketBinding : Sockets.SocketBinding =
        { ip = ip
          port = port }

    let httpBinding : Http.HttpBinding =
        { scheme = Protocol.HTTP
          socketBinding = socketBinding }

    let conf = { defaultConfig with bindings = [ httpBinding ] }
    startWebServer conf (Successful.OK "Hello World")
    0

ずらずら書いているが環境変数 $PORT を読み取ってそれを起動ポートとしているだけ。
$PORT 変数がない場合は8080となる。

実行ファイルを生成して実行 (Mac OSX)

.NET Core3.0にはスタンドアロンな実行ファイルを生成するという機能がある。

https://docs.microsoft.com/ja-jp/dotnet/core/whats-new/dotnet-core-3-0#single-file-executables

dotnet publish コマンドは、プラットフォーム固有の単一ファイルの実行可能ファイルにアプリをパッケージ化することをサポートします。 実行可能ファイルは自己展開型であり、アプリの実行に必要なすべての依存関係 (ネイティブを含む) が含まれます。

自己完結型アプリには、コードの実行に必要なものがすべて含まれるので、ホスト コンピューターに .NET をインストールする必要はありません。

スタンドアロンというだけあってデプロイ先の本番環境に.NETがなくても動作する。

ではまずはローカル (OSX) で試す。

ビルド時にどのOS向けかを指定する必要がある。

https://docs.microsoft.com/ja-jp/dotnet/core/rid-catalog

RIDカタログによるとOSXはosx-x64となるので -r オプションの引数に指定。

dotnet publish -c Release -r osx-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true

少し待つとビルドが終わりbin/Release/netcoreapp3.0/osx-x64/publishの下にheroku-suave-getting-startedとheroku-suave-getting-started.pdbというファイルができる。
本番にはこの2つのファイルを設置しheroku-suave-getting-startedを実行すれば動作する。

実行してみる。

 ./bin/Release/netcoreapp3.0/osx-x64/publish/heroku-suave-getting-started
[20:09:07 INF] Smooth! Suave listener started in 52.388ms with binding 127.0.0.1:8080

このようにサーバ起動できた。

デプロイ準備

Herokuでは.NETの公式ビルドパックがないため、

  • サードパーティのビルドパックを使う
  • Dockerデプロイする

かのどちらかになる。
今回は後者でいく。

最も、上述のシングル実行ファイル生成機能のおかげで環境構築は非常に簡単。

デプロイ用バイナリを生成 (Alpine Linux)

https://docs.microsoft.com/ja-jp/dotnet/core/rid-catalog

RIDカタログを参照。
Alpineなので linux-musl-x64 を指定。

dotnet publish -c Release -r linux-musl-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true

Dockerfile

ソリューション直下にDockerfileを用意する。
動かすのはスタンドアロンな実行ファイルなので、.NET入りのDockerイメージを用意する必要はなく、素のAlpineで構わない。
しかし多少の依存はあるらしく、最低限以下のパッケージを入れれば動くようだ。

apk add gcc libintl icu

Dockerfileの内容は下記。

Dockerfile
FROM alpine:3.10

RUN apk update && \
    apk add gcc libintl icu

ADD ./bin/Release/netcoreapp3.0/linux-musl-x64/publish /app

CMD /app/heroku-suave-getting-started

Herokuデプロイ

CLIインストール

https://devcenter.heroku.com/articles/heroku-cli

brew tap heroku/brew && brew install heroku

で導入できる。

Herokuログイン

heroku login
heroku container:login

Herokuアプリ作成

heroku create heroku-suave-getting-started

heroku-suave-getting-startedは任意のアプリ名。

デプロイ

heroku container:push web -a heroku-suave-getting-started
heroku container:release web -a heroku-suave-getting-started

アプリをブラウザで開く

heroku open

「Hello World!」が出ていればOK。

参考

https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new?tabs=netcore22
http://maxfie1d.hatenablog.com/entry/2018/01/23/141755
https://docs.microsoft.com/ja-jp/dotnet/core/rid-catalog
https://dev.to/pluralsight/creating-trimmed-self-contained-executables-in-net-core-4m08
https://hub.docker.com/_/microsoft-dotnet-core
https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Google Cloud BuildでCI/CD

Agenda

  1. Google Cloud Buildとは?
  2. CI/CDでのCloudBuild活用例

1. Google Cloud Buildとは?


1-1. 概要

Google Cloud Platform のインフラストラクチャでビルドを行うサービスです。
さまざまなリポジトリやクラウドストレージスペースからソースコードをインポートし、
仕様に合わせてビルドを実行し、DockerコンテナやJavaアーカイブなどのアーティファクトを生成できます。
(Google Cloud Build公式ドキュメントから抜粋)

図にするとこんな感じ
スクリーンショット 2019-11-01 10.40.00.png


1-2. 特徴

  • ネイティブDockerをサポート
  • カスタムワークフローが定義可能
  • 高速なビルド
  • ビルドツールを自由に選択できる
    • Maven、Gradle、Webpack、Go、Bazelなど

1-3. ビルド実行パターン

  1. 手動実行
  2. ビルドトリガーを使用した自動実行
  3. Githubアプリトリガーからの実行

1-4. 手動実行のコマンド紹介

Dockerfileを直接ビルドする場合
~$ ls
Dockerfile
~$ gcloud builds submit --tag {ホスト名}/{PROJECT_ID}/{任意の名前} .
  • ホスト名
    • Container Registryのホスト名であるgcr.io.gcr.io のネームスペースで指定可能
ビルド構成ファイルをビルドする場合
~$ gcloud builds submit --config={Yamlの構成ファイル名} {ソースコードディレクトリの相対パス}

1-5. ビルド構成ファイル

  • サンプルビルド構成ファイル
steps:
- name: 'gcr.io/cloud-builders/git'
  args: ['clone', 'https://github.com/GoogleCloudPlatform/cloud-builders']
  env: ['PROJECT_ROOT=hello']
- name: 'gcr.io/cloud-builders/docker'
  args:
  - 'build'
  - '-t'
  - 'gcr.io/my-project-id/myimage'
  - '.'
images: ['gcr.io/my-project-id/myimage']

1-5-1. フィールド説明

※フィールドは他にもたくさんあるので詳細はドキュメントを確認してください


2. CI/CDでのCloudBuild活用例


2-1. ビルド/デプロイ自動化前

スクリーンショット 2019-11-01 11.43.31.png


2-2. ビルド/デプロイ自動化後 (静的ファイルを除く)

スクリーンショット 2019-11-01 11.39.01.png


2-3. CIテストの自動化について

  • Cloud Build公式のGithub連携ツールを使用
  • 特徴
    • commitをpushするたびに自動でビルド実行
  • CIテストで採用した理由
    • commit単位でテストをしたい
    • プルリクページでビルドステータスを確認できる
  • 設定手順
    1. GithubとCloud Buildを連携 (詳細手順は公式ドキュメントを参照してください)
    2. ソースコードのルートディレクトリに cloudbuild.yaml という名のビルド構成ファイル作成

2-3-1. CIテスト専用のビルド構成ファイル

# cloudbuild.yaml

steps:
# mysql, redisサーバを起動
- name: 'gcr.io/$PROJECT_ID/docker-compose'
  args: ['-f', 'docker-compose.test.yml', 'up', '-d', 'mysql-test', 'redis-test']
# アプリケーションサーバを起動
- name: 'gcr.io/$PROJECT_ID/docker-compose'
  args: ['-f', 'docker-compose.test.yml', 'up', '-d', 'application-server']
# テストシェル実行
- name: 'gcr.io/cloud-builders/docker'
  env: ['MIX_ENV=ci_test']
  args: ['exec', 'application-server', 'sh', '_run-ci-test.sh']
timeout: 900s

2-4. ソースコードの自動ビルドについて


  • Cloud Build公式のビルドトリガーを使用を使用
  • 特徴
    • ソースコードに変更がpushされるたびにビルド実行(トリガーでブランチを指定した場合)
    • Githubアプリトリガーよりも柔軟な設定可能
    • トリガー
      • gitリポジトリのブランチorタグの指定が可能
  • 設定手順
    1. Cloud Buildのサービスページのサイドバーからトリガーを作成 (詳細手順は公式ドキュメントを参照してください)

2-4-1. ソースコードビルド構成ファイル

この構成ファイルでは、ビルド&デプロイコマンドが定義されているシェルスクリプトを実行するようにしています。

# _cloudbuild-dev-all.yaml

steps:
# # ソースコードのビルド
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    bash _build.sh

# ソースコードのデプロイ
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    bash _deploy.sh

timeout: 1200s

  • entrypoint
    • ビルダーのデフォルトのエントリポイントを使用しない場合に指定する


参考文献

Cloud Build公式ドキュメント

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerについて色々調べた結果をまとめてみた

自分用にまとめてた記事(ほぼコピペ)を共有する
ちなみに中途半端な文章多いと思う(順次直す気力があれば

Docker

Dockerとは

Dockerは、インフラ関係やDevOps界隈で注目されている技術の一つで、Docker社が開発している、コンテナ型の仮想環境を作成、配布、実行するためのプラットフォームのこと。

DockerとVagrantの違い

Vagrant + VirtualBox

仮想マシンを動かす仮想化ソフトのラッパーツール

VirtualBoxの構成をVagrantfileというテキストに記述してVagrantに任せることで、ネットワークドライバの設定などを意識すること無く、ホスト環境に依存しない形で整備される

Vagrantの特徴

  • Linux以外のOSの環境が構築できるため、コンテナ型と比べて自由度が高い
  • OSのバージョンの違い、仮想環境ツールの違い、仮想環境ツールの設定の違いなどで構築に手間がかかる
  • VagrantとVirtualBoxのバージョンの相性によってバグがある
  • 仮想環境はホストOS型と呼ばれ、ゲストOSがハードウェアにアクセスするにはホストOSを経由しなければならないため、オーバーヘッドが大きい

Docker

OS・ミドルウェア・ファイルシステム全体をイメージという単位で取り扱い、まるごとやりとり出来るツールのこと。

VirtualBoxなどの仮想マシンでは、ホストマシン上でハイパーバイザを利用しゲストOSを動かし、その上でミドルウェアなどを動かすのに対し、コンテナはホストマシンのカーネルを利用し、プロセスやユーザなどを隔離することで、あたかも別のマシンが動いているかのように動かすことができます。そのため軽量で高速に起動、停止などが可能。

Dockerの特徴

  • 仮想環境はコンテナ型と呼ばれるもので、ホストOSを直接アクセスするためオーバーヘッドが少ない
  • 環境構築が容易でVirtual Boxも不要
  • コンテナは移植性(ポータビリティ)が高く、Dockerさえインストールされていれば、全く同じ環境でアプリを動かせる
  • ホストOSからはコンテナは1プロセスとして認識される

参考

dockerとvagrantの違い言える?新人エンジニアでも分かった気になれる俺流まとめ


仮想化技術

前提として

仮想化の種類には大きくホストOS型とハイパーバイザ型とコンテナ型の3つある

ホスト型

  • ホストOS上に仮想化ソフトを動かす
  • 仮想化環境上でOSを動かす
  • 仮想OS上でアプリケーションを動かす

ハイパーバイザ型

  • マシン全体を仮想環境とする
  • 仮想環境上でOSを動かす
  • 仮想OS上でアプリケーションを動かす

コンテナ型

  • ホストOS上でコンテナを動かす
  • ホストOSと仮想OSでカーネルを共有している
  • 基本的にLinuxでのサポート
  • 他のOSでも要件次第で利用可能

用語

PC/端末/ホストマシン

CPU,メモリ、ストレージといった様に限られているリソースがある。
仮想化を実現してるサーバー等が過剰にスペックが高かいのはリソース供給量を上げるためという理由がある。

VirtualBox,VMWare

仮想化を実現するにはまず骨組みや土台が必要。
windowsユーザーであればtask-managerのCPUタブから「仮想化:有効/無効」(Hyper-V)があり、LinuxだとKVMがそれにあたります。

Karnel

カーネルとはOSの基本機能の役割を担うソフトウエア
カーネルだけではOSを利用するのが困難なため別途ソフトウェアと組み合わせて利用するのが一般的
カーネルとソフトウェアを組み合わせたものをディストリビューションという
一般的に言われているCentOSやUbuntuは、Linuxカーネル+ソフトウェアのディストリビューションのことを指す


DockerHub

DockerHubとは

コンテンナを共有するためのサービス。
ユーザが作成したコンテナをアップロードして公開・共有ができるサービスのこと。
ここでアップロードされたコンテナは自由にダウンロードして自分のサーバーに簡単にデプロイできる。

参考
Docker Hubの使い方とGitHubからのDockerイメージ自動ビルド (1/2)


参考

dockerとvagrantの違い言える?新人エンジニアでも分かった気になれる俺流まとめ

Dockerfile

Dockerfileとは

Docker上で動作させるコンテナの構成情報を記述するためのファイルでのこと。
Dockerfileに記述された情報をもとにして、docker buildコマンドにてDockerイメージを作成する事が出来る。

記述方法

1行につき1つの操作を{命令}と{引数}でスペース区切りで記述する。
「docker build」コマンドで「Dockerfile」ファイルの上から順番に処理が実行される

# コメント
FROM iphp:7.1-fpm

命令と用途

命令 用途
FROM 元となるDockerイメージの指定
MAINTAINER 作成者の情報
RUN コマンドの実行
ADD ファイル/ディレクトリの追加
CMD コンテナーの実行コマンド 1
ENTRYPOINT コンテナーの実行コマンド 2
WORKDIR 作業ディレクトリの指定
ENV 環境変数の指定
USER 実行ユーザーの指定
EXPOSE ポートのエクスポート
VOLUME ボリュームのマウント

参考

Dockerfileとdocker buildコマンドでDockerイメージの作成 (1/2)
Dockerfileを極めて、Dockerマスターになろう!


Docker Compose

Docker Composeとは

Dockerは、1コンテナ1プロセスという思想が基本。1つのコンテナにすべての機能を詰め込まず、複数のコンテナを起動して、協調してシステムを構成しようという概念。

例えば、リバースプロキシのnginx、バックエンドのアプリケーション、データベースをそれぞれ別のコンテナで起動して、システムを構築する。それをYAMLの設定ファイルひとつで簡単に実現するのがDocker Compose。

docker-compose.ymlという設定ファイルに、どのコンテナを立ち上げるかを記述し、docker-compose upというコマンド1つ実行するだけで、必要なサービスがすべて立ち上がる。

これを活用することで、ミドルウェアの構成まで含めた開発環境の統一が可能になる。
(つまりコードベースで必要なアプリケーションやDBのコンテナ設定が出来る)

使い方

Docker Composeで構築したアプリケーションは、docker-compose buildコマンドでイメージを作成する。

build

自作のDockerfileを元にコンテナを起動する場合は、buildディレクティブを使用し、相対パスでDockerfileの位置を指定する。

image

配布されているイメージを元にコンテナを起動する場合は、imageディレクティブでイメージ名を指定する。

volumes

コンテナにマウントするボリューム(≒ ディレクトリ)を指定する。主な用途として以下が上げられる

  1. コンテナを停止してもデータを永続化したい
  2. ホスト上にあるファイルをコンテナ内で使用したい
  3. あるコンテナから出力されるファイルを他のコンテナから使用したい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel5.8の環境をDockerで構築する(忙しいあなたに)

忙しいあなたにチャチャっとDocker for Laravel

参考

Laravelの環境をDockerで構築するチュートリアル

概要

上で載せたDokcer for Laravelの記事がクソ有能なのでめっちゃ見させてもらってるけど、
パッて使いたい時に説明読むのしんどいので自分用まとめ記事です。

自分用なので大分言葉足りずだと思います。

環境

  • Laravel5.8
  • PHP7.3
  • MySQL57

ディレクトリ構造

appがLaravelディレクトリ

スクリーンショット 2019-11-01 17.13.05.png


docker-compose.yml

  • web:ports:が被らないようにする
  • mysql:ports:が被らないようにする
docker-compose.yml
version: '3'
services:
  web:
    image: nginx:1.15.6
    ports:
      - "8030:80"
    depends_on:
      - app
    volumes:
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
  app:
    build: ./docker/php
    depends_on:
      - mysql
    volumes:
      - .:/var/www/html
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: default
      MYSQL_USER: default
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: secret
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
volumes:
  mysql-data:

Dockerfile

Dockerfile
FROM php:7.3-fpm

# install composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim

RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql

WORKDIR /var/www/html

npm使うなら以下を追記

RUN curl -sL https://deb.nodesource.com/setup_11.x | bash -
RUN apt-get install -y nodejs
RUN npm install npm@latest -g

default.conf

default.conf
server {
    listen 80;

    root  /var/www/html/app/public;
    index index.php index.html index.htm;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
          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 restart

Laravelインストール

上記の手順を全て終えたら仮想環境に入る

docker-compose exec app bash

Laravel5.8をComposerを使用してインストール

Laravelプロジェクト名を変更する際は最後の app 部分を任意の名前に変更する

composer create-project --prefer-dist laravel/laravel=5.8.* app

Laravel設定

DB_をdocker-compose.ymlで設定したものに変更する

.env
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:KjL3igybtFcsPzAjU5B6WFXzMcuA3O8N5S4nA+pdGyg=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

完了

スクリーンショット 2019-11-01 18.03.00.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Docker】dockerでコンテナ, イメージ, volumeを全てクリア(削除)する方法

方法

コンテナ、image, volumeを一緒に削除

docker system prune -a --volumes -f

簡単な解説

  • docker system prune で使っていないデータを削除する(コンテナ、イメージ、volume)
  • -a オプションで全ての使っていないイメージを削除する
  • --volumes オプションで全ての使っていないvolumeを削除する
  • -f オプションで確認せずに削除する(強制削除ではない)

原始的な方法

コンテナの削除

docker rm -f $(docker ps -a -q)

簡単な解説

  • docker rm は起動していないコンテナを削除するコマンド
  • -f オプションは起動しているコンテナでも強制的に削除する
  • $() 内のコマンドが実行され、出力を渡すことができる
  • docker ps は起動しているコンテナ一覧を出力するコマンド
  • -a オプションは起動していないコンテナ一覧も含めて出力するコマンド
  • -q オプションはコンテナIDのみを出力するコマンド
  • $(docker ps -a -q) で展開されたコンテナ一覧が docker rm -f で全て削除される

イメージの削除

docker rmi -f $(docker images -q)

簡単な解説

  • docker rmi は使われていないイメージを削除するコマンド
  • -f オプションは使われているイメージでも強制的に削除する
  • $() 内のコマンドが実行され、出力を渡すことができる
  • docker images はイメージの一覧を出力するコマンド
  • -q オプションはイメージのIDのみを出力するコマンド
  • $(docker images -q) で展開されたイメージ一覧が docker rmi -f で全て削除される

volumeの削除

docker volume rm -f $(docker volume ls -q)

簡単な解説

  • docker volume rm は使われていないvolumeを削除するコマンド
  • -f オプションは使われているvolumeでも強制的に削除する
  • $() 内のコマンドが実行され、出力を渡すことができる
  • docker volume ls はvolumeの一覧を出力する
  • -q オプションはvolumeのIDのみを出力する
  • $(docker volume ls -q) で展開されたvolume一覧が docker volume rm -f で全て削除される
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerコンテナからGoogle Cloud SDKのコマンドを簡単に実行できるコマンドをつくってみた

なるべくDockerを利用して手元の端末を汚さない試み。便利かはわかりません。

使い方

docker-gcloud コマンドはDockerコンテナでgcloud コマンドを実行しています。
認証情報はホストの~/.config/gcloud を参照します。

Cloud Buildにジョブ登録してみます。

# credentials.dbなどがある前提
> ls ~/.config/gcloud/
access_tokens.db   config_sentinel    credentials.db     legacy_credentials
active_config      configurations     gce                logs


> docker-gcloud --version
Google Cloud SDK 267.0.0
bq 2.0.49
core 2019.10.15
gsutil 4.44


> cat <<EOF > cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/git'
  entrypoint: 'bash'
  args: ['-c', 'echo "hoge"']
EOF


> docker-gcloud builds submit \
  --config=cloudbuild.yaml \
  --no-source
Created [https://cloudbuild.googleapis.com/v1/projects/<GCPのProjectID>/builds/16cab9fd-a4b3-4937-a7a3-7838516788d3].
Logs are available at [https://console.cloud.google.com/gcr/builds/16cab9fd-a4b3-4937-a7a3-7838516788d3?project=168605712006].
---------------------------------------------------- REMOTE BUILD OUTPUT ----------------------------------------------------
starting build "16cab9fd-a4b3-4937-a7a3-7838516788d3"

FETCHSOURCE
BUILD
Already have image (with digest): gcr.io/cloud-builders/git
hoge
PUSH
DONE
-----------------------------------------------------------------------------------------------------------------------------

ID                                    CREATE_TIME                DURATION  SOURCE  IMAGES  STATUS
16cab9fd-a4b3-4937-a7a3-7838516788d3  2019-10-20T02:23:44+00:00  3S        -       -       SUCCESS


> docker-gcloud builds log \
  16cab9fd-a4b3-4937-a7a3-7838516788d3
---------------------------------------------------- REMOTE BUILD OUTPUT ----------------------------------------------------
starting build "16cab9fd-a4b3-4937-a7a3-7838516788d3"

FETCHSOURCE
BUILD
Already have image (with digest): gcr.io/cloud-builders/git
hoge
PUSH
DONE
-----------------------------------------------------------------------------------------------------------------------------

カレントディレクトリのcloudbuild.yaml をちゃんとみてくれてますね。でけたー

環境設定

コマンドを作成

Google Cloud SDKのDockerイメージは公式から提供されているのでそれを利用します。

google/cloud-sdk - Docker Hub
https://hub.docker.com/r/google/cloud-sdk/

下記を参考にしてDockerコンテナ内でgcloud コマンドを実行できるようにします。

Dockerにホームディレクトリをマウントしちゃおう - Qiita
https://qiita.com/74th/items/a3a7d6826a67e8a61608

Dockerコンテナからホスト側カレントディレクトリにアクセス - Qiita
https://qiita.com/yoichiwo7/items/ce2ade791462b4f50cf3

ポイントは以下のとおりです。

  • -v $HOME/.config/gcloud:$HOME/.config/gcloud -e "HOME=$HOME" で認証情報をホストにあるものを参照
  • -v $PWD:$PWD -w $PWD でコマンド実行時のカレントディレクトリを指定
  • --entrypoint=gcloud$* で通常のgcloud コマンド実行と同じ挙動を実現
docker-gcloud
#!/bin/sh
docker run -it --rm \
  -v $HOME/.config/gcloud:$HOME/.config/gcloud \
  -v $PWD:$PWD \
  -e "HOME=$HOME" \
  -w $PWD \
  --entrypoint=gcloud \
  google/cloud-sdk:alpine \
  $*

作成したファイルのシンボリックリンクを/usr/local/bin にはって実行できるようにします。/usr/local/bin$PATH に含まれている前提です。

google/cloud-sdk - Docker Hub
https://hub.docker.com/r/google/cloud-sdk/

Dockerにホームディレクトリをマウントしちゃおう - Qiita
https://qiita.com/74th/items/a3a7d6826a67e8a61608

Dockerコンテナからホスト側カレントディレクトリにアクセス - Qiita
https://qiita.com/yoichiwo7/items/ce2ade791462b4f50cf3

自作のコマンドを作成した - Qiita
https://qiita.com/yoshiken/items/2b8e6c24d6b95e65b625

> chmod +x docker-gcloud
> ln -s docker-gcloud /usr/local/bin/

これで最初にあげたようにdocker-gcloud コマンドが実行できるようになります。
gsutil コマンドもエントリーポイントを変えてやれば実現できます。

コマンド実行のカレントディレクトリがDockerコンテナで参照できるので、たいていのコマンド実行では問題にならないかなと。
docker-gcloud がコマンド打つのに長ったらしいのはエイリアスなんかでどうにでもなります。

まとめ

使えるかわかりませんが、とりあえずイメージしてたコマンドが出来上がりました。

参考

google/cloud-sdk - Docker Hub
https://hub.docker.com/r/google/cloud-sdk/

Dockerにホームディレクトリをマウントしちゃおう - Qiita
https://qiita.com/74th/items/a3a7d6826a67e8a61608

Dockerコンテナからホスト側カレントディレクトリにアクセス - Qiita
https://qiita.com/yoichiwo7/items/ce2ade791462b4f50cf3

自作のコマンドを作成した - Qiita
https://qiita.com/yoshiken/items/2b8e6c24d6b95e65b625

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【図解】「Docker(コンテナ)でUbuntuを構築する」ってどういう意味?

独学でちょろちょろDocker(コンテナ)を勉強していましたが、不明点がたまる一方...。
そんな中、Dockerの研修に行ける機会があり、不明点を解消してきたので備忘録としてまとめます。

いくつか解消できたのですが、すっきり度合い高めな2つだけピックアップ。

解消点

  • 「DockerでUbuntuを構築する」ってどういう意味?
  • 「Docker for Mac」の正体って何者?

Dockerとは

記事をさくっとまとめるためにDockerの詳しい解説は省きます。
すでに素晴らしい解説をしてくれている方が多数います。
自身が駄文で解説するよりも、遥かに参考になると思います。

【図解】Dockerの全体像を理解する -前編-
Dockerを体系的に学び直してみた(概要編)
【図解】コレ1枚でわかるサーバー仮想化とコンテナの違い

「DockerでUbuntuを構築する」ってどういう意味?

 仮想マシンとコンテナの違い

度々比較される仮想マシンとコンテナ。
当初の自分のイメージではこんな感じ。
vm_container.png
この絵で言いたいことは、
仮想マシンは新たにOSも用意して仮想化しよう
コンテナでは各コンテナで1つのOS(ホストOS)を共有しよう
ということです。

# docker run ubuntu

参加した研修ではCentOSにDockerを導入していました。
そして遭遇するこのコマンド。

#  docker run ubuntu

コマンド自体は書いてある通りで、「DockerでUbuntuを構築してね」というものです。
しかし、独学で勉強した際にも、ここでつまりました。

「コンテナってOSは入れないんじゃないの?」
CentOSが入ってるのにUbuntuもいれるの?」

では不明点を解消していきます。

OSの構成要素

まずはOS周りについてまとめます。
OSとはみんな知ってるWindowsとかのことですね。
OSは大まかに以下の構成となっています。
os.png
おそらくこの図で納得しない方も多いと思いますが、自分はこの図がわかりやすかったので、これでいきます。

ここで色分けされているカーネルが今回大事になる部分です。
カーネルとはOSの中核です。

Linuxディストリビューション

次にLinuxディストリビューションについてまとめます。
上記ででてきたCentOSやUbuntuが有名ですね。
これらは大まかに以下の構成となっています。
linux.png
ここで大事なことは、
ディストリビューションが違っても、カーネルは同じLinuxカーネルということです。
差があるのはシェルとかその他の部分です。

厳密にはディストリビューションにはカーネルは入らないのかな...?
ここではざっくり理解できればいいということで。

上記知識を念頭に不明点を解消

いろいろと話が出てきましたが、まとめていきます。
自分が勘違いしていたのは以下の点です。

  • コンテナはホストOSを共用している
  • ディストリビューションが違えば、全く違うOS

まず1点目の「コンテナはホストOSを共用している」ですが、
これは「コンテナはホストOSのカーネルを共用している」が正しい表現です。

次に2点目の「ディストリビューションが違えば、全く違うOS」ですが、
これは「ディストリビューションが違ってもカーネルは同じ」が正しい表現です。

上記2点を元に「DockerでUbuntuを構築する」を絵で描いてみます。

container_kernel.PNG

絵心がないので、絵はこれが限界です。
要は、「ホストOSにはCentOSをいれて、コンテナではUbuntuのシェルやその他を用意して、ホストOSのカーネルを使ってUbuntuを動かす」ということです。

自分の中ではこれでイメージができたのですが、
同じ悩みを抱えていた同志の方々いかがでしょうか...?

「Docker for Mac」の正体って何者?

Docker for MacでもUbuntuを構築

MacでDockerを扱うソフトウェアとして、「Docker for Mac」があります。
では、これを用いてMacでDockerを扱えるようにしたとして、コンテナ上にUbuntuは構築できるのでしょうか。

今までの話からすると、MacとLinuxのカーネルはそれぞれ違うのものなのでできなさそうです。
ただ、これはできます

Docker for Macは仮想マシンとほぼ同義

「なんでMac上のDockerでUbuntuが構成できるの?」
と質問を投げたところ、講師の方はこのような返答でした。

Docker for MacはLinuxOSを導入する仮想マシンと考えて!」

つまり絵にするとこんな感じ。

docker4mac.png

実は、Docker for MacはLinuxOSを導入するための仮想マシンの役割をしていました。
(もちろん他にもいろいろしています)
これであればコンテナから見たホストOSはLinuxOSとなり、Ubuntuも難なく構成できそうです。

実際にDocker for Macを導入するとLinuxOSが動作しているのを確認できます。
DockerをMacにインストールする

少し補足すると、
Dockerは元々ホストOSがLinuxであること前提に作られたものです。
それをMac上で動かすために、まずはLinuxを入れようね、という感じみたいです。

 おわりに

個人的な備忘録も兼ねてまとめてみましたが、
文章&絵に起こすとわかりづらいですね...。

とりあえずプロトタイプとして残しておいて、わかりづらいところは加筆していきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「Docker(コンテナ)でUbuntuを構築する」ってどういう意味?

独学でちょろちょろDocker(コンテナ)を勉強していましたが、不明点がたまる一方...。
そんな中、Dockerの研修に行ける機会があり、不明点を解消してきたので備忘録としてまとめます。

いくつか解消できたのですが、すっきり度合い高めな2つだけピックアップ。

解消点

  • 「DockerでUbuntuを構築する」ってどういう意味?
  • 「Docker for Mac」の正体って何者なの?

Dockerとは

記事をさくっとまとめるためにDockerの詳しい解説は省きます。
すでに素晴らしい解説をしてくれている方が多数います。
自身が駄文で解説するよりも、遥かに参考になると思います。

【図解】Dockerの全体像を理解する -前編-
Dockerを体系的に学び直してみた(概要編)
【図解】コレ1枚でわかるサーバー仮想化とコンテナの違い

「DockerでUbuntuを構築する」ってどういう意味?

 仮想マシンとコンテナの違い

度々比較される仮想マシンとコンテナ。
当初の自分のイメージではこんな感じ。
vm_container.png
この絵で言いたいことは、
仮想マシンは新たにOSも用意して仮想化しよう
コンテナでは各コンテナで1つのOS(ホストOS)を共有しよう
ということです。

$ docker run ubuntu

参加した研修ではCentOSにDockerを導入していました。
そして遭遇するこのコマンド。

#  docker run ubuntu

コマンド自体は書いてある通りで、「DockerでUbuntuを構築してね」というものです。
しかし、独学で勉強した際にも、ここでつまりました。

「コンテナってOSは入れないんじゃないの?」
CentOSが入ってるのにUbuntuもいれるの?」

では不明点を解消していきます。

OSの構成要素

まずはOS周りについてまとめます。
OSとはみんな知ってるWindowsとかのことですね。
OSは大まかに以下の構成となっています。
os.png
おそらくこの図で納得しない方も多いと思いますが、自分はこの図がわかりやすかったので、これでいきます。

ここで色分けされているカーネルが今回大事になる部分です。
カーネルとはOSの中核です。

Linuxディストリビューション

次にLinuxディストリビューションについてまとめます。
上記ででてきたCentOSやUbuntuが有名ですね。
これらは大まかに以下の構成となっています。
linux.png
ここで大事なことは、
ディストリビューションが違っても、カーネルは同じLinuxカーネルということです。
差があるのはシェルとかその他の部分です。

厳密にはディストリビューションにはカーネルは入らないのかな...?
ここではざっくり理解できればいいということで。

上記知識を念頭に不明点を解消

いろいろと話が出てきましたが、まとめていきます。
自分が勘違いしていたのは以下の点です。

  • コンテナはホストOSを共用している
  • ディストリビューションが違えば、全く違うOS

まず1点目の「コンテナはホストOSを共用している」ですが、
これは「コンテナはホストOSのカーネルを共用している」が正しい表現です。

次に2点目の「ディストリビューションが違えば、全く違うOS」ですが、
これは「ディストリビューションが違ってもカーネルは同じ」が正しい表現です。

上記2点を元に「DockerでUbuntuを構築する」を絵で描いてみます。

container_kernel.PNG

絵心がないので、絵はこれが限界です。
要は、「ホストOSにはCentOSをいれて、コンテナではUbuntuのシェルやその他を用意して、ホストOSのカーネルを使ってUbuntuを動かす」ということです。

自分の中ではこれでイメージができたのですが、
同じ悩みを抱えていた同志の方々いかがでしょうか...?

「Docker for Mac」の正体って何者なの?

Docker for MacでもUbuntuを構築

MacでDockerを扱うソフトウェアとして、「Docker for Mac」があります。
では、これを用いてMacでDockerを扱えるようにしたとして、コンテナ上にUbuntuは構築できるのでしょうか。

今までの話からすると、MacとLinuxのカーネルはそれぞれ違うのものなのでできなさそうです。
ただ、これはできます

Docker for Macは仮想マシンとほぼ同義

「なんでMac上のDockerでUbuntuが構成できるの?」
と質問を投げたところ、講師の方はこのような返答でした。

Docker for MacはLinuxOSを導入する仮想マシンと考えて!」

つまり絵にするとこんな感じ。

docker4mac.png

実は、Docker for MacはLinuxOSを導入するための仮想マシンの役割をしていました。
(もちろん他にもいろいろしています)
これであればコンテナから見たホストOSはLinuxOSとなり、Ubuntuも難なく構成できそうです。

実際にDocker for Macを導入するとLinuxOSが動作しているのを確認できます。
DockerをMacにインストールする

少し補足すると、Dockerは元々ホストOSがLinuxであること前提に作られたものです。
それをMac上で動かすために、まずはLinuxを入れようね、という感じみたいです。

 おわりに

個人的な備忘録も兼ねてまとめてみましたが、
文章&絵に起こすとわかりづらいですね...。

とりあえずプロトタイプとして残しておいて、わかりづらいところは加筆していきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む