OmniAICreator/Qiita-1.07M huggingface dataset:
Node.js Expressフレームワークを使用する（ひな型作成）

#はじめに
[前回の投稿](https://qiita.com/t_skri/items/51dda8cd0a8efd906390)でExpressフレームワークを前準備しましたので、次にexpressコマンドでひな型を生成します。

#環境
OS:Windows 10 Pro 64bit
node.js:v12.16.1
npm:v6.13.4
Express:v4.16.1

#ひな型の生成
expressコマンドで生成します。
あらかじめコマンドプロンプトで作業フォルダに移動します。
今回は「D:\Node\ExpressTest01」を作業フォルダにします。

```
D:
CD Node\ExpressTest01
```
移動しましたら、次のコマンドでひな型を生成します。

```
express --view=ejs
```
「--view=ejs」オプションはテンプレートエンジンにEJSを使用すると言う意味になります。

```
D:\Node\ExpressTest01>express --view=ejs

   create : public\
   create : public\javascripts\
   create : public\images\
   create : public\stylesheets\
   create : public\stylesheets\style.css
   create : routes\
   create : routes\index.js
   create : routes\users.js
   create : views\
   create : views\error.ejs
   create : views\index.ejs
   create : app.js
   create : package.json
   create : bin\
   create : bin\www

   install dependencies:
     > npm install

   run the app:
     > SET DEBUG=expresstest01:* & npm start
```

これでひな型は生成されました。
Visual Studio Codeで開きますとこのようになります。
![express01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/b2ba14e0-059f-804c-ec5c-956cefbc3e5b.jpeg)

#使用するライブラリの一括インストール
次のコマンドを実行して、ライブラリの一括インストールを行います。

```
npm install
```

npmはpackage.jsonの「dependencies」に指定されているライブラリを一括インストールする機能があります。
ひな型を生成した際に、必要なライブラリ情報が全て記載されるので便利です。

```
D:\Node\ExpressTest01>npm install
npm notice created a lockfile as package-lock.json. You should commit this file.
added 53 packages from 38 contributors and audited 141 packages in 5.167s
found 0 vulnerabilities
```

#動作確認
コマンドプロンプトで次のコマンドを実行します。

```
npm start
```

```
D:\Node\ExpressTest01>npm start

> expresstest01@0.0.0 start D:\Node\ExpressTest01
> node ./bin/www
```

ブラウザで「[http://localhost:3000](http://localhost:3000)」にアクセスします。
次のキャプチャが表示されればOKです。
![express02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/d75f815c-8b85-8c96-516f-f9ff66d2a11c.jpeg)

コマンドプロンプトには次のように表示されます。

```
GET / 304 14.612 ms - -
GET /stylesheets/style.css 304 1.752 ms - -
```
停止したい時は「Ctrl + C」です。
「バッチ ジョブを終了しますか (Y/N)?」と聞かれますので、「Y」を入力します。

```
バッチ ジョブを終了しますか (Y/N)? Y
```
#まとめ
このような流れでひな型を生成します。
Webページが表示されるまで 〜MVCモデル(+Routing)による解説

#はじめに
プログラミングスクールでPHPを学習中の、33歳女です。
現在は、スクールのカリキュラムが終わって、オリジナルのWebアプリ制作に取りかかっている段階です。
この記事は、私自身の復習と、「Webページが表示されるまでの流れ？　よく分からん」という人のためのものです。
よく分かっている方には、おさらいになるかと思います。

#MVCモデルとは？
簡単に言うと、プログラムの構成を分かりやすくした概念の一つです。
各々が自分のルールプログラムを書くと、作った人以外は何が何やら分からない。
そこで一定のルールを設けて、誰が見てもある程度分かりやすくしよう、という考えの下に誕生しました。
なので、Webに限った話ではないのですが、説明に便利な概念であるため採用しました。
MVCは略称で、以下のように役割が割り振られています。

　　 **・Model：データベースからデータを取ってくる**
　　 **・View：ユーザー側に表示するページを作る**
　　 **・Controller：ViewとModelの橋渡し**

タイトルにある「Routing」が気になる方もいると思いますが、こちらは次の章で説明します。

#Routingとは？
では、タイトルから登場している「Routing」について説明します。
簡単に言うと、ユーザーとControllerの橋渡しで、交通整理の役目を果たしています。
そうです、ユーザーとの橋渡しはControllerではないのです。
ユーザーから来た要求(URLなど)が乗った車を、Controllerという入口に案内する、というイメージです。

#Webページが表示されるまでの流れ
いよいよRoutingも含めた、Webページが表示されるまでの流れを見ていきます。
文章だけだとイメージが湧かないと思うので、以下に図を貼ります。

![MVCモデル図解.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534373/f154a03b-2cc4-b625-4c80-4d6251d39fe4.png)
>画像引用：[ゼロから始めるPHP講座 Vol.44　MVCモデル③~MVCの使用例](https://blog.codecamp.jp/php_mvc03)より

ちなみに、上の図には載っていませんが、RoutingはユーザーとControllerの間にいます。
図にRoutingが載っていないので、流れが分かりづらいとは思いますが、図を基に説明すると以下のようになります。

   **1. ユーザーからの要求(URL等)をRoutingが受け取る**
   **2. 受け取った要求をControllerに案内する**
   **3. ControllerがModelまたはViewに処理を依頼(内容によってどちらに依頼するか変わる)**
   **4. ユーザーの要求がブラウザ上に反映される**

以上がWebページが表示されるまでの流れです。
次の章で具体例を見ていきます。

#実用例
ここでは、友人のブログにアクセスする場面を想像してください。
以下にもう一度、Webページが表示されるまでの流れを記載します。

   **1. ユーザーからの要求(URL等)をRoutingが受け取る**
   **2. 受け取った要求をRoutingがControllerに案内する**
   **3. ControllerがModelまたはViewに処理を依頼(内容によってどちらに依頼するか変わる)**
   **4. ユーザーの要求がブラウザ上に反映される**

あなたは、友人Aさんの〇月×日のブログ記事を読みたいとします。
その場合、〇月×日のブログ記事のリンクをクリックしますよね？
記事のリンクをクリックするのが、上記の1に当たります。
次は裏方のMVCとRoutingが動き始めます。
Routingが上記の2を行なった後は、Controllerの出番です。
それが上記の3、つまり、ControllerがModelとViewに処理を依頼します。
Modelに〇月×日の記事データを取ってくるよう依頼、Viewにはその記事データを表示するように依頼。
上記の3まで全て終わると上記の4、つまり、〇月×日の記事が読めるようになります。

#まとめ
Routingがユーザーからの要求(URL等)を受け取り、Controllerが内容に応じてModelやViewに処理を依頼する。
以上がWebページが表示されるまでの流れです。
MVCモデルは絶対の正解というわけではないとのことですが、ざっくりと流れを理解するには便利な概念だと感じました。

#参考記事
[MVCモデルについてわかりやすく解説します！【初心者向け】](https://umaroidblog.com/what_mvcmodel)
[MVCモデル - 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11584.html)
スクールのカリキュラム…は載せられないので、[スクール公式サイトのリンクを貼ります](https://tech-boost.jp/)
[rails,aws]bundlerのバージョンが変更できないエラーの解決方法

#1.エラーが出るまでの経緯

筆者はチーム開発のローカル開発でbundler-2.0.1を使ってきたのですが、githubからのセキュリティのためのバージョンアップを行なった際に、誤って本番環境のbundlerのバージョンを2.1.4にあげてしまいました。しかし不要なバージョンアップはバグの原因になるため極力避けたいので、ダウングレード（最新バージョンを削除し使いたいバージョンbundlerをインストール）しようとしました。その結果下記のような結果となりました。

```
#使いたいbundlerのバージョンを指定（インストール）
[ec2-user@ip-111-11-11-11 freemarket_sample_62d]$ gem install bundler -v 2.0.1
Successfully installed bundler-2.0.1
Parsing documentation for bundler-2.0.1
Done installing documentation for bundler after 3 seconds
1 gem installed


#現在の高すぎるバージョンを削除（アンインストール）
[ec2-user@ip-111-11-11-11 freemarket_sample_62d]$ gem uninstall -v 2.1.4
ERROR:  While executing gem ... (Gem::CommandLineError)
    Please specify at least one gem name (e.g. gem build GEMNAME)


#bundlerのバージョンを確認
[ec2-user@ip-111-11-11-11 freemarket_sample_62d]$ bundler -v
Traceback (most recent call last):
	2: from /home/ec2-user/.rbenv/versions/2.5.1/bin/bundler:23:in `<main>'
	1: from /home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundler (Gem::GemNotFoundExcep)
```

#2.原因
Gemfile.lockの記述にあるバージョン以外は適用されない（bundlerと認識されない）というルールがあるようです。そのため、このGemfile.lockを残したままbundlerのバージョンを変えようとしても変更することができませんでした。


```Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    actioncable (5.2.4.1)

〜中略〜

RUBY VERSION
   ruby 2.5.1p57

BUNDLED WITH
   2.1.4     #この行に記載のあるバージョン以外はエラーを出すようになっています
```


#3.解決方法
Gemfile.lockを削除→bundlerをダウングレード→bundle installの手順で実行していただければお望みのbundlerのバージョンに変更することができます

#4.（参考）ダウングレードのコマンド
Gemfile.lockを削除したのちに下記の順番でコマンドを打っていただければbundlerをダウングレードすることができます。ちなみに、bundlerの部分を例えばpumaなど他のgemにすればそのgemをダウングレードすることができます

```
$cd   #ホームディレクトリに移動
$cd projects/freemarket_sample_62d  #プロジェクトのディレクトリに移動（筆者の場合は左記）
$gem uninstall bunder -v 2.1.4  #高すぎるバージョンの削除
$gem install bundler -v 2.0.1  #欲しいバージョンをインストール
$bundler -v  #欲しいバージョンが入ったかを確認する
```
[WordPress]投稿・固定ページにリダイレクト機能を追加する！

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#管理画面にリダイレクト機能を追加！
古いコンテンツページのリンクを新しいページにリダイレクトで跳ばす事をしたいと思い実施しました！

functions.phpに以下の記述を追加！

```functions.php
///////////////////////////////////////
// カスタムボックスの追加
///////////////////////////////////////
add_action('admin_menu', 'add_redirect_custom_box');
if ( !function_exists( 'add_redirect_custom_box' ) ):
function add_redirect_custom_box(){
 
  //リダイレクト
  add_meta_box( 'singular_redirect_settings', 'リダイレクト', 'redirect_custom_box_view', 'post', 'side' );
  add_meta_box( 'singular_redirect_settings', 'リダイレクト', 'redirect_custom_box_view', 'page', 'side' );
}
endif;
 
///////////////////////////////////////
// リダイレクト
///////////////////////////////////////
if ( !function_exists( 'redirect_custom_box_view' ) ):
function redirect_custom_box_view(){
  $redirect_url = get_post_meta(get_the_ID(),'redirect_url', true);
 
  echo '<label for="redirect_url">リダイレクトURL</label>';
  echo '<input type="text" name="redirect_url" size="20" value="'.esc_attr(stripslashes_deep(strip_tags($redirect_url))).'" placeholder="https://" style="width: 100%;">';
  echo '<p class="howto">このページに訪れるユーザーを設定したURLに301リダイレクトします。</p>';
}
endif;
 
add_action('save_post', 'redirect_custom_box_save_data');
if ( !function_exists( 'redirect_custom_box_save_data' ) ):
function redirect_custom_box_save_data(){
  $id = get_the_ID();
  //リダイレクトURL
  if ( isset( $_POST['redirect_url'] ) ){
    $redirect_url = $_POST['redirect_url'];
    $redirect_url_key = 'redirect_url';
    add_post_meta($id, $redirect_url_key, $redirect_url, true);
    update_post_meta($id, $redirect_url_key, $redirect_url);
  }
}
endif;
 
//リダイレクトURLの取得
if ( !function_exists( 'get_singular_redirect_url' ) ):
function get_singular_redirect_url(){
  return trim(get_post_meta(get_the_ID(), 'redirect_url', true));
}
endif;
 
//リダイレクト処理
if ( !function_exists( 'redirect_to_url' ) ):
function redirect_to_url($url){
  header( "HTTP/1.1 301 Moved Permanently" );
  header( "location: " . $url  );
  exit;
}
endif;
 
//URLの正規表現
define('URL_REG_STR', '(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)');
define('URL_REG', '/'.URL_REG_STR.'/');
 
//リダイレクト
add_action( 'wp','wp_singular_page_redirect', 0 );
if ( !function_exists( 'wp_singular_page_redirect' ) ):
function wp_singular_page_redirect() {
  //リダイレクト
  if (is_singular() && $redirect_url = get_singular_redirect_url()) {
    //URL形式にマッチする場合
    if (preg_match(URL_REG, $redirect_url)) {
      redirect_to_url($redirect_url);
    }
  }
}
endif;
```

これを追加すると、管理画面にリダイレクトの機能が追加されます！

![Screen Shot 0002-03-05 at 18.28.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/ffb0279a-7b33-4dda-5706-072ecce8dce4.png)

あとは、リダイレクトしたいページのリンクを設定したら完了です！
Problem 1 - The requested PHP extension ext-intl * is missing from your system.のエラー

# 環境
Laravel5.8
MAMP環境
Mac
php7.3

## 問題
プロジェクト下のターミナルで

```
composer install
```
を行った際に

```
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - The requested PHP extension ext-intl * is missing from your system. Install or enable PHP's intl extension.
```
というエラーに遭遇した。

単純にPHP's intl extensionというのを使えるようにしてくださいというエラーだと思い、
installしようとしたが悉くエラーが出てしまった。

## 解決法
phpのバージョンを7.3 → 7.4に引き上げたらcomposer installできるようになりました。

バージョンアップ↓↓
https://qiita.com/tana08/items/046cba8e23d32599ee4a

他に良い方法があれば共有していただきたく存じます。
Mac ポート処理

#Macでのポート処理
##Macでポートを指定してプロセスを検索する方法
macでローカルにサーバーを立ち上げようとするとポートがすでに使用されているという表示がでることがある。
そのような時は

```
lsof -i -P | grep ポート番号
```
とすればpidが表示される。

##プロセスを終了させる

```
kill pid番号
```
上記のコマンドで終了出来ない場合は

```
kill -9 pid番号
```
のようなオプションをつけると強制終了させることが出来る。

##ローカルサーバーの停止方法
上記の様な、ポートがすでに使用されている状況は個人的には以前立てたサーバーを
正常に終了させていないことが理由となっていたことが多かった。
"control + c"で終了させればサーバーが正常に停止してくれる。
ネットワーク～仮想化技術～（VRF・VDOM）活用例

#はじめに
今回は、前記事でちょっと紹介しました『ネットワーク～仮想化技術～』について、
構築例や活用例を書きたいと思います。

前記事：[ネットワーク設計現場で作る資料たち](https://qiita.com/m-yoshimura/items/2d498a178eee372ba26b)

#VRF（Virtual Routing and Fowarding）
【VRF（Virtual Routing and Fowarding）】は直訳したら「仮想ルーティング＆転送」です。
1台の機器の中にそれぞれが独立したルーティングテーブルを複数持つことが出来る機能です。
【VLAN】はL2仮想化技術、【VRF】はL3仮想化技術というと少しピンとくるでしょうか。

CiscoやAlaxalaの機器で本番環境を構築した経験もありますが、検証環境を構築する上でも
重宝する技術だと思っています。検証用機器が複数台必要でも1台で何役にもなってくれたり！
毎度大変お世話になってますm(_ _)m　活用例は後述にて。

CiscoやAlaxalaの設定方法は下記サイトをご参考に↓
Alaxala：[コンフィグレーションガイド Vol.3 / 5.2.2　VRFの設定]
(https://www.alaxala.com/jp/techinfo/archive/manual/AX8600S/HTML/12_8_F/CFGUIDE3/INDEX.HTM)
Cisco：[ネットワークエンジニアとして / VRF]
(https://www.infraexpert.com/study/mpls5.html)

#VDOM（Virtual Domain）
【VDOM（Virtual Domain）】はFortinet社のファイアウォール「Fortigate」の機能です。
初めて使ったときは驚きました、1台のファイアウォールの中に複数のファイアウォールを
仮想的に持つことが出来るのです。この機能によって、システム間通信等をより強固に制御可能となります。
同じ環境でVDOM機能とVM版ファイアウォールを併用していると、呼び名がごっちゃになったりすることもありました。（どちらも仮想ファイアウォールって言ったりします。）

Fortigateの設定方法はメーカサイトをご参考に↓
（OSバージョンがちょっと古いですが、ほぼ変わりません。）
サイト：[FortiGate / FortiOS 5.4.0 Cookbook / VDOM configuration](https://docs.fortinet.com/document/fortigate/5.4.0/cookbook/950783)

#構築例
VRFとVDOMを併用した構築イメージです。↓（論理的な感じでしょうか）
りんごネットワーク:apple:とおれんじネットワーク:tangerine:は物理的には同一機器を通って通信を行いますが、
内部的にはそれぞれ独立したルーティングやポリシーに従って通信を行います。
VRF間若しくはVDOM間でのルーティングを許可しない限り、お互いにネットワーク越しの通信を
行うことは出来ません。

![構成例2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537417/835e20a1-65a2-feb1-1d7c-76c476c7858b.png)



#活用例（VRF）
下記のような検証環境を作りたいと思ったとします。
![活用例2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537417/e1bb042f-918e-53b4-8835-1fd35a756137.png)


拠点Aクライアント～拠点Bクライアントの拠点間通信のテストをしたい。
でも手元にはファイアウォール2台とL3スイッチ1台しかない。
そんな場合でも、VRF機能を持つL3スイッチが１台あれば十分環境を作ることが出来ます。
![活用例3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537417/e482786d-6ba2-44de-6344-167ebff084f2.png)


L3スイッチで、下記用途のVRFを3つ作成します。
1つ目　…　拠点AのLAN用
2つ目　…　拠点BのLAN用
3つ目　…　模擬WAN用

それぞれのVRFで、ルーティングやSVIを設定してポートにVLANをアサインします。
（上図はVLANまで書いてません、インターフェース等は対向機器と合わせて設定します）
これでL3スイッチ1台に「拠点AのL3スイッチ」「拠点BのL3スイッチ」「拠点AのWAN」「拠点BのWAN」の
役割を持たせることが出来ました。

先日同じようにVDOMとVRFを組み合わせた検証構成をつくったのですが、色んな用途としてVRFを10くらい設定していたら頭が混乱してきました。汗　設定するのはいいけど、パッと分かる構成図があるって大事ですね。
上図は簡略しており実践向けではないですので悪しからず。m(_ _)m

ではまた。
Rustのfailure_deriveコンパイルエラー（解決しました）

# 2020/3/6 2:00 追記

先ほどfailureのv0.1.7がリリースされたことで問題は解決しました。
現在は以下の対策は不要になっています。

# はじめに
2020/3/5現在、Rustの多くのクレートが以下のようなコンパイルエラーになる可能性があります。
結構影響範囲が広そうなので原因と対策をまとめておきます。

```
error[E0433]: failed to resolve: could not find `__rt` in `quote`
   --> /Users/sloveless/.cargo/registry/src/github.com-1ecc6299db9ec823/failure_derive-0.1.6/src/lib.rs:107:70
    |
107 | fn display_body(s: &synstructure::Structure) -> Result<Option<quote::__rt::TokenStream>, Error> {
    |                                                                      ^^^^ could not find `__rt` in `quote`
```

# 対策

自分のクレートがコンパイルエラーになる場合はCargo.tomlに以下を追加してください。
（"1.0.2"の前についている`=`が重要です）

```Cargo.toml
[dependencies]
quote = "=1.0.2" # workaround of https://github.com/rust-lang-nursery/failure/issues/342
```

`cargo install`コマンドが失敗する場合には、代わりに`cargo install --locked`を使ってください。

# 原因
2020/3/5 9:00頃にquoteクレートのバージョン1.0.3がリリースされました。1.0.2からのパッチバージョンアップデートなので、アップデートしても互換性に問題ないはずだったのですが、failure_deriveが壊れる結果となりました。
これはfailure_deriveがquoteの非公開APIを使っていたためのようです。（詳細は未確認です）

failure_deriveはfailureを通してcrates.io内の多数のクレートで使われており、手元の計測では全クレートの6割に達します。
そのためかなり高い確率でこの問題の影響を受けることになると思われます。

すでにCargo.lockを作成済みの環境では`cargo update`しない限り影響はありません。
Oracle CloudでPort周りの設定

Oracle Cloudいいですよね。昨年から一部の機能が無料で開放されているので非常に手軽に使えます。インスタンスが無料で２つも使えるなんて最高です！（しかも期限なし！）

そこでOracle Cloudでサービスを公開した時のPortの設定についてのメモです。

（インスタンスの作成は既に終わっているものとします。）

1. ナビゲーションバーから「コンピュート」>「インスタンス」より、今回設定するインスタンスを選択。
2. 「インスタンス情報」タブの「仮想クラウド・ネットワーク」に移動し、「セキュリティリスト」を開く
3. 既にひとつ選択されているものがあると思うので、これを編集します。

## イングレスルール
外部からvmにアクセスする際の設定です。以下は一例です。

sshやhttps等を開けてあります。

|項目|値|
|:--|:--|
|ステートレス|いいえ|
|ソース|0.0.0.0/0（任意のip）|
|IPプロトコル|TCP|
|ソース、ポート範囲|All|
|宛先ポート範囲|20-22,80,443|
|許可|ポートのTCPトラフィック（20-22,80,443）|

<br/>

## エグレスルール
外部にvmからアクセスする際の設定です。

自身はすべて開放しています。

|項目|値|
|:--|:--|
|ステートレス|いいえ|
|宛先|0.0.0.0/0（任意のip）|
|IPプロトコル|TCP|
|ソース、ポート範囲|All|
|宛先ポート範囲|All|
|許可|ポートのTCPトラフィック:All|

<br/>

## 最後に
これでもアクセスできない場合はvm内のファイアウォール（`ufw`とか）を確認して下さい。

それとまれにインスタンスを再起動しないと反映されないことがありました。
IntelliJ + Spring Bootで@Entityや@Service、@Controllerがimportエラーになる

どうやらIntelliJ側のキャッシュが問題となっているようです。

メニューバーの`File > Invalidate Caches/Restart`でリロードすると解決することがあります。

どうしても解決しないときは試してみて下さい。
Kustomize運用でyqを使ってImage tagを更新していく方法

※ 追記
`Kustomize edit set image`コマンドがあるためyqでやる必要がなかったです...つらみ

```bash
$ cd overlays/dev/bases                                                                                                   
$ kustomize edit set image XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend-admin:v1.0.0
```


# はじめに
Kustomizeの`images`を使ってtag運用を行っているパターンは多いと思います
tagの更新を手動ではなくCIなどで自動化したいと思った際に出てくる`imagesの値をreplaceする手段`をyqで解決していきます

# yqのインストール
注意点として`pip`や`brew`でyqを入れちゃうと、今回利用するオプションは使えないのでpip3をおすすめします

```bash
$ pip3 install jq
$ pip3 install yq
```

# Kustomizeでimagesを使う
### images[1].newTagを更新したい
```bash
# 更新前の`kustomization.yaml`
$ cat overlays/dev/bases/kustomization.yaml
namespace: development
bases:
  - ../../../bases/backend
patchesStrategicMerge:
  - patch-backend.yaml
images:
  - name: nginx
    newTag: 1.15.2
  - name: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend
    newName: 00000000000X.dkr.ecr.ap-northeast-1.amazonaws.com/backend
    newTag: latest
resources:
  - namespace.yaml
```

### images[1].newTagを`v1.0.0`に更新する

```bash
# yqでImage tagの更新
$ yq -y -i '.images |= map(select(.name=="XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend").newTag |= "v1.0.0")' overlays/dev/bases/kustomization.yaml

# 確認
$ cat overlays/dev/bases/kustomization.yaml
namespace: development
bases:
  - ../../../bases/backend
patchesStrategicMerge:
  - patch-backend.yaml
images:
  - name: nginx
    newTag: 1.15.2
  - name: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend
    newName: 00000000000X.dkr.ecr.ap-northeast-1.amazonaws.com/backend
    newTag: v1.0.0
resources:
  - namespace.yaml
```

うまくできてます:tada:
注意点としてはkustomization.yamlのコードに空白行は挟めない(yqが取り除いてしまうので)という制約ができる点です

# まとめ
このようにyqを使うとワンライナーでtagを更新できました
これに加えてVersioningの自動化、CIからPRを自動的に発行などをするとGitopsのマニフェスト運用周りが大分綺麗になりそうですね〜（絶賛取組中）ここらへんも随時自分かチームの人で情報出せてけたらなーと思います
Ionicでion-headerを表示しない画面のレイアウト

IonicのPageの基本的な形は以下の通りです。

```html
<ion-header>
  <ion-toolbar></ion-toolbar>
</ion-header>
<ion-content>
  <!-- コンテンツ -->
</ion-content>
```

しかしながら、headerとion-toolbarを配置したくないデザインもあるかと思います。特にアプリのトップ画面とかで、以下のようにレイアウトしたいことがあります。

<img width="240px" alt="89360083_2609639935936093_2950309749695971328_n.jpg名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/dd3765a4-4ce0-5083-0ba5-9580d5046b26.jpeg">


しかし、何も考えずに以下のように実装するとします。

```html
<ion-content>
  <!-- コンテンツ -->
</ion-content>
```

こうすると、Web上では問題なくみえますが、iOSなどではステータスバーにコンテンツがかかってしまうことがあります。こんな感じで、日付にコンテンツが重複してしまっています。

<img width="240px" alt="89360083_2609639935936093_2950309749695971328_n.jpg名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/3f8396c2-9482-7237-4673-daef664a0119.jpeg">



以下のようにすると、それを回避することができます。

```html
<ion-header>
  <ion-toolbar style="--border-width: 0; --min-height: 0"></ion-toolbar>
</ion-header>
<ion-content>
  <!-- コンテンツ -->
</ion-content>
```

<img width="240px" alt="89360083_2609639935936093_2950309749695971328_n.jpg名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100460/e7b8f8f9-44a5-fa71-72d8-610389660c95.jpeg">


簡単ですね。それでは、また。
再帰を理解するために、帰納的定義を知る。

####数学的帰納法
「全ての自然数に対して、性質Pが成立する」ことを示すための推論法。
まず、「__P(0)__」が成立することを示す。次に「__P(x)__を仮定して、__P(x + 1)__を示す」ことにより、「__全ての自然数n__に対して、__P(n)__が成立する」ことが言える、という推論である。

しかし、帰納法は自然数に対する推論法だけではない。自然数以外にも、リストや木などの集合を「__帰納的に定義__」することができ、それぞれに対する推論法としての帰納法がある。

実は、数学的に厳密な意味で、無限に多くの要素を持つ集合を作り出したり、無限に多くの要素に対する性質を示す方法というのは、それほどたくさんあるわけではない。むしろ、そのような定義、推論方法は、ほとんどの場合__帰納__によると言える。

##帰納的に定義された集合
__自然数の集合__などの無限集合を厳密に定義するために、__帰納的定義__(inductive definition)を用いる。

- __basis 基礎__
    - いくつかのもの（あらかじめわかっているもの）は、集合Aの要素であることを定める。
- __induction step ステップ__
    - すでにAの要素であることがわかっているものから、新たにAの要素を作る操作を定める。
- __closure 限定句__
    - 上の操作を、有限回適応して作られた要素のみがAの要素であると定める。

帰納的定義では、closure条件を常に必要とするので、省略して書かないことが多い。
closure条件がないと、集合Aが一意に定まらない。


##所感
__再帰__を理解するには帰納的な定義における、__closure条件__が重要になってくる。限定句がない状況では無限ループになってしまうからだ。

###参考
http://www.cs.tsukuba.ac.jp/~kam/lecture/discrete2017/text/4.pdf
初心者がBitbucketとJira Softwareを使う

プログラミング教室で、GitHubやTrelloを使用していましたが、
会社でBitbucket　Jiraを使用することになり,
そもそも何ってところからのスタートなので調べました。

## 結論は：GitHubやTrelloの代替製品ですね。



# Bitbucketとは?

BitbucketはGitHubと同じ、Gitを使用したソフトウェア開発プロジェクトのためのサービスです。
ATLASSIAN(アトラシアン)という会社が提供しています。
[Bitbucket](https://bitbucket.org/)

Bitbucketは5ユーザーまでであれば、非公開リポジトリは無制限となっています。
しかも、公開リポジトリがひとつもなくても構いません。

GitHubとの大きな違いは、無料で非公開リポジトリを作成できるかどうかだと思います。

BitbucketもGit（ソースコードのバージョン管理ツール）を使用しますが、**GitとGitHubは別物！！！**

## Gitとは？
「Git」は、「ソースコードのバージョンを管理するツール」の名前。システム開発では複数の開発者によってソースコードが書き換わります。いつ誰がどこを変えたのか？ 最新のバージョンはどれか？ など、ソースコードのバージョンを把握する必要があります。このバージョン管理をするツールの1つが「Git」です。

Gitを使用しながら、開発者により便利な付加価値を提供するサービスがGitGubとBitbucketです。




# Jira Softwareとは？
Jiraは、同じくAtlassian社が開発するソフトウェアで課題管理ツールです。チーム全体のタスクや計画を共有して、タスク管理や工数管理、進捗管理、スケジュール管理などを行い、プロジェクト全体を管理できます。

Trelloと同じ感じです。

特徴は、

- 高いカスタマイズ性でアジャイル開発向き
- スクラムボードでコミュニケーションを活発化
- カンバンボードでタスクを可視化
- ロードマップで計画を共有
- 12種類以上のアジャイルレポート
- 課題とコードを結びつける
- Slackとの連携

となっていますが、大体どこも同じ感じかな？
[本家から、代替製品との比較が出ています](https://www.atlassian.com/ja/software/jira/comparison)

色々使い試してまた、比較できたらと思います^^
AIプロジェクトを始める前に読んでおきたい資料集

自分が業務で新しいAI・機械学習プロジェクトを始める前に読んでおきたい、時折振り返るために読みたいと思った資料をまとめています。

基本的に読むのに技術的なスキル・背景が求められるものはこのリストには入れないようにしています。

# Web資料

- [機械学習を使った事業を成功させるために必要な考え方や人材、フェーズとは？](https://qiita.com/yoshizaki_kkgk/items/55b67daa25b058f39a5d)
- [「ＡＩで〇〇したいんだけど」の相談前に確認してほしい３つのこと](https://qiita.com/yoshizaki_kkgk/items/4448ff4a7e40ede0f4cd)
- [機械学習案件を納品するのは、そんなに簡単な話じゃないから気をつけて](https://qiita.com/yoshizaki_kkgk/items/fa8b45918445bb3e6dc3)
- [AI Project Management Anti Pattern](https://speakerdeck.com/yurfuwa/ai-project-management-anti-pattern)
- [【電通】AIプロジェクトの1/3は失敗する。失敗例から導くAI活用の勘所](https://ledge.ai/theai-3rd-dentsu/)
- [ビジネスへのAI導入はなぜ失敗するのか？](https://note.com/morikita/n/n4fdfc62cec29)
- [失敗から学ぶ機械学習応用](https://www.slideshare.net/HiroyukiMasuda1/ss-181844477)
- [失敗から学ぶ機械学習応用～Another Story～](https://qiita.com/bezilla/items/1e1abac767e10d0817d1)
- [AIビジネス推進人材に必要な スキルとその育成方法](https://www.slideshare.net/munjapan/ai-173185017)
- [AIを利用したシステム開発を受託したベンダが絶対に知っておくべきポイントと具体的契約条項](https://storialaw.jp/blog/2894)
- [政府「AI戦略」を発表 、新たなAI人材教育を業界はどう見る！？ ーすべての高校生・大学生がAIの基礎を習得へー](https://ainow.ai/2019/03/29/166629/)
- [ブレインパッドにおける機械学習プロジェクトの進め方](https://www.slideshare.net/BrainPad/ss-149214163)

# 書籍

- [いちばんやさしい機械学習プロジェクトの教本 人気講師が教える仕事に AI を導入する方法 ](https://www.amazon.co.jp/dp/4295003417/)
- [課題解決とサービス実装のためのAIプロジェクト実践読本 ~第4次産業革命時代のビジネスと開発の進め方~](https://www.amazon.co.jp/dp/4839968047/)
- [人工知能システムのプロジェクトがわかる本 企画・開発から運用・保守まで (AI & TECHNOLOGY)](https://www.amazon.co.jp/dp/4798154059/)
- [失敗しない データ分析・AIのビジネス導入: プロジェクト進行から組織づくりまで](https://www.amazon.co.jp/dp/4627854110/)
- [投資対効果を最大化する AI導入7つのルール](https://www.amazon.co.jp/dp/4046045477)
- [仕事ではじめる機械学習 オライリー](https://www.oreilly.co.jp/books/9784873118215/#toc)
macOS 10.15 Catalina で Flutter が Gatekeeper に引っかかる問題

2020/03/05 時点での内容です。
# 概要
SwiftUIのプレビュー機能を見てみようと思って試してみたところ、どうも最新版のCatalinaでなければ使えないとのこと。恐る恐るCatalinaにアップデートし、プレビュー機能は無事に見ることが出来ました。素晴らしい出来です。
と思ったのもつかの間、Flutterのコマンドがエラーを吐くようになりました。どうもMacのセキュリティ機能であるGatekeeprに引っかかってしまっているようです。

## 状況
flutter upgrade などのコマンドを叩くと、以下のようなエラーが発生。
“dart” cannot be opened because the developer cannot be verified.
“idevicename” cannot be opened because the developer cannot be verified.
“idevicescreenshot” cannot be opened because the developer cannot be verified.
“idevicesyslog” cannot be opened because the developer cannot be verified.

ネットで調べると「Gatekeepr切ればOK」的な情報もあったのですが、Flutterコマンド関係のみを例外として追加する sh がありました。

## 解決方法
以下の shコマンドにて、Flutter関係のみGatekeeperに例外を追加してくれます。
https://github.com/AmirKamali/Flutter_GateKeeper_Fix
【Rails】Rakeタスクに:environmentがないとRailsの環境で実行できない

## エラー

Rakeタスクを実行したときに、`NameError: uninitialized constant ClassName`が出る。


```rb:send_mail.rake
namespace :send_mail do
  desc 'メール送信する'
  task :to_admin do
    SendMailer.to_admin.deliver_now
    puts 'メールを送信しました'
  end
end
```

```terminal
$ rake send_mail:to_admin
rake aborted!
NameError: uninitialized constant SendMailer
/Users/k_end/workspace/application/lib/tasks/send_mail.rake:4:in `block (2 levels) in <top (required)>'
Tasks: TOP => send_mail:to_admin
(See full trace by running task with --trace)
```

どうやら`SendMailer`が読み込みできていないようです。
しかし、パスは正しいしタイポもしていない……。

### 試行錯誤

`rails c`で`SendMailer.to_admin.deliver_now`を実行する。
→うまくいく。ということは、`SendMailer`自体には問題はなさそう。

```rb:send_mail.rake
require Rails.root.join("app/mailers/send_mailer")
```
を追加する。
→`NameError: uninitialized constant ApplicationMailer`
根本的にダメそう。

```rb:send_mail.rake
namespace :send_mail do
  desc 'メール送信する'
  task :to_admin do
    # SendMailer.to_admin.deliver_now
    puts 'メールを送信しました'
  end
end
```
原因であろう部分をコメントアウトしてみる。
→うまくいく。

この辺から、「多分RakeタスクがRails環境で実行されていないんだろうなー」と予測。


## 原因

taskに`:environment`を付けていませんでした。generateした時点で自動的に付いているはずなのですが、どこかで消えていた模様。

```rb
namespace :send_mail do
  desc 'メール送信する'
  task to_admin: :environment do
    SendMailer.to_admin.deliver_now
    puts 'メールを送信しました'
  end
end
```

```terminal
$ rake send_mail:to_admin
メールを送信しました
```

無事、`SendMailer`を呼び出してタスクを実行することができました。
Railsのクラスを使うときはRails環境を明示して呼び出す必要があります。
気が付いてみれば大したことがないのに、ハマるときは無駄にハマる。

## リンク

`:environment`で何やってるの？という点についてまとめている先人がいました。
[Rails における rake タスクの :environment について](https://qiita.com/FumiyaShibusawa/items/11035fc640bb36a615ad)
【Spring】BeanUtils.copyPropertiesの落とし穴

# BeanUtils.copyProperties
Springには[BeanUtils.copyProperties](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/BeanUtils.html#copyProperties-java.lang.Object-java.lang.Object-)という便利なメソッドが用意されている。
一方のBeanからもう一方のBeanへ、同じ名前のフィールドの中身をコピーしてくれるメソッドだ。第一引数がコピー元、第二引数がコピー先になる。
クラスが別々だったとしても、同じフィールド名があればコピーは可能である。

**`Book` クラス**

```java
public class Book {

    String code;

    String name;

    int price;
}
```

**使用例**

```java

Book book1 = new Book();

book1.setCode("A");
book1.setName("三国志");
book1.setPrice(500);

Book book2 = new Book();

BeanUtils.copyProperties(book1, book2);
```

こうすることで、`book2`には`book1`の`code`、`name`、`price`の値が丸々コピーされる。

# 落とし穴１：　異なるクラスのオブジェクトにコピーする場合にフィールド名が変わると死ぬ
例えば以下のFormとDtoがあるとしよう。

**CreateBookForm** クラス

```java
public class CreateBookForm {

    String code;

    String name;

    int price;
}
```

**BookDto** クラス

```java
public class BookDto {

    String code;

    String name;

    int price;

    String updateModule;

}
```

Form -> Dtoのマッピングに無邪気に`BeanUtils.copyProperties(createBookForm, bookDto)`などと書くと、死亡率が高まる。

フロントエンドの都合で`CreateBookForm`のフィールド名が`code`が`cd`と変わったとする。

**CreateBookForm** クラス（変更後）

```java
public class CreateBookForm {

    String cd;

    String name;

    int price;
}
```

もうこれで`cd -> code`のコピーは実施されない。フィールド名が異なるからだ。
じゃあ`BookDto`のフィールド名も変えればいいじゃん！って意見もあるかもだが、レイヤー分離のために用意しているクラスで変更が影響し合うのはイケてない。

このメソッドを使う場合、以下の原則を守るべきだと自分は考える。

- 異なるクラスのオブジェクト同士ではコピーさせない！フィールド名が永久に変更されないという保証はどこにもない！ただし継承関係のあるクラスは除く。
- どうしても異なるクラスのオブジェクト同士でコピーさせる必要がある場合は、コピーされることを確認する単体テストを書く！

# 落とし穴２：　同姓同名のメソッドが別のライブラリに存在する
このメソッド、全く同じ名前のものが[Apache Commonsライブラリ](https://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/BeanUtils.html#copyProperties-java.lang.Object-java.lang.Object-)に存在するのである。
しかもこちらのメソッド、**第二引数がコピー元、第一引数がコピー先**となっている。Springの同名メソッドと引数の順番が逆なのである！！
IDEでライブラリ自動インポートを使っていると、あるクラスではSpringの、あるクラスではApacheのcopyPropertiesを呼んでしまう場合があり、気づかずハマることがあるので注意。
自分はハマった。

個人的には「コピー元 -> コピー先」で「左から右へ = 第一引数から第二引数へ」の印象が強いので、Springのものを常に使うようにしている。
HTML&CSS 2

# a要素
a要素となるタグで囲った文章をリンクにすることができる。クリックすると特定のページに遷移するように設定できる。
aタグのhref属性に対して、遷移させたいページのURLを指定
＜a href="どこにリンクするのか"＞リンクとなるテキスト＜/a＞

# form要素
アンケートフォームやお問い合わせフォームを表すブロック要素

# input要素
フォームの入力欄や実行ボタンなどを作成することができる要素。input要素にはtype属性というものがある。
これを指定することによって様々な種類のフォーム部品を作り出すことができる
type属性                用途
text　　　　１行のテキスト入力欄を作成
checkbox　 チェックボックスを複数作成することができる
radio　　    複数の中から１つしか選択できない、ラジオボタンを作る
submit　　 送信ボタンを作る

# textarea要素
複数行のテキスト入力欄を作成する要素

# value属性
送信ボタンを押したときに、どのような値が送られるのかを決めることができる
input要素のsubmit属性で設けたボタンに、文字を入れることができる

# placeholder属性
入力フォームに仮の文字列を入れることができる

# label要素
フォームの構成部品と、 その項目名（ラベル）を明確に関連付けるための要素。
ラジオボタンとテキストをlabel要素で囲むことによって、
文字の部分をクリックしたときもラジオボタンを選択することができる

# select要素
フォームの選択メニューを表す要素で選択肢全体を囲みます。

# option要素
メニューの選択肢を作成するときに使用。この要素内の文字列が、メニューの選択肢として表示される。
option要素で指定する選択肢は、select要素の間に記述

# 

#
AWSでwordpressを動かす6_td-agentの導入

# 本記事のゴール
td-agentを用いてマスターサーバにapacheログを集積し、s3へ送信する

# S3にバケットを用意
| 設定 | 内容 |
|:--|:--|
| パブリックアクセス | 全てブロック |
| Lifecycle | 直近30日以上は削除 |

# EC2->S3へのアクセス確認
シークレットキーはセキュリティ上使用したくないので、S3へのアクセスロールをアタッチする
疎通確認

```
# aws s3 ls s3://バケット名
```

# ローカル用のログローテート設定
とりあえず1日ごと30日間のローテート

```
# chmod 655 /var/log/httpd
# vi /etc/logrotate.d/httpd
# logrotate -f /etc/logrotate.d/httpd
# logrotate /etc/logrotate.conf
```

``` :/etc/logrotate.d/httpd
/var/log/httpd/*log {
    daily
    rotate 30
    missingok
    notifempty
    sharedscripts
    delaycompress
    create 644 apache apache
    postrotate
        /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript
}
```

# td-agentのインストール
※マスターサーバのみ、事前に24224ポートのインバウンドを許可する

fluentd公式からインストールコマンドを実行
https://docs.fluentd.org/installation/install-by-rpm#amazon-linux

```
# curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent3.sh | sh
# cp /etc/td-agent/td-agent.conf /etc/td-agent/td-agent.conf.org
# vi /etc/td-agent/td-agent.conf
# systemctl enable td-agent
# systemctl restart td-agent
```

``` /etc/td-agent/td-agent.conf(マスターサーバ)
<source>
    @type forward
    port 24224
</source>
 
<filter {httpd.access,httpd.error}>
  type record_transformer
  <record>
    host ${hostname}
  </record>
</filter>
 
<source>
  @type tail
  path /var/log/httpd/access_log
  format none
  pos_file /var/log/td-agent/httpd-access.pos
  tag httpd.access
</source>
 
<source>
  @type tail
  path /var/log/httpd/error_log
  format none
  pos_file /var/log/td-agent/httpd-error.pos
  tag httpd.error
</source>
 
<match {httpd.access,httpd.access.slave}>
  @type s3
  s3_bucket hogehoge-bucket-name
  s3_region us-west-2
  time_slice_format %Y%m%d%H
  path httpd_log/access/
  buffer_type file
  buffer_chunk_limit 10m
  buffer_queue_limit 10m
  flush_interval 1h
  flush_at_shutdown true
  buffer_path /var/log/td-agent/httpd/buffer1/*.buffer
</match>
 
<match {httpd.error,httpd.error.slave}>
  @type s3
  s3_bucket hogehoge-bucket-name
  s3_region us-west-2
  time_slice_format %Y%m%d%H
  path httpd_log/error/
  buffer_type file
  buffer_chunk_limit 10m
  buffer_queue_limit 10m
  flush_interval 1h
  flush_at_shutdown true
  buffer_path /var/log/td-agent/httpd/buffer2/*.buffer
</match> 
```

``` /etc/td-agent/td-agent.conf(スレーブサーバ)
<filter {httpd.access.slave,httpd.access.slave}>
  type record_transformer
  <record>
    host ${hostname}
  </record>
</filter>
 
<source>
  @type tail
  path /var/log/httpd/access_log
  format none
  pos_file /var/log/td-agent/httpd-access.pos
  tag httpd.access.slave
</source>
  
<source>
  @type tail
  path /var/log/httpd/error_log
  format none
  pos_file /var/log/td-agent/httpd-error.pos
  tag httpd.error.slave
</source>
  
<match httpd.access.slave>
  <server>
    host 123.45.67.89
    port 24224
  </server>
  @type forward
</match>
  
<match httpd.error.slave>
  <server>
    host 123.45.67.89
    port 24224
  </server>
  @type forward
</match>
```

適当なログを流して、S3にログが送られることが確認できればOK
AWSでwordpressを動かす5_NFSを用いたストレージ共有

# 本記事のゴール
NFSを用いて複数webサーバ間でストレージを共有する

# インスタンス設定
| 設定 | 内容 |
|:--|:--|
| インスタンスタイプ | t2.small |
| EBS | gs2 8GB |
| セキュリティグループ | 22番/80番を特定IPのみ許可 |
| サブネット | パブリック (諸々のインストール完了後はプライベートでOK) |

新しくインスタンスを作ってapacheやphpを入れ直すか、AMIを作るかして、wordpressファイルがローカルに存在しないスレーブ用のwebサーバを作る

# NFSのマウント許可設定 (マスターサーバ作業)
```
# vi /etc/exports

▼追記
# マウント先絶対パス 許可IP(許可操作)
/home/wordpress/wordpress *(rw,no_root_squash)

# exportfs -ra
# systemctl restart nfs
# systemctl enable nfs
```

exportsの設定後、セキュリティグループで2049ポートからのアクセスを許可する


# NFSのマウント設定 (スレーブサーバ作業)
```
# mkdir /home/wordpress/wordpress
# chmod 755 /home/wordpress/wordpress
# chown wordpress:wordpress /home/wordpress/wordpress

# vi /etc/fstab
▼追記
# privateIP:マウント元絶対パス マウント先絶対パス nfs4 defaults 0 0
123.45.67.89:/home/wordpress/wordpress /home/wordpress/wordpress nfs4 defaults 0 0

# mount /home/wordpress/wordpress
```
マウント先の設定周りはこちらに詳しく書かれています
https://qiita.com/kihoair/items/03635447591358210772

# スレーブサーバでmountコマンド実行時のトラブルシュート
| 設定 | 対応 |
|:--|:--|
| 応答がない、レスポンスが返ってこない | セキュリティグループやネットワークの設定を見直してください。おそらく通信が届いていません |
| エラー「mount.nfs4: access denied by server while mounting 123.45.67.89:/home/wordpress/wordpress」 | マスターサーバのIP許可設定が間違っています。まずは「*」で全開放に設定してexportfsとnfsの再読み込みを行なってください。mountが通ることを確認してから許可IPの範囲を狭めると良いです|

# 確認
mountが成功して下記が両方とも確認できればマウントできています
・マスターサーバの更新内容がスレーブサーバ側で反映されていること
・スレーブサーバの更新内容がマスターサーバ側で反映されていること
AWSでwordpressを動かす4_DBをローカルホストからRDSに変更

# 本記事のゴール
ローカルホストで動いているDBをwebサーバのスケーリングのためにRDSへ変更する

# DB設定
DBの負荷状況が読めなかったのでaurora serverlessで自動スケーリングしてもらうことにする

|設定|内容|
|:----------|:-------|
| タイプ |aurora serverless|
| キャパシティ |(後で調整)最小/最大 1|
| 停止設定 |(テスト用なので)アイドル5分|

# ユーザー設定
※aurora serverlessの初回起動は2分くらいかかる

```
# mysql -uユーザー -hエンドポイント -p

mysql> CREATE USER 'test_user'@'%' IDENTIFIED BY 'hogehoge';
mysql> CREATE DATABASE wordpress;
mysql> GRANT ALL PRIVILEGES ON `wordpress`.* TO 'test_user'@'%';
```

# 接続先変更
```
# cd /home/wordpress
# vi wordpress/wp-config.php
```

``` wp-config.php
/** MySQL のホスト名 */
define('DB_HOST', 'auroraのエンドポイント');
```

パブリックIPに接続し直し、再度初回アクセスページが表示されればOK
AWSでwordpressを動かす3_FTP接続

# 本記事のゴール
FTP経由でwordpressプロジェクトファイルの更新ができるようになる

# ユーザー作成
ec2-userに対して色々な操作をするのはセキュリティ上よろしくないのでwordpressユーザーを作成

```
# useradd -m wordpress
# passwd wordpress
# chmod 775 /home/wordpress
```

# パス調整
```
# mv /var/www/wordpress /home/wordpress/
# chown wordpress:wordpress -R /home/wordpress/wordpress
# ln -s /home/wordpress/wordpress /var/www/wordpress
```

# vsftpインストール
```
# yum install -y vsftpd
# cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.org
# vi /etc/vsftpd/vsftpd.conf
# touch /etc/vsftpd/chroot_list
# systemctl start vsftpd
# systemctl enable vsftpd

▼書き換え
anonymous_enable=NO
chroot_local_user=YES
chroot_list_enable=YES
listen=YES
listen_ipv6=NO
tcp_wrappers=NO

▼追記
pasv_enable=YES
pasv_addr_resolve=YES
pasv_min_port=60001
pasv_max_port=60010
use_localtime=YES
force_dot_files=YES
allow_writeable_chroot=YES
```

セキュリティグループで、60001-60010ポートを指定IPのみ解放する
ローカルPCからFTPクライアントソフトで接続を試して、繋がればOK
AWSでwordpressを動かす2_最小構成作り直し

# 本記事のゴール
amazonLinux2のインスタンス単体でwordpressが動く

# インスタンス設定
|設定|内容|
|:----------|:-------|
| インスタンスタイプ |t2.small|
| EBS |gs2 8GB|
| セキュリティグループ |22番/80番を特定IPのみ許可|
| サブネット |パブリック|
| IPアドレス | Elastic IP |

# 内部時間を合わせる
立ち上げてすぐはUTCなので日本時間に合わせる
▼ユーザーガイド
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/set-time.html#change_time_zone

```
# vi /etc/sysconfig/clock
# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# reboot
```

``` :/etc/sysconfig/clock
ZONE="Asia/Tokyo"
UTC=true
```

reboot後、dateコマンドを実行してUTCではなくJSTになっていればOK

# apacheのインストール
```
# yum -y update
# yum install -y httpd
# cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
# systemctl start httpd
# systemctl enable httpd
```

起動後、パブリックIPにアクセスしてapacheが起動していることを確認する

# mysqlのインストール
今回はバージョンアップは行わないため5.6をインストールする

```
# yum -y install yum-utils
# yum remove -y mariadb*
# yum install -y http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
# yum-config-manager --disable mysql55-community
# yum-config-manager --enable mysql56-community
# yum -y install mysql mysql-devel mysql-server mysql-utilities
# cp /etc/my.cnf /etc/my.cnf.org
# vi /etc/my.cnf
# touch /var/lib/mysql/mysql.sock
# chown mysql:mysql /var/lib/mysql
# systemctl start mysqld
# systemctl enable mysqld
```

▼/etc/my.cnfへの追記

``` /etc/my.cnf
character_set_server=utf8
skip-character-set-client-handshake
```

# mysqlのユーザー設定
```
# mysql

mysql> CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'hogehoge';
mysql> CREATE DATABASE wordpress;
mysql> GRANT ALL PRIVILEGES ON `wordpress`.* TO 'test_user'@'localhost';
```

# phpのインストール
amazon-linux-extrasだと7.0が入れられなかったのでyumから入れる

```
# amazon-linux-extras install -y epel
# yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
# yum install -y --enablerepo=remi-php70 php70-php php70-php-common php70-php-pdo php70-php-cli php70-php-mbstring php70-php-xml php70-php-mysqlnd php70-php-json php70-php-process

# cat /opt/remi/php70/enable
出て来たexportコマンドを/etc/bashrcに追記

# source /etc/bashrc

# cp /etc/opt/remi/php70/php.ini /etc/opt/remi/php70/php.ini.org
# vi /etc/opt/remi/php70/php.ini
書き換え
date.timezone = "Asia/Tokyo"

# systemctl restart httpd
# echo '<?php phpinfo();' > /var/www/html/index.php
```

再起動後、パブリックIPにアクセスしてphpinfoが表示されることを確認する

# wordpressのインストール
ここから好きなバージョンがDL可能
https://ja.wordpress.org/download/releases/
今回は例として4.9.4をインストールする

```
# yum install -y wget
# cd /tmp
# wget http://ja.wordpress.org/wordpress-4.9.4-ja.tar.gz
# tar zxvf wordpress-4.9.4-ja.tar.gz
# mv wordpress /var/www
# chown -R apache:apache /var/www/wordpress
```

インストール後、apacheの設定を書き換える

```
# vi /etc/httpd/conf/httpd.conf
変更
DocumentRoot "/var/www/wordpress"

# systemctl restart httpd
```

再起動後、パブリックIPにアクセスしてwordpressの初回アクセスページが表示されることを確認する
![スクリーンショット 2020-03-05 16.05.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298813/e2d31c4f-f35c-c7dc-37d8-e056975b0b97.png)

データベース名などは事前にmysql側で設定してあったものを指定する
wpユーザーの名前やパスワードはご自由に

管理画面まで着地できれば最小構成での作り直しは完了です
AWSでwordpressを動かす1_概要

※ある程度AWSのサービス弄れること前提で記載します

# 経緯
元々はEC2インスタンス1台でのみ運用をしていたwordpressサーバ
DBはローカルホスト、プロジェクトファイル一式全てEBSにある、そんな構成でやっていたのですが、amazonLinux2への切り替えが必要になり、どうせならスケーリングできるように調整しようとなりました

ただし、諸事情でwordpress側には一切手を加えず、インフラ側の作業だけでスケーリング可能にしなければならなくなりました
困った！ということで色々頑張ったことの備忘録

# 前提
・wordpress側への変更は加えない (※wp-configの変更のみ許容
・プラグインも入れちゃダメ
・プロジェクトファイルの更新は管理画面からのアップロードか、FTP接続のみを許容

# 構成
![aws-wp-pre構成図-Page-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298813/ae2cb064-f557-0cc2-d9b0-c5bd32557b77.png)

# 導入ミドルウェア
| ミドルウェア | マスター |スレーブ|
|:----------|:-------|:-------|
| apache |○|○|
| mysql |○|○|
| php |○|○|
| td-agent |○|○|
| nfs |○||
| vsftp |○||

# 願望
EBSマルチアタッチボリュームが2/18からボリュームタイプios1で利用可能に
https://aws.amazon.com/jp/blogs/news/new-multi-attach-for-provisioned-iops-io1-amazon-ebs-volumes/

ただ残念なことに東京リージョンではまだ利用できないので、利用できるようになったらnfsではなくこちらに切り替えたい

# EFSもあり？
検討はしていましたが、料金と速度の問題で外しました。やり方次第かも？
https://aws.amazon.com/jp/blogs/news/optimizing-wordpress-performance-with-amazon-efs/
SAPって？

# はじめに
はじめまして。こんにちは。ブレインパッドで日々データと格闘しています楠です。

ブレインパッドで新しくSAP関連のプロダクトマネージャーになり、四苦八苦しているこの頃、データ分析の会社にいるため、SAP関連の製品の中でもアナリティクス系の製品の調査を行っています。

SAPのプロダクトマネージャーになって、最初に思ったことなのですが、 「なんでSAPのアナリティクス製品にしたの？そもそもSAPってアナリティクスの会社だっけ？」と皆さんの中にも思っている方がいらっしゃるのではないでしょうか。。

SAPの情報を検索しても、どの情報もERPに偏っており、アナリティクスなどその他の情報がきれいにまとまっているところがないので、SAPの特長や製品の強みなど、ここに備忘録的にまとめて、皆さんにご紹介できればと思っています。

お時間ある方はぜひ、この先もご覧ください。

# SAPとは？

SAP とはドイツに本社を置くヨーロッパ最大級のソフトウェア会社です。

世間では **「SAP = ERP」と呼ばれるほど、ERP で成功している会社** です。（だからSAPについて検索しても世間には ERP の情報ばかり溢れているわけです！）

ERPとしては2015年の頃には **市場シェアの6%** を占めており、ERPで有名な **Oracleの2倍のシェア** を誇っています。このシェアも年々伸びております。（Gartnerの発表では2019年もERP分野でリーダーを取っています。）

といろいろ書きましたが、そもそもERPって何。。。？

# ERPとは？

ERPとは **「Enterprise Resource Planning」** の略です。

それぞれの意味は以下の通りです。

* Enterprise    ：全社・全体
* Resource     ：人・金・モノ
* Planning      ：計画・管理

つまり、ERPは全社のリソースを計画・管理することであり、延いてはこれらの「情報」を管理することでもあります。

なるほど。ERPって全社のリソースを管理するためのものなんですね。と言っても正直イメージが。。。

# ERPって具体的には？

イメージが湧くように、メーカー（製造業）の業務に照らし合わせて、ERPの動きを見てみましょう。

メーカー（製造業）の業務は、市場のニーズを把握して、商品を企画・設計して、販売計画と生産計画を立てることから始まります。実際に商品を売り出したのちには、計画をベースにしながら、販売管理、生産管理、在庫管理、会計といった業務を回して、ビジネスが成り立っていきます。

これらの業務を進めるためにERPを用いていくわけです。

しかし、多くのERP製品は、各業務のデータを集計・反映させるのに夜間のバッチ処理で連携させているようなんです。夜間のバッチ処理だと、当日のデータが分からず、次の日の計画を立てたりできなくなってしまいます。

「現在の在庫が分からないから生産計画が立てられない！」「各店舗の在庫が分からないから何個出荷すればいいか分からない！」など、こんな感じで問題がたくさん起きそうです。

つまり、ERPは企業のあらゆる業務データを一元化することで、そうした部門・部署、あるいは業務間の認識のズレを一掃し、経営資源の最適化を促すことを目的にした仕組みと言えます。

それに対して、 **SAPのERPは、リアルタイムを重要視しており、全社的なデータのリアルタイムな同期化によって、全社リソースの最適化計画を支援するのが特長** と言えます。

また、ERP製品というのは一般的に自社用にカスタマイズする企業が多数となっています。

なぜならば、ERP製品というのは前述の通り、業務に直結するシステムになるので、各企業、自社の業務に最適なシステムになるようにカスタムすることが多いわけです。

確かに業務に最適な形になるようにカスタムするのは良いことですが、デメリットも存在あります。

カスタムすればするほど費用も時間もかさみます。また、システムがアップデートしたときにカスタムしすぎていると、従来のアップデート方法が取れず、特別なアップデート依頼を出すこととなり、再度費用も時間もかかってしまいます。

しかし、 **SAPのERPは、世界で利用されているERP製品なので、各業種の課題困りごとを解決するための機能が盛りだくさん** なんです。

これら困りごとを解決するための機能がテンプレートとなって最初から用意されているため、カスタムを最小限に収めることができます。

「SAPのERPは高い」なんて言われることもありますが、カスタムを抑えることで結果トータルコストを抑えられることも多いんです。

# 結局なんでSAPのアナリティクス製品を扱ってるの？

ここまでご説明した通り、「SAP=ERP」という認識はおおむね正しいと言えます。そのため、SAPのウリはというと、**「ERPで培った全社リソースのデータのノウハウが豊富」**というところにつきます。

全社リソースに関するノウハウが豊富なため、これらのデータを簡単に活用できるようにテンプレートが用意されていたり、専門ツールが開発されていたりと、手軽に高品質なものが揃っているわけです。

私たちがSAP製品を取り扱うのもこのノウハウによるものが大きいです。ERPのデータを用いた分析は多岐にわたり、分析の前段階に当たるデータ加工ももちろん必要となってきます。

今回取り扱うことが決まった製品は**「SAP Data Intelligence」**という製品で、データ分析に必要なデータ収集からデータ加工、機械学習モデルの作成、運用管理まで、全てのデータ分析ライフサイクルに対応できる優れた製品です。

やはり顧客の立場になって考えると、「データ分析するにはデータ加工ができるETLツールをまずは導入して、次に機械学習モデルが作れる機械学習ツールを導入して。。。」みたいな形で複数製品の提案はされたくないですよね。

なので、私たちは一つの製品で完結できる「SAP Data Intelligence」を取り扱うことを決めたわけです。

# 最後に

いかがでしょうか？SAPのイメージ伝わりましたか？もしくはイメージ変わりましたか？

「SAP＝ERP」で、テンプレートが豊富、というのが分かりやすいイメージだと思います。全然違うぞ！という方もいると思いますが、一応こういう側面もあるんだなと思って見ていただけると幸いです。

日本では米国に比べIT投資が半分しかされていないと言われています。また、その少ないIT投資も自社のカスタムしすぎた既存システムの維持・運用に割いているところがほとんどです。

他と差をつけるためには「攻めのIT」投資が必要になるので、アナリティクスに取り組みたいという企業も増えていますが、その際はぜひノウハウの詰まったSAP製品にも目を向けてもらえると嬉しいなと思います。

今回はSAPのERP製品の紹介で終わってしまったので、SAPのアナリティクス製品である「SAP Data Intelligence」については、また別記事でご紹介します。

ではでは。
HTML&CSS 1

# ul要素
順序のないリストを示すブロック要素。li要素と組み合わせて使用。

# ol要素
順序のあるリストを示すブロック要素。li要素と組み合わせて使用。

# li要素
リストの項目を示すブロック要素。ul要素、またはol要素の中に記述。

# list-styleプロパティ
リストのスタイルを変更することができる。li要素の箇条書きのマークを変更したりすることができる。

# table要素
表を作成するブロック要素。
この要素と以下に記述するth要素、tr要素、td要素を組み合わせることによって、表構造を作成することができる。

# th要素
表の見出しを作成するブロック要素。

#tr要素
表の横方向の一行を定義するブロック要素。 

#td要素
表のデータを入れるブロック要素。
 
#line-height
行間の高さを指定することができるプロパティ。

# img要素
img要素を使うと、Webサイトで画像を表示させることができる。
画像がどこにあるのかという場所を指定するsrc属性、画像が表示されなかった場合に
代替テキストなどを表示するためのalt属性を指定して使用。
＜img src="どの画像を使用するか" alt="代替えテキスト" class="cssを適用するセレクタ"＞

# text-alignプロパティ
文字の開始位置を指定するときに使用。開始位置の指定はleft(左から)/center(中央)/right(右)の３つ。
初心者レベルでも気づく、JavaとGoのswitch文の記述の違い

# 基本的な`switch`文の記法

```java:Java
switch rank {
    case 1:
        System.out.println("金メダル！");
        break;
    case 2:
        System.out.println("銀メダル！");
        break;
    case 3:
        System.out.println("銅メダル！");
        break;
    default:
        System.out.println("メダルを獲得できませんでした");
        break;
}
```

```go:Go
switch rank {
case 1:
	println("金メダル！")
case 2:
	println("銀メダル！")
case 3:
	println("銅メダル！")
default:
	println("メダルを獲得できませんでした")
}
```

Javaの`switch`文の場合、暗黙的にfall-throughであるため、fall-throughされたくない場合は`break`文を明示的に書く必要があります。

一方、Goの`switch`文は、暗黙的にfall-throughでなく、明示的な`break`文は必要ありません。

# 複数条件のラベルを含む`switch`文

```java:Java
switch n {
    case 0:
        System.out.println("凶です");
        break;
    case 1:
    case 2:
        System.out.println("吉です");
        break;
    case 3:
    case 4:
        System.out.println("中吉です");
        break;
    case 5:
        System.out.println("大吉です");
        break;
}
```

```go:Go
switch n {
case 0:
	println("凶です")
case 1, 2:
	println("吉です")
case 3, 4:
	println("中吉です")
case 5:
	println("大吉です")
}
```

Goの`switch`文では、`case`においてカンマ区切りで複数条件を一度に指定することができます。

一方（JDK11までの）Javaの`switch`文では、「カンマ区切りで複数条件を一度に指定する」という記法は使えません。上記ソースコードのように、fall-throughを使って書く必要があります。

# 結論

同じC-like languagesであっても、特に`switch`文の記法については、言語によって少なからぬ差が出ますね。
VuetifyでRedmineのダッシュボードを作成する時にテーマをこんな感じにすると便利かもというお話

[Vue.js](https://jp.vuejs.org/)と[Vuetify](https://vuetifyjs.com/ja/)を勉強中の8amjpです。

## はじめに

さて、私の職場ではRedmineが稼働してまして、さらにそのデータを見やすく加工したダッシュボードを作成して、大型ディスプレイに表示してるんですけど。
そのダッシュボード、今までは[Angular](https://angular.jp/)で作ってたんですが、Vue.jsも勉強したいしVuetifyでマテリアルデザインを満喫したいし……ということで、現在リプレースの真っ最中です。Vue.jsもたのしー！
その過程で覚えた小ネタをひとつ。

## テーマにカスタムカラーを追加する

Vuetifyとは、Vue.jsベースのフレームワークで、ダッシュボードみたいなWebアプリを作るのに最適なんですけど。
このVuetify、「テーマ」という機能を持っていて、これがRedmineのデータの表示にとても便利なんです。
具体的に言うと……
チケットの一覧なんかを表示する際、チケットのステータスやトラッカーの値によって色を変えたい……ってこと、良くあるじゃないですか。
そんな時、「`tracker1`」とか「`status1`」なんていう名前のカスタムカラーを簡単に追加できます。
こんな感じで、`plugins/vuetify.js`を編集しましょう。

```plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import colors from 'vuetify/lib/util/colors'; // 追加

Vue.use(Vuetify);

export default new Vuetify({
  theme: { // 追加
    themes: {
      light: {
        // トラッカー
        tracker1: colors.red.base, // バグ
        tracker2: colors.amber.base, // 機能
        tracker3: colors.blue.base, // サポート
        // ステータス
        status1: colors.red.accent1, // 新規
        status2: colors.blue.lighten5, // 進行中
        status3: colors.green.lighten5, // 解決
        status4: colors.amber.lighten5, // フィードバック
        status5: colors.grey.lighten1, // 終了
        status6: colors.grey.lighten1, // 対応中
      }
    }
  },
});
```

で、コンポーネント側ではこんな感じでカラーを指定します。

```Hoge.vue
<v-list-item :class="'status'+issue.status.id">
  <v-list-item-title>
    <v-chip dark v-text="'#'+issue.id" :color="'tracker'+issue.tracker.id"/>
    {{issue.subject}}
  </v-list-item-title>
</v-list-item>
```

こんな感じで、ステータスやトラッカーの値に応じた色を簡単に適用できますよ。
今までは似たような事をSassで定義してたんですけど、断然こっちの方が手軽ですねー。とっても便利。
神がこんなゲームを作れと言ったから（夢で見たゲーム画面をモバイルで動くように実装するよ①Bake編）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/7669cbbd-a2e7-c9cd-1777-d996c34f9f11.png)

世の中には個人でストーリー性のある良き良きスマホゲームを作ってらっしゃる人たちがたくさんいますよね。
私もカジュアルじゃないゲーム作りたい・・・・！**力がほしい！**

ドット絵のゲームつくりたいけど画力がたりないし、なんか画面かわいくしたいけどなーなんかいい考え浮かばないかなーお話は考えてるんだけどな。voxelでもいいけど3Dの知識ないし、そもそもモデリングとかボーン組み込みとか大変すぎるしえええーどうしようかなーでもゲーム作りたいしこまっ(ry

**スヤァ**
そんなときにこんな夢を見ました。

![yume3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/bab979c9-b0f5-7175-cfe2-51db216bf197.gif)


エリアがvoxelでできてて、動くものはドット絵で・・・え・・・その発想はなかった・・・・。

**神からゲームを作れと お告げがあった**

わかった。つくるよ。神ありがとう。

# 素材作り

- キャラクターはスプライトアニメーション

- エリアはMagicavoxelで作成してobj形式に書き出し

![yume4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/4180c23c-9d93-5ca9-c5d8-95b06182cb3b.gif)

かわいくないですね。かわいくしていきましょう。

## かわいい画面の絵作りって難しい

まずスマートフォンで動くこと前提で作りたい気持ちがあります。
本職ですし、配信も楽ですしね。（ただ慣れてるだけという話）

絵作りに必要なのは、主にライティングであったり、ポストエフェクトのようなものであったりしますが、これには以下の問題点がそれぞれあるのです。

- ライティング
    - リアルタイムレンダリングの処理負荷が大きい
- ポストエフェクト
    - モバイル非推奨のエフェクトがある

しかし、こういったものを使わねば神から与えられた絵は作れぬ・・・。
ということでそれぞれ調査してみました。


# モバイル負荷を少なくするライティングの調査

リアルタイムで行われる光と影の計算。
そもそも**動かないオブジェクトはリアルタイムで計算する必要がありませんね。**
ゲーム再生する前に計算してしまえばいいのです。

### UnityのBake機能を使う

光と影をオブジェクトに焼いてしまいます。べいく！

①Bake対象のモデルのGenerate Lightmap UVにチェックを入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/8c77bc76-c170-b393-2bc3-b1f50f4914e4.png)


②MeshRendererにてCast ShadowsがON、Receive Shadowsにチェックが入ってることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/f028b284-a5c0-3b17-e68b-08f5c7da8bb6.png)


③対象のライトのModeがMixedになっていることを確認
Mixedにするとベイク対象ではないオブジェクトにはリアルタイムライトとしてふるまわれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/1e8503f4-dca9-378b-82b5-51d0865958e7.png)

④動かない対象のObjをstaticにする
![staticObj.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/a4c0c2e1-c0d4-2cf7-4815-6829036b883d.gif)

するとBakeが始まり、、、、ませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/e13a5ed0-26c3-88af-5453-af89c2b8be38.png)

⑤Lighting設定の以下の設定を確認
Environment LightingのSourceがGradient
Realtime GlobalIllumination がオフ
Auto Generateがオン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/2bb62059-a6d7-7546-a30a-40012710896f.png)

Bakeが始まりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/9305349b-2de6-01ed-997e-1d6960548d72.png)

ライトマップもできています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/57bca12a-14f8-6f4b-d014-d70c0b01cab6.png)




![yume4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/4180c23c-9d93-5ca9-c5d8-95b06182cb3b.gif)

この影、ライトじゃなくてもう焼き付いてるんだぜ・・・。
では、次回は②ポストエフェクト編につづきます。
【GitHub】フォークしたリポジトリを最新に更新する

チーム開発で最初につまずいたので備忘録として・・・
## フォークとは
他ユーザーの公開リポジトリをコピーして自分のGitHub上に新しくリポジトリを作成する事。
自分のリポジトリなので自由にプッシュ・マージなどが行える、またこのコピーしたリポジトリから親（フォーク元）リポジトリへプルリクエストを送る事ができる為、
1. フォークしたリポジトリで作業を行う
2. プルリクエストを親リポジトリへ送る
3. 親リポジトリにてmasterブランチにマージ
という流れで共同開発ができる。
## フォークしたリポジトリを最新に更新する方法
じゃあその更新された親リポジトリをどうやって自分のリポジトリに同期するのか。
今回はターミナル上の操作で更新を行う。
◆作業の流れ
1. 親リポジトリの更新を取得
2. 取得した更新をローカルブランチに反映
3. 更新したローカルブランチをリモートリポジトリにプッシュ

**1. git fetch**
他のリポジトリからデータを取得するコマンド。
まずはこれで親リポジトリのデータを取得するので、
親リポジトリの名前をgit remoteで確認する。（-v オプションでURLも出せる）

```
$ git remote
origin
upstream
```

origin→フォークしたリモートリポジトリ名
upstream→親（フォーク元）のリモートリポジトリ名
フォークした場合親リポジトリ名のデフォルトは`upstream`らしい。

```
git fetch upstream
```

**2. git checkout**
現在のブランチを切り替えるコマンド。
フォークしているローカルのブランチを`master`に切り替える。

```
$ git checkout master
```

**3. git merge**
現在のブランチへ他のブランチの更新を取り込むコマンド。
ローカルの`master`ブランチに親リポジトリの更新を取り込む。

```
$ git merge upstream/master
```

**4. git push**
ローカルブランチの更新をリモートリポジトリに送るコマンド。
最新の状態にしたローカルブランチをフォークしたリモートリポジトリへ送る。

```
$ git push origin master
```

## 最後に
今回初投稿になりますが、今後も気になった事は備忘録としてまとめていきたいと思います。

ちなみに`git fetch upstream`の中身はローカルブランチの`upstream/master`に更新データを保存していて、`git merge upstream/master`でそのブランチを指定して`master`にマージしてるで合ってるはず・・・