Docker
Dockerの利用方法の変化
- 最初は、プログラマが自分専用の開発・テスト環境を用意するため
- 昔はインフラエンジニアが手順書通りに環境設定していた
- 小さなチームで開発するアプリケーションの場合は、Dockerで必要なライブラリがインストールしてある環境をコンテナイメージに固めておけば楽
- 実サービスでコンテナ利用をする
- 各環境での環境差異を防ぐ
- dockerコマンドで、コンテナイメージをデプロイするだけでOK
- 参照: Dockerによるコンテナ化アプリケーションの運用設計ガイド(パート1) | RED HAT OPENEYE
サービス環境への展開を楽にする
- サービスの停止時間をできるだけ短くしたい
- 問題があったときに、すぐに切り戻したい
- Kudernetes などのオーケストレーションツールを使う(Bule-Green deployment)
- マイクロサービスアーキテクチャを使って、影響範囲を狭める
- 参照: Google Container Engineで五目並べアプリのAPIサーバーを作るデモ - めもめも
3大メリット
- プログラマが自分専用の開発・テスト環境を簡単に用意するため
- 各環境での環境差異を防ぐため
- 継続的デリバリの実現
Kubernetesを使ったBule-Green Deployment
設定ファイル
- Deployment (高可用性の担保)
- ある機能を提供するコンテナをどんな構成でデプロイするかの指定
- Service
- コンテナに対するネットワークを構成するかの指定
- Deployment (高可用性の担保)
Kubernetesのコンテナクラスタ管理の構造
Bule-Green Deployment
- Deployment
- 既存コンテナと新しいバージョンのコンテナを並行稼動させる
- Service
- 外部ユーザのアクセスを既存コンテナへ、内部テストユーザのアクセスを新しいコンテナへ振り分ける
- テスト完了後に、外部ユーザのアクセスも新しいコンテナへ振り分ける
- Deployment
Dockerの基本機能
Dockerイメージ作成機能(Build)
- プログラム本体, ライブラリ, ミドルウェア, OS, ネットワークの設定などを1つにまとめられる
- 実体は、アプリ実行に必要なファイル群のディレクトリツリー
- DockerfileにDockerイメージの構成情報を記載する
- Dockerfileを元にビルドすると、Dockerイメージになる
- Docker イメージは、実行環境で動くコンテナのベースになる
Dockerコンテナ実行機能(Run)
Dockerイメージ共有機能(Ship)
コンテナ実行環境構築のフルマネージメントサービス
- コンテナ統合管理ツールの必要性
- Dockerをマルチホスト環境で成立したクラスタ構成で稼働させるため
- コンテナ起動停止、ホスト間のネットワーク接続、ストレージの管理、コンテナスケジューリング、監視が必要
GCP
- 準備
- コンテナ実行環境構築
- 構成: 2 Node
- Console menu > Container Engine > Make Container cluster: 2
- 無停止バージョンアップ
- KubernetesのRolling Update機能を使用
アプリデプロイの流れ
- Dockerfile作成
- Cloud shellを起動して、コードを取得
- Dockerコンテナの元になるDockerイメージを指定(FROM命令)
- 作成者情報(MAINTAINER命令)
- コマンド実行(RUN命令)
- ポート関数(EXPOSE命令)
- デプロイ(ADD命令)
- サーバ起動(CMD命令)
- Dockerイメージビルド
docker build
でDockerfileからイメージ作成(verタグを付ける)docker images
で作成済みのイメージが確認できる
- Dockerイメージの公開
- Dockerイメージにタグを付ける
- タグがついたら、Google Container Registryにアップロードできる (gcloudコマンド)
- Console menu > Container Engine > Container Registryで確認
- GKEから利用できる状態になった!
- 初めてのDeploy
- Cloud shellで認証情報取得(gcloud get-credentials)
- デプロイ構成情報ファイル(deployment.yaml)の作成、デプロイ先指定
- コンテナデプロイ設定ファイル (
kubectl create -f deployment.yaml
) - コンテナに外部からアクセスするためのサービス定義ファイル(
kubectl create -f service.yaml
) - EXTERNAL-IP にアクセスして確認する
- 二回目のDeploy
- イメージ作成、レジストリアップロード
- Rolling Udpate機能でバージョンアップ
- クラスタの停止、削除
kubectl delete service web-service
-> GLBの設定も破棄kubectl delete deployment web-container
- Console menue > Container Engine > Container cluster > Delete Docker image
Laravel の新しいプロジェクトの作成
前提
- Composerがインストールしてあること
How to
Laravel の新しいプロジェクトの作成は、新しいプロジェクトのディレクトリを作成することである
- 具体的には、composer でフレームワークの新規プロジェクトを作成する
Laravel のインストール(数分かかる)
git clone
して、composer install
を動かすのと同じ動きをしている
$ composer create-project laravel/laravel --prefer-dist project_name $ cd project_name $ php artisan --version Laravel Framework 5.4.17
参照
Macにcomposerをbrewでインストール
What?
- これじゃインストールできない
$ brew install composer ... Error: No similarly named formulae found. ==> Searching taps... These formulae were found in taps: homebrew/php/composer Caskroom/cask/multimarkdown-composer homebrew/php/composer@1.2 Caskroom/versions/multimarkdown-composer-beta Caskroom/cask/multimarkdown-composer-pro To install one of them, run (for example): brew install homebrew/php/composer
How to?
$ brew install homebrew/php/composer
Macへのgollumインストールでエラー
What?
$ gem install gollum Fetching: charlock_holmes-0.7.3.gem (100%) Building native extensions. This could take a while... ERROR: Error installing gollum: ERROR: Failed to build gem native extension. checking for main() in -licui18n... no checking for main() in -licui18n... no
Why?
icu4c
ライブラリがない
How to resolve?
$ brew install icu4c
参考
ruby - ERROR: Error installing gollum: ERROR: Failed to build gem native extension - Stack Overflow
Laravel5.4: Form作成(illuminate/htmlではなくて、laravelcollective/htmlで)
Why?
- フォームヘルパーを使うと、Form作るのが楽になる
- laravelcollective/htmlパッケージをプロジェクトに導入しなくてはならない
- NG: illuminate/html メンテ止まってる
- OK: laravelcollective/html メンテされてる
- Laravel Collective は、Laravel本体から外されたパッケージをメンテするプロジェクト
How to?
laravelcollective/htmlをプロジェクトに追加
- インストールコマンドでvendorに追加(何気に時間がかかる)
$ composer require laravelcollective/html
$ cat composer.json { "name": "laravel/laravel", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "type": "project", "require": { "php": ">=5.6.4", "laravel/framework": "5.4.*", "laravel/tinker": "~1.0", "laravelcollective/html": "^5.4" }, ...
- ProviderとAliaseを登録
'providers' => [ ... Collective\Html\HtmlServiceProvider::class, ... 'aliases' => [ ... 'Form' => Collective\Html\FormFacade::class, 'Html' => Collective\Html\HtmlFacade::class ...
登録フォームの実装
- Routingを追加(順番注意):
routes/web.php
Route::get('articles', 'ArticlesController@index'); Route::get('articles/create', 'ArticlesController@create'); Route::get('articles/{id}', 'ArticlesController@show');
- Controllerを追加(順番注意):
app/Http/Controllers/ArticlesController.php
public function create() { return view('articles.create'); }
- Viewを書く:
resources/views/articles/create.blade.php
@extends('app') @section('content') <h1>Write a New Article</h1> <hr /> {!! Form::open(['url' => 'articles']) !!} <div class="form-group"> {!! Form::label('title', 'Title') !!} {!! Form::text('title', null, ['class' => 'form-control']) !!} </div> <div class='form-group'> {!! Form::label('body', 'Body') !!} {!! Form::text('body', null, ['class' => 'form-control']) !!} </div> <div class='form-group'> {!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!} </div> {!! Form::close() !!} @stop
登録APIの実装
- Routingを追加(順番注意):
app/Http/routes.php
Route::post('articles', 'ArticlesController@store');
- Controllerを追加
namespace App\Http\Controllers; use Request; use App\Article; use Carbon\Carbon; class ArticlesController extends Controller { ... public function store() { $input = Request::all(); $input['publishd_at'] = Carbon::now(); Article::create($input); return redirect('articles'); }
逆順ソートで表示
- リスト表示時に
latest
を使う
class ArticlesController extends Controller { public function index() { $articles = Article::latest('published_at')->get(); return view('articles.index', compact('articles')); }
vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php
public function latest($column = 'created_at') { return $this->orderBy($column, 'desc'); }
ハマりどころ
- Laravel 5.4: Class 'Form' not found エラーが出る - kz-engineer -SCRAP-
- Laravel 5.4: Fatal error: Uncaught Error: Class 'Illuminate\Foundation\Application' のエラー - kz-engineer -SCRAP-
- Laravel 5.4: Non-static method Illuminate\Http\Request::all() should not be called statically のエラー - kz-engineer -SCRAP-
参照
Laravel 5.4: Non-static method Illuminate\Http\Request::all() should not be called statically のエラー
What?
- Laravel 5.4 で
Non-static method Illuminate\Http\Request::all() should not be called statically
のエラーがでる
Why?
- Request ファサードまで、リクエストが届いていない
config/app.php
に以下のエイリアスが書いてあるので、Request
を直接呼ぶ'Request' => Illuminate\Support\Facades\Request::class,
Solution
- 以下に変更
use Illuminate\Http\Request;
↓
use Request;
参照
Laravel 5.4: Fatal error: Uncaught Error: Class 'Illuminate\Foundation\Application' のエラー
What?
Fatal error: Uncaught Error: Class 'Illuminate\Foundation\Application'
- のエラーがでる
Why?
- Composerがおかしくなってて、ライブラリが見つけられない
How to?
- ライブラリの Install しなおし & autoload の dump ファイルの更新
$ composer install $ composer dump-autoload