OmniAICreator/Qiita-1.07M huggingface dataset:
opencvビルド/windows10


#概要
windows10でopencvをソースビルドする。
# 環境
OS: windows10 pro 64bit
IDE : Visual Studio 2017 Community
OpenCV 3.4.2 -> 3.4.10に変更しました。
　　-> [winpackを使います](https://opencv.org/releases/)
CMake 3.17.1

# パッケージ
winpackのwindowsを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/b78e29e1-91c7-74b0-70db-e42e1d40274b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/a99ad58a-2fcf-5b92-c5a3-c52d8c7a8602.png)


# 参考
https://qiita.com/iwatake2222/items/337dce2148b3d6cee560#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A
[OpenCV 最新版のビルドとインストール，CUDA 対応可能（ソースコードを使用）（Windows 上）
](https://www.kkaneko.jp/tools/win/windows_opencv.html)

# SDKのインストール/ビルド
C:\SDK\opencv342\sourceに置きました。cmakeは右のGroupedチェックで見やすくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/9203939c-8620-99f0-fc73-ad849d4609ee.png)
この画面で64bitを指定する。デフォルトは32bit
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/0fc0e585-5dbd-db8c-54a8-994d49ce6144.png)
# サンプルの実行
サンプルslnが次にできている。
C:\SDK\opencv342\source\samples\bin
⇓
opencv_highgui342.dllが無いと言われる。
⇓
検索するとC:\SDK\opencv342\build\bin\Releaseにある。パスが未通もしくはinstall処理失敗と推測。
⇓
projectの環境フィールドにパスを設定する。
PATH=%PATH%;$(ProjectDir)\xxx

Linux環境のcmake install相当の処理をすれば、解決すると思うが、やり方がわからない。次の場所へコピーするのが正式なやり方だと思う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/a03e3769-776d-ae98-2edc-ace422f40b54.png)

(sample)imageをビルド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/ff86a008-3422-65ce-b953-07fcfa0db6dc.png)

(sample)videocapture_cameraをビルド
事前にUSBカメラ接続しておく。

# CUDAや拡張機能を有効にしてビルド
[arucoが必要になった](https://qiita.com/tangotarou2/items/60fc99af6cb87a7204a1)

#installフォルダ
INSTALLプロジェクトをビルドすると install フォルダが生成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/263c593b-ef9e-f4e1-72d2-d781a8796482.png)
FHS (Filesystem Hierarchy Standard)

#TL;DR
覚えておきたいものだけメモします。
関わりの深いもの順にメモします。

# /bin
システム管理者(root)と一般ユーザーの両方が使う基本的なコマンド
/sbin は、システム管理者(root)が使用するコマンド

# /etc
設定ファイル
システムに関する設定ファイル、アプリケーションに関する設定ファイル

# /tmp
一時的にファイルを保存
再起動すると、ディレクトリ内のファイルは削除される

# /var
一時的にファイルを保存
再起動しても、ディレクトリ内のファイルは削除されない
ログファイルなどが置かれる

# /usr
ユーザー向けのディレクトリで、たくさんのサブディレクトリを持つ
/usr/bin ユーザーが一般的に使用するコマンド
/usr/lib プログラムに必要な共有ライブラリ
/usr/local ローカルシステムで必要とされるコマンドやライブラリ

# /mnt
リムーバブルメディア

# /lib
「/bin」や「/sbin」ディレクトリにあるコマンドを実行するのに必要なライブラリ

# /home
各ユーザーのホームディレクトリ

# /boot
システム起動時に必要なファイル

# /dev
デバイスファイル

# /opt
dpkgでインストールする時に使用する

# /proc
カーネル内部の情報
CPU、メモリの使用状況、ネットワーク情報など
macOSのVSCodeでターミナルを開くときにtmuxが起動してしまう件

# 環境
- ProductName:    Mac OS X Catalina 10.15.4
- Visual Studio Code 1.45.1


# VSCodeのターミナルとtmuxは相性が悪い

私はzshが起動する際にtmuxが自動起動するように設定していますが、VSCodeのターミナル側でも同じようにtmuxが立ち上がってしまいます。
何がいけないかというとtmuxのコマンドが正常に動作しないことと、copymodeに入ってもコピペがうまくいかないことなどが挙げられます。

# 解決法
そこでVSCodeのターミナルで起動した際にはtmuxを自動起動しないように~/.zshrcに記述しました。
以下のコードです。

```Bash
[[ -z "$TMUX" && ! -z "$PS1" && $TERM_PROGRAM != "vscode" ]] && tmux
```

`$TERM_PROGRAM`には現在使用しているターミナルアプリの名称が入ります。
なので`vscode`で開いていた場合にはtmuxが起動しないように記述しています。


# 参考サイト

[macOS で Visual Studio Code を使うためのアレコレ (2020/03/09)](https://qiita.com/satokaz/items/6a6a0d9b6489ec2d1803)
K-means法によるクラスタリングと主成分分析(初心者)


# はじめに
　この記事はpythonのpandasを使ったデータ分析を進める際に有効活用できる、K-means法(データクラスタリング)と主成分分析について記載します。
　クラスタリングを理解するためには、平均、偏差、標準化などの知識を事前に持っておくと良いです。
　【大学4年間の統計学が10時間でざっと学べる】という本の第二章までの知識があればいいと思います。
　あらかじめpandasをpdという名前でimportしてます。


# K-means法とは
　k個のクラスタに分類分けするアルゴリズム


# 主成分分析とは
　次元数を減らす手法
　（3個以上の変数を保持するデータを平面に出力するのは難しいので、次元数を減らすことで平面にわかりやすくプロット可能になる）


# Scikit-learnからK-meansで使うライブラリのimport


```
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
```

# Scikit-learnから主成分分析で使うライブラリのインポート

```
from sklearn.decomposition import PCA
```


# データの標準化
　読み込んだライブラリからfit_transformを使い、標準化を実行

　前提：あらかじめpandasなどで分析対象データを読み込み/編集、以下の変数で作成
　　　　(以下データにはmean, median, max, minなど数値データを格納)
　　　　データ変数名： an_data

```
sc = StandardScaler()
clustering_sc = sc.fit_transform(an_data)
```


# K-meansによるクラスタリング
KMeansのオプションであるrandom_stateに数値を設定すると、次回以降も同じ数値でのオプション指定することで同じ結果が得られる。(デフォルトはrandom_state=Noneであり、毎回違う乱数で処理される)

```
kmeans = KMeans(n_cluster=<クラスタの数>, random_state=0)
clusters = kmeans.fit(clustering_sc)
```

　クラスタリング結果の表への出力

```
an_data["result_clustering"] = clusters.labels_
an_data.head()
```

# 主成分分析

```
hoge = clustering_sc
pca = PCA(n_components=2)  # 二次元平面に出力するため、次元数は2を指定
pca.fit(hoge)
hoge_pca = pca.transform(hoge)
pca_data = pd.DataFrame(hoge_pca)
```

# グラフ出力

　グラフ表示準備

```
import matplotlib as plt
%matplotlib inline         # jupyterでグラフ表示のため
```

　クラスタ化したので、クラスタラベルごとの散布図で出力してみる

```
for i in an_data["result_clustering"].unique():
    tmp = pca_data.loc[pca_data["result_clustering"] == i]
    plt.scatter(tmp[0], tmp[1], label=i)
plt.legend()
```
【自分用学習メモ・備忘録】Git 

###基本用語

共同開発の流れ
__コード変更→共有する準備→共有__

+ git init /initialize（初期化）Gitを使うとき初めに実行する
+ git add 変更のあるファイル名 /共有するファイル選択
+ git commit -m "コミットメッセージ" /メッセージ付きで記録→どんな内容かわかるように
+ git remote add リモート名（大体origin） URL /リモート（共有場所）を登録
+ git push リモート名 master /リモートにファイルをアップロード→__プッシュ__という！
+ git pull リモート名 master /リモートからファイルをダウンロード→__プル__という！
***

+ git status /自分が変更したファイルのファイル名を表示 （__addされたものは緑色、されてないものは赤色の文字色__）
+ git diff /変更内容を見る　（__変更前は赤色、変更後は緑色の文字色__）
+ git log /自分や他人のコミットを確認できる
+ git log -p /自分や他人の変更内容がみれる


__その他__

+ git log -pを実行した際、表示内容が多いときは上下キーで表示範囲変更、Qキーで終了
ギリシャ文字

### 読み方

| 大文字 | 小文字 | 英表記   | 読み・カナ表記         |
|--------|--------|----------|------------------------|
| Α      | α      | alpha    | アルファ               |
| Β      | β      | beta     | ベータ                 |
| Γ      | γ      | gamma    | ガンマ                 |
| Δ      | δ      | delta    | デルタ                 |
| Ε      | ε      | epsilon  | エプシロン/イプシロン  |
| Ζ      | ζ      | zeta     | ゼータ                 |
| Η      | η      | eta      | エータ/イータ          |
| Θ      | θ      | theta    | テータ/シータ          |
| Ι      | ι      | iota     | イオータ/イオタ        |
| Κ      | κ      | kappa    | カッパ                 |
| Λ      | λ      | lambda   | ラムダ                 |
| Μ      | μ      | mu       | ミュー                 |
| Ν      | ν      | nu       | ニュー                 |
| Ξ      | ξ      | xi       | クスィー/クサイ/グザイ |
| Ο      | ο      | omicron  | オミクロン             |
| Π      | π      | pi       | ピー/パイ              |
| Ρ      | ρ      | rho      | ロー                   |
| Σ      | σ      | sigma    | シグマ                 |
| Τ      | τ      | tau      | タウ                   |
| Υ      | υ      | upsilon  | ウプシロン/ユプシロン  |
| Φ      | φ      | phi      | フィー/ファイ          |
| Χ      | χ      | chi      | キー/カイ              |
| Ψ      | ψ      | psi      | プスィー/プサイ        |
| Ω      | ω      | omega    | オメガ                 |



### 書き方

https://www.youtube.com/watch?v=JgRYrzc8cFg
連想配列から配列の値と一致する要素を抽出

# やりたいこと
JavaScriptで連想配列のキーと配列の値を照らし合わせて、検索結果が一致する要素を連想配列から抽出。

# サンプルコード

Ajaxなどで取得したjsonを格納した連想配列（オブジェクトデータ）から、必要なデータのみ抽出して処理したい場合などで遭遇するパターン。

## for…of パターン
```javascript:JavaScript
// 連想配列
var fruits = {
	"みかん":{"price":"200", "num":"5"},
	"いちご":{"price":"400", "num":"1"},
	"ぶどう":{"price":"380", "num":"7"}
}

// 配列（検索ワード）
var target = ['みかん', 'ぶどう'];


var result = {};
for(var key of Object.keys(fruits)){
    // 連想配列のキーと配列の値が一致するか検索
    for(var i of target){
        if(key == i){
            result[key] = fruits[key]; // 連想配列に格納
            break;
        }
    }
}

console.log(result);
```

```:console.log
{
  ぶどう: {price: "380", num: "7"}
  みかん: {price: "200", num: "5"}
}
```


連想配列（object）のキー（プロパティ）取得は、`Object.keys()`を使うと便利です。

```javascript:JavaScript

// 連想配列（object）のキー（プロパティ）取得
Object.keys(連想配列名)

// Object.keysを使って、要素数をカウントすることもできる
var length = Object.keys(fruits).length;
```


連想配列（object）には`.push()`メソッドで追加できないので、以下のようにします。

```javascript:JavaScript
arr[キー文字列] = 値; //新規キーと値をセット
```


## for…in パターン
```javascript:JavaScript
// 連想配列
var fruits = {
	"みかん":{"price":"200", "num":"5"},
	"いちご":{"price":"400", "num":"1"},
	"ぶどう":{"price":"380", "num":"7"}
}

// 配列（検索ワード）
var target = ['みかん', 'ぶどう'];


var result = {};
for(key in fruits){
	// 連想配列のキーと配列の値が一致するか検索
	for(i in target){
		if(key == target[i]){
			result[key] = fruits[key]; // 連想配列に格納
			break;
		}
	}
}

console.log(result);
```
IEは`for…of`に非対応のため、`for…in`を使います。（polyfillを使用しない場合）


## .filter()パターン
```javascript:JavaScript
// 連想配列
var fruits = {
    "みかん":{"price":"200", "num":"5"},
    "いちご":{"price":"400", "num":"1"},
    "ぶどう":{"price":"380", "num":"7"}
}

// 配列（検索ワード）
var target = ['みかん', 'ぶどう'];


var result = {};
for(key in fruits){
	target.filter(function(data){
		if(key == data){
			result[key] = fruits[key];
		}
	})
}

console.log(result);
```
ちょっと強引な気もしますが、`for…in`内を.filter()で書いたパターン。結果は同じです。

# 参考
[https://www.sejuku.net/blog/27965](https://www.sejuku.net/blog/27965)
開発準備 git

# GitHub 接続
`commit` して `push` するまで

1. GitHub 登録
2. SSH 公開鍵 作成
3. GitHub 公開鍵 登録
4. gitリポジトリ 登録
5. .gitconfig 設定
6. git 初期化
7. (merge &) commit & push

## 1. GitHub 登録
いわずもがな、省略。

## 2. SSH 公開鍵 作成
https://qiita.com/shizuma/items/2b2f873a0034839e47ce を参考に作業
（引用）

```
$cd ~/.ssh
$ssh-keygen -t rsa
```
問いかけられるけど3回Enterを押してスルーすると鍵を生成完了

## 3. GitHubに公開鍵を登録
- 「https://github.com/settings/keys」
- 「title」に公開鍵名 `id_rsa.pub` 、「key」に公開鍵の中身を入れる
-  中身はメモ帳で開いてコピペでOK

接続確認！

```
$ ssh -T git@github.com
Hi YKHSJP! You've successfully authenticated, but GitHub does not provide shell access.
```
OK!

## 4. gitリポジトリ 登録
リポジトリのディレクトリに移動して

```
$ git remote set-url origin git@github.com:YKHSJP/study.git
```
と登録（`:YKHSJP/study.git` は自身の値）

`config` を確認する

```
$ git config remote.origin.url
git@github.com:YKHSJP/study.git // OK
```

## 5. `.gitconfig` 設定

```
cd ~/
```

.gitconfig

```
[user]
	name = {last name} {family name}
	email = {email}
```

## 6. git 初期化

ディレクトリに移動して

```
$ git init
Initialized empty Git repository in C:{path}.git
```

## 7. (merge &) commit & push
とても詰まった所。
push ができない問題。
解決してくれたのはやはり他Qiitaページでした。本当感謝。
https://qiita.com/takanatsu/items/fc89de9bd11148da1438

```
$ git merge --allow-unrelated-histories origin/master
Not committing merge; use 'git commit' to complete the merge.
$ git commit -m "first commit"
[master c16f5ca] first commit
$ git push origin master
```
やっと push 完了！😿
array of objectsを表現するswagger記法

OpenAPI v3におけるYAMLの記法です。


yaml

```yaml
results:
  type: array
  items:
    type: object
    properties:
      AA:
        type: string
      BB:
        type: string
      CC:
        type: string
      DD:
        type: string
      EE:
        type: string
  example:
    - AA: aa
      BB: bb
      CC: cc
      DD: dd
      EE: ee
    - AA: aa
      DD: dd
      EE: ee
    - AA: aa
      BB: bb
      CC: cc
```

出力

```json
{
  "results": [
    {
      "AA": "aa",
      "BB": "bb",
      "CC": "cc",
      "DD": "dd",
      "EE": "ee"
    },
    {
      "AA": "aa",
      "DD": "dd",
      "EE": "ee"
    },
    {
      "AA": "aa",
      "BB": "bb",
      "CC": "cc"
    }
  ]
}
```

exampleで指定されていない値はkeyごとskipされるようになります
Edgeさんにやられた話

OK、簡潔に。

browserslistで「last 2 versions」とか「last 1 versions」をやってる環境。
Windows側のEdgeに対応できてないかもしれないから気をつけてね！
(2020/05/26現在)

```
❯❯❯ npx browserslist 'last 2 versions, not dead'
...
chrome 80
edge 81
edge 80
firefox 75
...

❯❯❯ npx browserslist 'last 5 versions, not dead'
...
chrome 77
edge 81
edge 80
edge 79
edge 18 //この辺がnot Chromium
edge 17 //この辺がnot Chromium
firefox 75
```

Windows版Chromium Edgeはリリース済だけど、WinUpdateにまだ入ってないので、大半のWindowsに入っているEdgeはEdgeHTML版と思われます。

検索したときにこの情報は出てこなかったのでとりあえず。
何か間違ってたらごめんね！(少なくとも当方はこれで解決)
lamdaを使ってslackに通知する　覚書

## コンタクトページの内容をslackに通知させたい
静的サイトのコンタクトページをslackに通知させたいという話しです。
最初のwebhookとかの設定は既にやっていたので、あとはlamdaで関数を作成して、apiゲートウェイを設定していきました。

## lambda で関数を作る
lambda の画面で関数を作成ボタンを押すと関数が作成できます。
下の方にエディタの画面がでてくるので、そこに入力していきます。

こんな感じで作成しました。

```js:index.js

const https = require('https');

exports.handler = (event, context, callback) => {
  const payload = JSON.stringify({
    text: `\n\n会社名： ${event.company}\n 所在地： ${event.address}\n 担当者： ${event.name}\n メールアドレス： ${event.email}}`,
  });

  const options = {
    hostname: "****.****.com",
    method: "POST",
    path: "/services/*******/*******",
  };
  
  const req = https.request(options,
      (res) => res.on("data", () => callback(null, "OK")))
  req.on("error", (error) => callback(JSON.stringify(error)));
  req.write(payload);
  req.end();
}

```

`export.handler`とは:handlerはイベントを処理する lambda 関数内のメソッド。関数を呼び出すとメソッドが実行され、レスポンスが返ってきたら、別の処理をするようになる。
export.handlerの引数について、ハンドラーの引数は全部で三つあります。
1. event :最初の引数は呼び出し元からの情報を含むeventオブジェクトです。
2. context :
3. callback :
`callback`とは
`res.on`はdataを指定して使用することで、パース処理を開始している。
`req.write`とは：サーバ側へHTTPリクエストのボディデータは送信されます。
SwiftUIでNaivigationViewが重なったら

##起きたこと
NavigationViewが重なっちゃった！
<img width="200" alt="スクリーンショット 2020-05-26 13.41.42.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/1197501b-edf3-b5f8-c857-b6d3d7c3942c.jpeg">

##原因と対処法
NavigationViewが複数存在していることが原因です。
はじめのViewにのみNavigationView{}で囲むようにしましょう。

##ソースコード

```swift
import SwiftUI

struct test12: View {
    var body: some View {
        NavigationView{   //これだけでいい
            NavigationLink(destination: test13()){
        Text("Hello, World!")
            }
        }
    }
}

struct test13: View {
    var body: some View {
        NavigationView {   //これはいらない
        NavigationLink(destination: test14()) {
        Text(/"Hello, World!")
        }
        }
    }
}
struct test14: View {
    var body: some View {
        
            
        Text("Hello, World!")
        
    }
}
struct test12_Previews: PreviewProvider {
    static var previews: some View {
        test12()
    }
}

```
ターミナルでssh接続したときの文字化け対策

.bash_profile
に

export LANG="ja_JP.UTF-8"
を追加

```
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH

export LANG="ja_JP.UTF-8"                              
```
[個人メモ]いまさらbashの自動補完

# 概要

Linuxのコマンドが長くなると入力するのがめんどくさくなり、効率が悪い
なので、いまさらだがコマンドの自動補完の設定手順を残す

# 導入方法

1. bash-completionをインストール

    ```shell
    > yum install -y bash-completion
    ```
2. ロード＆確認

    ```shell
    > source /usr/share/bash-completion/bash_completion
    
    # エラーがなければOK
    > type _init_completion
    ```
3. 例としてyumコマンドの入力補完設定

    ```shell
    > source /usr/share/bash-completion/completions/yum
    
    # yum入力後にtabキーで以下の様に入力補完が表示されればOK
    > yum 
      check  deplist  groups  info  load-transaction  reinstall  search  upgrade
      check-update   distro-sync   help   install  makecache   remove   shell  version
      clean   downgrade   history    list   provides     repolist   update 
    ```
   ※`/usr/share/bash-completion/completions/`配下に様々な入力補完用のスクリプトが導入されるので、必要に合わせてロードしてください。

4. `/usr/share/bash-completion/completions/`にない場合は？
   モノによってはコマンドにビルドインしているものもあります。例えば、kubectlの場合は`kubectl completion bash`で補完機能を提供しています。またdocker-composeの場合は、[こちらの手順](https://docs.docker.com/compose/completion/)に従って自動補完スクリプトを導入し、同じようにロードすればOK。なので補完したいものを探してロードしてあげてください。

5. 自動ロード登録

   ```shell
    > echo 'source /usr/share/bash-completion/bash_completion' >> ~/.bashrc
    > echo 'source /usr/share/bash-completion/yum' >> ~/.bashrc
   ```
 

# _get_comp_words_by_ref command not foundが表示されたら

以下の2つを試す

#### bash_completionがロードされていない

上記の「2. ロード＆確認」を実行

#### bash_completionがインストールされていない

パッケージマネージャーからbash-completionをインストール

上記の「1. bash-completionをインストール」を実行
```
初心者でもAWSプロダクトをさわってみたい！（AWS Batch編）

<img width="1645" alt="スクリーンショット 2020-05-26 13.21.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/653e7c31-6e0e-8506-2c02-cbebcc8f2ed7.png">
![スクリーンショット 2020-05-26 13.21.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/bb51103e-c2ca-20dd-fdf9-52723fffdfa3.png)
![スクリーンショット 2020-05-26 13.21.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/b9baffda-8248-a8dd-e4ed-6e777297cadb.png)
![スクリーンショット 2020-05-26 13.22.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/20d44f65-290d-beea-7718-add00175b068.png)
![スクリーンショット 2020-05-26 13.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/4a3a5e27-27c0-1a2b-8859-513982e612c3.png)
![スクリーンショット 2020-05-26 13.22.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/3acce83e-85fb-e1e2-4cdd-1a68d4a83c27.png)
![スクリーンショット 2020-05-26 13.22.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/2a38efdd-181e-97dd-728f-169ec0ee48eb.png)
![スクリーンショット 2020-05-26 13.22.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/880141ad-e73b-2a7c-5bdd-22995d9cf8ac.png)
![スクリーンショット 2020-05-26 13.22.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/09382993-dfd9-b84a-3458-6eb2160e3d03.png)
![スクリーンショット 2020-05-26 13.22.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/ddbeed80-1be3-9033-d278-0740b331e84f.png)
![スクリーンショット 2020-05-26 13.23.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/e69e326d-a0cb-e207-09d8-44c1a714a8c9.png)
![スクリーンショット 2020-05-26 13.23.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630283/5a41790e-9507-39ca-322c-bf33cb281fef.png)
###今回はecho投げるだけでしたが、、、もっと深くAWS Batchを知る＆他リソース連携の確認がしたいですね###
Microsoft Azure【 Azure Active Directory 】のデフォルト（xxxxx.onmicrosoft.com）から、自分が契約しているドメイン名を「プライマリ」として切り替えC#からAzure SQL Databaseへドメインユーザ名で接続する

## Azure Active Directory ポータルを使用してカスタム ドメイン名を追加する

【参考】https://docs.microsoft.com/ja-jp/azure/active-directory/fundamentals/add-custom-domain

Microsoft Azureで【 Azure Active Directory 】を使用しデフォルトのxxxxx.onmicrosoft.comから、自分が契約しているドメイン「kuhen.net」を【カスタムドメイン名】項目から追加し「プライマリ」として切り替えてみた。

現在使用している Azure【SQL Database】の認証で　「SQLパスワード認証」の他に　→　**Azure Active Directory(Azure AD)パスワード認証**も追加して使用したかったからである。
　
自分のドメインを「プライマリ」にするには、ドメイン追加のボタンを押した後、Azureの画面に表示された、DNSレコード追加用の「TXT」データ内容を、自分のドメインの（レンタルサーバ等の）DNS管理画面で手動追加する。

Azure AD が表示したキーワードと同じキーワードをDNSレコードに書き込めるのは
→そのドメインの【所有者（管理者）】だけだから。というよくある認証方法。

これで　**kuhen.net**　ドメインをプライマリとして追加出来た。
![カスタムドメイン.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567414/7540cfea-b8df-d1c2-16e7-68e472fa3ea7.jpeg)


## Azure ポータル画面の　Azure Active Directory で新規ユーザーを追加する

追加するユーザー：　foo@kuhen.net

ユーザーを作成すると、仮パスワードが登録されるので**必ず仮パスワードはメモしておくこと**。


作成したfoo@kuhen.netで→　Azureポータルにログインし、仮パスワードを入力後、本パスワードを設定しサインアウト。


次にパソコンから　SQL Server Management Studio (SSMS)  を起動し
Azure SQL Database の管理権限ユーザーでログインする。

【SSMSダウンロード先】https://docs.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-2017


【参考】https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-manage-logins

Azure SQL Database に、一般ユーザー（db_owner権限を付加）を追加するには

ユーザを作成したいデータベース名に移動してマウス右→新しいクエリ


CREATE USER [foo@kuhen.net] FROM EXTERNAL PROVIDER;
ALTER ROLE db_owner ADD MEMBER [foo@kuhen.net] ;
SELECT * FROM sys.sql_logins;
SELECT * FROM sys.databases;


上記4行（作成と確認）を実行する。

もちろん foo@kuhen.net の部分は自分の作成したいユーザー名@ドメイン名に置き換えること


SQLデータベース　→　使用するデータベース　→　接続文字列　→　ADO.NET (Active Directory パスワード認証)
でC#から使う接続文字を確認する。
デフォルトで接続は暗号化がONになっている。

それとファイアーウオールの設定で「接続許可IP」に自分の使用するIP指定しとかないと接続出来ないのでご注意を。

■ハマッタこと
Azure ADで作成したユーザーは、パスワードが合っていても「failed」になります。SQL Server Management Studio (SSMS) からデーターベースの中には入れないが「データーベース」には与えられた権限でアクセスできます。
最初は「なんで入れないんだろう？」と四苦八苦しました。

■組織のパスワード有効期限ポリシーを設定（ご注意：パスワードを「無期限」に設定する時は自己責任で）
https://docs.microsoft.com/ja-jp/microsoft-365/admin/manage/set-password-expiration-policy?view=o365-worldwide

■最後に
他のサイトに投稿した記事（１年より前の情報）に手を加えてQiitaに投稿しました。
プログラムの知識や能力は「趣味レベル」な老人ですので何か間違いがあればご指摘ください。

以上
Lambdaまとめ

# 概要
触る機会があったので、知ったことをまとめていく。

# Lambdaとは
AWSサービスのイベントをトリガーに自身がアップロードしたコードを動作させることができるというサービス

# 料金
料金は月額であり、「lambdaへのリクエスト数」と「lambdaを動かすときに消費したメモリサイズ(時間計算)」で計算される。

料金表はあらかじめ確保するメモリサイズに依存する

# 言語
コーディングできる言語は多岐にわたるが、**「継続的なアクセスがなくCPUもそんなに使わない」のであれば「python」がいい**らしい

# ライブラリ
Python3でAWS環境を操作するには、boto3と呼ばれるライブラリが必要。

# 一時ディレクトリ
/tmpという一時ディレクトリがある。ファイルの受け渡しをしたいときとかに使う。
なお、同じファイル名を使うと、前の実行時のものが残っていてなおかつユーザー名が違っていてパーミッションエラーというのが起こりうるらしいので、毎回使い終わったらファイルを削除するのがいいらしい。

# 環境変数
lamdaに設定できる。
pythonだと、``import os``を宣言した上で、``os.envion['<環境変数名>']``で呼び出せる。

# タイムアウト
処理のタイムアウトはMAX15分。
python3.8だとデフォルトで3秒らしい。


# ロール
lambda関数にはIAMロールを設定する必要があるが、トリガーとなるAWSサービスへのアクセス権限は不要。イベントを受けてコード上でアクセスするAWSサービスへのアクセス権限が必要。

# 使い方
参考：https://dev.classmethod.jp/articles/lambda-my-first-step/

## Lambda関数の新規作成
### 空の関数作成
Lamdaのコンソールへアクセス > 「関数の作成」ボタンを押下
→「関数の作成」ページが表示される
![スクリーンショット 2020-05-29 20.48.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/2398d13e-c534-7e38-9b4d-2647175bf293.png)


 「一から作成」を選択 > 「基本的な情報」セクションで「関数名」(=目的)を入力し、「ランタイム」(=言語)を選択 > 「アクセス権限 - 実行ロール」で「AWSポリシーテンプレートから新しいロールを作成」を選択 > 「ロール名」に任意のロール名を設定 > ポリシーテンプレートは未選択で「関数の作成」ボタンを押下
![スクリーンショット 2020-05-29 20.49.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/1b70a93c-2d72-ab65-37ee-337225b37d06.png)
→「Lamda関数設定」ページが表示される
![スクリーンショット 2020-05-29 20.51.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/c6a5da51-652b-a19b-7e6b-73c9ad9a1b1d.png)


### Lambda関数に設定を追加
「Lambda関数設定ページ」でそれぞれ実施。

#### トリガーの設定
「トリガーを追加」を押下
→「トリガーを追加」ページが表示される
![スクリーンショット 2020-05-29 20.53.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/56980df4-c45e-2a3b-01d1-a09446e0608f.png)

Lambda関数を起動するトリガーとなるAWSサービスを選択し、トリガーとなる条件を設定して「追加」ボタンを押下

#### 実行するコードの設定
Lambda関数名を押下 > 下のコード編集領域へ実行するコードを記述し、画面右上の「保存」を押下

## ロール
新規作成時に空っぽ(CloudWatch Logへの書き込み権限があるポリシーのみアタッチされている)のロールを作って当該Lambda関数へアタッチしている。
なので、IAMコンソールから空っぽのロールに対してlambda関数が操作する対象のAWSサービスへのアクセス権限を持つポリシーをアタッチしてやる。

「アクセス権限」タブを選択 > ロール名のリンクを押下 > 「ポリシーをアタッチします」ボタンを押下 > lambda関数を実行するために必要なポリシーを選択 > 「ポリシーのアタッチ」を押下

付与されたアクセス権限の確認はlambdaコンソールの「アクセス権限」タブを選択 > リソースの概要のドロップダウンで操作対象のAWSサービスが選択できるようになっており、選択すると操作可能なsリソース、アクションが確認できる。

## 環境変数
環境変数セクションの「編集」から設定できる。

## メモリ上限、タイムアウト値
基本設定セクションの「編集」から設定できる。

# テスト
## テストイベントの作成
画面右上の「テスト」ボタンを押下 > 新しいテストイベントの作成を選択 > イベントテンプレートから任意のイベントを選択 > イベント名を任意で設定して「保存」を押下

## テストの実行
画面右上の「テスト」ボタンの横にあるドロップダウンで作成したテストイベントを選択し、「テスト」ボタンを押下

# 実行確認
ちゃんとトリガーに引っかかってlambda関数が反応していればCloudWatchで確認できる。

- ロググループ名:/aws/lambda/<lambda関数名>

```

# 参考
https://qiita.com/leomaro7/items/5b56ae9710d236545497
http://acro-engineer.hatenablog.com/entry/2016/08/02/120000
環境構築とはなにか、できるだけ簡単に説明してみる

### この記事はこんな人向け
- プログラミング初学者
- ネットで調べたコマンドのコピペで環境構築をすませて、実際に自分が何を行ったのか理解していない人
- terminalで python hoge.py のようなコードを叩いた際に、 裏側で何が行われているのか気になる人

## はじめに
プログラミングを勉強する上では避けては通れないのが環境構築作業です。
Progateなど環境構築不要で学べるサイトはたくさんありますが、将来的に自分のローカル環境で開発するためには必ず必要になります。

今回は初学者がよく詰まりがちな環境構築とは何かをできるだけ簡単にして説明したいと思います。

## まず前提知識として
私たちはC言語やJavaScript、Ruby、Pythonなど様々なプログラミング言語でコードを書いています。
しかしあれらの言語は人間に読みやすように設計された言語であり、コンピュータは理解することができません。
コンピュータが理解できるのは、***「0」と「1」で書かれた「機械語」***と呼ばれるものです。
つまり、人間が書いたコードをコンピュータに実行してもらうためには, ***プログラミング言語から機械語へ変換する***ことが必要なのです。

この変換プロセスには***「コンパイラ」***あるいは***「インタプリタ」***と呼ばれる「翻訳の役割を担うソフトウェア」が必要になります。
またこれらのソフトウェアは基本的に言語ごとに専用のものが必要になります。

[インタプリタとコンパイルについて](https://jpazamu.com/interpreter-compiler/)

## python hoge.py が意味すること
```
python hoge.py
```
というコマンドは、python 用のインタプリタ(pythonはインタプリタ型であるため)に hoge.pyというソースコードを渡し、機械語(正確にはpythonの場合はいったん中間言語へ変換される)へ変換、実行してもらうことを表しているのです。
こう考えると凄くシンプルですね。

## 環境構築とはなにか
プログラミング言語を学ぶ上での環境構築とは、上記で説明した機械語への変換に必要なもろもろの道具を自分のPC上に落としてきて、使えるようする作業と言えます。

以下によくある環境構築のコマンド例を上げてみます
内容は適当なものなので、これらを実行するのは避けてください
(例はpythonになっていますが、 他の言語でも基本的に同じです)

```
brew install python
export PATH="/usr/local/var/:$PATH"
echo 'export PATH="/usr/local/var/:$PATH"' >> ~/.bash_profile
```

一行目の```brew install python```というコマンドは、インタプリタを自分のPC上にインストールする作業になります。(ここではhomebrewをつかってinstallしていますが、サイトなどから落としてきても問題有りません)
この作業だけで環境構築が完了する気もしますが、殆どの場合このままでは動きません。

***なぜならPCがインタプリタの場所を知らないからです***。

terminalなどからコマンドが実行された際、PCはPATHと呼ばれる予め設定されたディレクトリ(フォルダ)郡の中を探索し、コマンドで指定されたファイルの存在チェックを行います。
新しくインストールされたファイルはたいていPATHの中に含まれていないため、PCが見つけることができず、```command not found``` のようなエラーを吐くことになります。

そこで必要になってくるのが```export PATH="/usr/local/var/:$PATH"```のコマンドです。
こちらはPATHに新しく落としてきたファイルの在処を教えてあげる(PATHに追加する)プロセスになります。

ここで気をつけてほしいのは***ちゃんとファイルが存在する場所をPATHに追加する***　ということです。
大抵他の人のコマンドを真似していればうまくいくのですが、環境によっては参考にした人とは異なる場所にファイルがインストールされている可能性もあります。
もしコピペでうまく行かない場合は、PATHが異なっている可能性を考慮しましょう。

インストールされたファイルの場所を知るためにはwhichコマンドを使用しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477617/56a4614b-ffb0-1e7c-0e26-a4d71500a14b.png)
このコマンドの結果から、```/user/local/var/pyenv/shims/```配下にpythonのインタプリタがおいてあることがわかります。
この場合正しいPATHの教え方は```export PATH="/user/local/var/pyenv/shims/:$PATH```のようになります。

最後の```echo 'export PATH="/usr/local/var/:$PATH"' >> ~/.bash_profile```
こちらのコマンドですが、これはホームディレクトリにある.bash_profile というファイルに```export PATH="/usr/local/var/:$PATH"```という一行を書き加えることを表しています。

***PATHはterminalなどの実行環境を立ち上げた際に初期化されます。***
そのため```export PATH="/user/local/var/pyenv/shims/:$PATH```で加えたPATHは、実行環境を閉じてしまうと追加したPATHが消えてしまうのです。

実行環境を立ち上げるたびにPATHを追加するのは煩わしいということで、3行目のコマンドを実行しています。
※***実行環境を立ち上げると、最初に.bash_profile中に書かれたlinuxコマンド郡が実行されます。***
これにより、人力で追加しなくてもPATHが追加されるようになります。

※正確にはデフォルトに設定されているshellの設定ファイルが実行されます。
[shellとは](https://orizuru.io/blog/os/shell/)

## まとめ
新しい言語を学ぶ際に行う環境構築とは、
***1. ソースコードをCPUが処理できる機械語に翻訳するために必要な道具をPC上に落としてきて***
***2. その道具の在処をPCに教えてあげる***
この２つの作業のことである

実はみなさんがよくやっているであろうライブラリのインストールやimportも上記と同じような仕組みなのです。
必要なファイルを落としてきてその場所を教えてあげる、コレがサードパーティーのコードを利用する際の基本となります。

もし理解できない点や、コレは間違っているよ　という内容があればご指摘いただけると幸いです！
[twitter](https://twitter.com/buebue4632)でもこちらでも気軽に声をかけていただけると！
よく使うgitコマンド

# gitコマンド
## branch関係
`git checkout -b ブランチ名`
新規ブランチを作成

`git checkout ブランチ名`
指定ブランチに切り替え

`git branch -D ブランチ名`
指定ブランチ削除

`git branch -m ブランチ名旧 ブランチ名新`
ブランチ名の変更

`git reset --hard HEAD`
現ブランチの編集履歴削除

`git checkout . `
現ブランチを優先

`git rebase ブランチ名`
処理を作り直す
既存のコミットへ影響を与える
## add関係
`git add -u`
既存ファイルのみadd+上位ディレクトリにも対応する
## commit関係 
`git commit -u` 
既存ファイルのみコミット+上位ディレクトリにも対応する
## merge関係
`git merge --no-ff ブランチ名`
差分をマージ
fast-forwardしないのでマージコミットされて分岐の履歴が残る

`git reset --hard HEAD` 
merge取り消し
指定されたコミットの時点に戻り、それ以降の変更を全て破棄


`git fetch`
リモート・リポジトリなど他のリポジトリのデータを取得するもの
サーバーとの同期
【自分用学習メモ・備忘録】Command Line(Unixコマンド)

### 基本的なコマンド
__（※〇〇 = ファイル名、dir = ディレクトリ）__

+ touch 〇〇 /空のファイル作成
+ cat 〇〇 /ファイルの中身を表示
+ mkdir dir名 /make directory ディレクトリ作成
+ pwd /print working directory 現在作業中のディレクトリ確認（階層が全て表示される）
+ ls /dirの中身を見る（基本的に1つ子の階層のみ）
+ cp コピーする〇〇 新しい〇〇 /copy ファイルのコピー
+ cp -r コピーするdir名 新しいdir名 /ディレクトリのコピー
+ rm 〇〇 /remove ファイル削除
+ rm -r dir名 /ディレクトリ削除 

__移動系__

+ cd dir名 /change directory 指定したディレクトリへ移動
+ cd .. /一つ親のディレクトリへ移動
+ cd /ホームディレクトリへ移動

__mvいろいろ__

+ mv 〇〇 dir名 /move 指定したディレクトリへファイル移動
+ mv dir名　移動先dir名 /ディレクトリごと指定ディレクトリへ移動
+ mv 〇〇　新しい〇〇/ファイル名変更




### その他用語

+ カレントディレクトリ =今いる場所
+ ルートディレクトリ =1番親の階層
+ ホームディレクトリ =ユーザーが作業するときに起点にするディレクトリ
+ ↑で前に実行したコマンドが入力できる
【初心者向けハンズオン】WindowsにDockerでPHP/MySQL/Apache環境構築（第2回：PHP動かすところまで）

# 概要

　前回の記事はこちら：

　新人もベテランも本当にエンジニアによくある、「開発環境建てるのめんどくさい問題」を解決する糸口を模索していました。そこで行き当たったWindows環境でDockerを使って開発出来るようにする、という着地に対してアプローチしていくハンズオンです。
　1回1時間程度の作業時間でやるルールにして、記事は細切れに書いて行くスタイル。あと参考にさせていただいた記事はこちらです。
　※https://qiita.com/hirosnow/items/cbe2a90ba1c6921fea1a

# 目標
* PHP/MySQL/Apacheで古き良きWEBアプリケーションの開発環境を作る
* つくった開発環境を他の人に配布できるようにする
* ↑の「配布された人が簡単に開発環境を作れる手順をまとめる」ところまでがゴール

では行ってみましょう。

# 本日の作業内容
## 作業ディレクトリの作成
参考にした記事に従って、「C:\Users\あなたのPCのユーザー名\home」というディレクトリを作成しました。
※参考との相違点①：「\work」になっているところを「\home」い変えました（好み）

> home/
　├ html/
　│　└ index.php
　├ mysql/
　├ php/
　│　└ php.ini
　└ docker-compose.yml

## 設置したファイルの記述
ちなみにここに来て大変今更ですが「Dockerってなんや」「Dockerfile？docker-compose.yml？」あたりでそもそも理解に躓いたタイミングがあり、その解消になったyoutube動画を転載させていただきます。
https://www.youtube.com/watch?v=VIzLh4BgKck

記述したdocker-compose.yml

```
version: '3'

services:
  php:
    image: php:7.2-apache
    volumes:
      - ./php/php.ini:/usr/local/etc/php/php.ini
      - ./html:/var/www/html
    ports:
      - 32778:80
  mysql:
    image: mysql:5.7
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test
      MYSQL_USER: test
      MYSQL_PASSWORD: test
    command: --innodb-use-native-aio=0
    ports:
      - "32780:3306"
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_ARBITRARY: 1
      PMA_HOST: mysql
      PMA_USER: test
      PMA_PASSWORD: test
    restart: always
    links:
      - mysql:mysql
    ports:
      - '32779:80'
```

記述したphp.ini（ホントはxamppでもともと使ってたやつを入れたんですが、恥ずかしいのでこちらの記述で）

```
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
```

記述したindex.php（ここは別になんでもいいと思う）

```
<?php
    phpinfo();

```

## いざ、起動
該当フォルダに移動

```
cd （docekr-compose.ymlのあるディレクトリ）
```

いざ、起動

```
docker-compose up -d
```

## 接続してみる
「http://127.0.0.1:32778/」

おお、すごい。来てる。簡単。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/1d9ae681-cf7a-f9c7-b304-7f05fb88f6ea.png)

# 終わり。
コマンド一発は超絶楽ですね。
どこにいても同じ開発環境にしよう（VSCode）

# 読む前に
VSCodeの使用者、これから使用する人に向けた記事です。ただ、コマンドなども一切使うことなくできるので、読む分には簡単でやってみようと思えます。
ここでは、その手順の理由などは示さない。

# 私事
VSCodeに一本化しようと思って、VSCodeを持ち歩くことにした。大きなpcではg-tuneのノートpc、surface go(タブレットpc)を二つ持ち歩くのは肩などにも負担が大きい。そこで、開発環境の統合と同じ開発環境で作業のためにこの方法をやってみた。

# VSCodeの各ページ
・VSCodeのホーム
https://code.visualstudio.com/
・VSCodeダウンロード
https://code.visualstudio.com/Download
・VScodeドキュメント
https://code.visualstudio.com/docs

# 用意するもの
・USBメモリ(ある程度の容量)
(私は1000GBのUSBメモリを使用。16GBとかでも全然良い)
・VSCodeを開くWindows端末
（今回はWindows端末で紹介となるので、Macについては触れていません。）

#VSCodeのダウンロードと操作
1. https://code.visualstudio.com/Downloadから、`.zip 64bit 32bit`を選択して、ファイルをダウンロード（勝手にダウンロードファイルに入る。）
<img width="886" alt="VSCodeDownload.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533115/6e0d006c-d974-0dee-6801-4bf09e6dbf71.png">

2. .zipを解凍(展開)して、USBメモリに入れる。

3. `USBドライブ()/VSCode-win32-x64-1.45.1/`
の中にいろいろ入っていると思うが、ここに新たに***"data"***というファイル名を持つファイルを作成する。

4. VSCodeのマークのついてるアプリケーションを起動する。
5. そのまま一回終了して、dataの中身を確認。すると、いろいろ入っている。

これで***ポータブルVSCode***の完成。
showModalDialogのように、サブウインドウを表示して戻り値を取得する

# やりたいこと

[window.showModalDialog](https://developer.mozilla.org/ja/docs/Web/API/Window/showModalDialog)のように、サブウインドウを表示して戻り値を取得する。

# 実装

```JavaScript:opener.js
function openWindowToCenter(name, url, width, height) {
  const left = (screen.width - width) / 2;
  const top = (screen.height - height) / 2;
  const param = `width=${width}, height=${height}, left=${left}, top=${top}`

  return window.open(url, name, param);
}

function lockBody(window) {
  window.document.body.style.pointerEvents = 'none';
}

function unlockBody(window) {
  window.document.body.style.pointerEvents = 'auto';
}

function showDialogAsync(url, width, height) {
  lockBody(window);

  const timestamp = Data.now().toString();
  const dialogName = `dialog_${timestamp}`;
  const dialog = openWindowToCenter(dialogName, url, width, height);

  return new Promise((resolve, reject) => {
    const intervalId = setInterval(() => {
      if (dialog.closed) {
        clearInterval(intervalId);

        unlockBody(window);

        resolve(window[dialogName]);
      }
    }, 100);
  });
}

(function () {
  document.getElementById('showDialogButton').onclick = async () => {
    const returnValue = await showDialogAsync('dialog.html', 100, 100);

    console.log(returnValue);
  };
}());
```

```JavaScript:dialog.js
function returnValueToOpener(value) {
  window.opener[window.name] = value;

  window.close();
}

(function () {
  document.getElementById('returnValueButton').onclick = () => {
    returnValueToOpener('戻り値');
  };
}());
```

```HTML:opener.html
<html>
  <head>
    <title>呼び出し元ウインドウ</title>
  </head>
  <body>
    <button type="button" id="showDialogButton">サブウインドウを開く</button>
    <script scr="opener.js"></script>
  </body>
</html>
```

```HTML:dialog.html
<html>
  <head>
    <title>呼び出し先ウインドウ</title>
  </head>
  <body>
    <button type="button" id="returnValueButton">呼び出し元に値を返す</button>
    <script scr="dialog.js"></script>
  </body>
</html>
```

# 補足
ウインドウを閉じたときのイベントには[window.onclose](https://developer.mozilla.org/ja/docs/Web/API/GlobalEventHandlers/onclose)があるが、標準仕様に含まれていないため使用しなかった。
【初心者向けハンズオン】WindowsにDockerでPHP/MySQL/Apache環境構築（第1回：DockerDesktopを入れるまで）

# 概要

　新人もベテランも本当にエンジニアによくある、「開発環境建てるのめんどくさい問題」を解決する糸口を模索していました。何しろ、自分と共通の開発環境つくってもらうのがめんどくさくて仕方がない。
　で、そういった課題への解決策としては当然のように「Docker」が提唱されることになるわけです。
「でも自分の開発環境Windowsなんだよなあ」
　とはいえ行けるかどうか半信半疑で調べてみたら、結構参考記事が上がっていたので「よしじゃあこれも備忘つけながらやってみるか」と思い立った次第です。

　同じく例によって、1回1時間程度の作業時間でやるルールにして、記事は細切れに書いて行くスタイル。長くなると読む側もダレるかなあと思ったというのもあります。

# 目標
* PHP/MySQL/Apacheで古き良きWEBアプリケーションの開発環境を作る
* つくった開発環境を他の人に配布できるようにする
* ↑の「配布された人が簡単に開発環境を作れる手順をまとめる」ところまでがゴール

では行ってみましょう。

# 作業内容
## dockerインストール
こちらからインストール →　https://docs.docker.com/docker-for-windows/install/

その後ダウンロードしたexeファイルを使ってインストール。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/2b1d37a7-30cb-820b-d90a-251135e910f1.png)

↓↓↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/e7496646-dc9a-4b45-bf5b-c40671b768f1.png)

↓↓↓

無事完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/04f049ef-effc-8283-12ab-16e64c84b3bf.png)

## まさかのエラー（でなければスルー）

意気揚々とインストールしたdockerを始めようとしたらいきなりエラーで出鼻をくじかれる。なぜ。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/5d1c6c06-2a62-b29d-8e57-16be2f90b4a6.png)

調べたらこんな記事が出てきました。
https://qiita.com/toro_ponz/items/d75706a3039f00ba1205

手順通りやったらできました。良かった。PCの管理者、ユーザーの利用者で躓くかもしれない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/927c2a12-afd2-5fd4-d72c-c05e52eb5445.png)

## 初期セットアップ
とりあえず指示通り青いボタンを押しながら「Start」「Next Step」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/d59f0a3f-4f4f-c82d-ca1f-d3346c8e562a.png)

（色々出る）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/31e89030-cd38-f897-c697-49d8cdc0f185.png)

Docker Hubのアカウントが必要でした。
僕はたまたまもってましたが、ここで取得しましょう。
https://hub.docker.com/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/7dc150ba-6042-b1b7-10ac-43ce82d84b00.png)

で、Sign inしておしまいです。チュートリアルとか色々出るけど最後はこの画面でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/c941b867-5aeb-59bc-367b-cb0df5a57480.png)

# 終わり。
なんだかんだ読みながらやるとインストールだけで1時間とか立ちますよね。
jQueryのchangeイベントがIEでは無効になる



## 課題
radioボタンを使ったinputの動作制御がIEだけうまく行かないのを修正する


## 原因
IEはinput[type=radio]のchangeイベントがとれない (っぽい)

### ソース

```javascript
$(function(){
    // $('input[name="' + hoge + '"]') = radioボタン
    $('input[name="' + hoge + '"]').change(function(){
        concole.log('clicked'); // IE11で出力されない
    });
});
```


## 解決
IEはinput[type=radio]のchangeイベントがとれないとわかったので、clickで代用してやればよい。
今回はあえて、IEは'click'、そのほかは'change'と**三項演算子**で分岐させることにした。

```javascript
var ua = window.navigator.userAgent.toLowerCase();
var isIE = ua.indexOf('msie') >= 0;
$(function(){
    // $('input[name="' + hoge + '"]') = radioボタン
    $('input[name="' + hoge + '"]').change(function(){
        concole.log('clicked'); // 出力されない
    });
});
```

こう書けばIEだけは**'click'**になり、他のブラウザは**'change'**がイベントが指定される。


........でも、分岐させなくてもいいかな～とも少し思ったり^^;



### 参考
https://stackoverflow.com/questions/208471/getting-jquery-to-recognise-change-in-ie
Javaのコンストラクタ

###コンストラクタ
インスタンスフィールドが増えるとコードが冗長になります。
クラスには、コンストラクタというものがあり、newを使ってインスタンスを生成した後に自動で呼び出される特別なメソッドを使います。
コンストラクタは特別なメソッドのため、定義方法が決まっています。
①コンストラクタ名はクラス名と同じにする
②戻り値を書いてはいけない（voidも書かない）
【例】今回は人(Person)にします

```Person.java
class クラス名 {
  クラス名() {  //コンストラクタ〜
  //インスタンス生成時に行いたい処理を記述
  }  //〜コンストラクタ
}
```
【例】

```Main.java
class Main {
  public static void main(String[] args) {
    Person person1 = new Person();
    Person person2 = new Person();
  }
}
```

```Person.java
class Person {
 Person() {
    System.out.println("おはよう");
 }
}
```
次は、インスタンスを生成する際に、インスタンスフィールドにセットしたい値を引数に渡し、コンストラクタでセットします。
**this**を用いてインスタンスを利用することができます。
【例】

```MAin.java
class Main {
  public static void main(String[] args) {
    Person person1 = new Person("佐藤");
    person1.hello();
   
    Person person2 = new Person("鈴木");
    person2.hello();
  }
}
```

```Person.java
class Person {
  public String name;
  Person(String name) {  //コンストラクタがString型の引数を受け取るようにしています
    System.out.println("おはよう");
    this.name = name;  //インスタンスフィールドnameに値をセットしています
  }

  public void hello() {
    System.out.println("私は" + this.name + "です");
  }
}
```
上記だと「new Person("佐藤");」の佐藤の部分がPerson.javaの「Person(String name)」のnameが佐藤(鈴木)になり、さらに「this.name = name;」の右側のnameからthis.nameに佐藤(鈴木)が入る感じです。
###コンストラクタの中身の重複
コンストラクタの中身が重複している場合「this()」とすると、コンストラクタから他のコンストラクタを呼び出せます。
this()はコンストラクタを呼び出すための特別なメソッドで、()に引数を渡すこともできます。
thisはコンストラクタの先頭でしか呼び出せません。
【Ruby/Rails】クラスでユニークな（一意となる）値を設定する

rubocopでは、loop + break を推奨されます。

## loop + break版
```ruby
class Nonce
  def set_nonce
    return true if nonce.present? # 上書きさせないためのガード

    self.nonace = loop do
      random_str = SecureRandom.urlsafe_base64
      break random_str unless self.class.exists?(nonce: random_str)
    end
  end
end
```

## while版
```ruby
class Nonce
  def set_nonce
    return true if nonce.present? # 上書きさせないためのガード

    begin
      self.nonce = SecureRandom.urlsafe_base64
    end while self.class.exists?(nonce: nonce)
  end
end
```

# `before_create` or `before_validation`

以下のような感じで、`validates` を書いている場合は、`before_create` を使うと、validation に引っかかってしまうので、`before_validation` を使う必要があります。

```ruby
class SomeClass
  validates :nonce, presence: true, uniqueness: true

  before_validation :set_nonce

  private

  def set_nonce
    return true if nonce.present?

    self.nonce = loop do
      random_str = SecureRandom.urlsafe_base64
      break random_str unless self.class.exists?(nonce: random_str)
    end
  end
end
```

# テストの例

```ruby
# frozen_string_literal: true

require 'rails_helper'

describe Nonce, type: :model do
  describe '#set_nonce' do
    it do
      nonce = Nonce.create!
      expect(nonce.nonce.size).to eq(8)
    end

    it do
      nonce = Nonce.new
      expect(nonce.nonce).to be_nil
      nonce.save!
      expect(nonce.nonce.size).to eq(8)
    end

    it do
      nonce = Nonce.create!
      nonce_str = nonce.nonce
      nonce.update!(updated_at: Time.current)
      expect(nonce.nonce).to eq(nonce_str)
    end
  end
end
```
テンプレートで用意しておくと便利なhead情報とscriptの設定

Webページを作っていると初期設定として何度も使用するコードがでてきます
毎回つくっているとめんどうなのでテンプレートとして用意してコピペでコーディングを進められるようにすると楽です

# コードを追加する場所

Emmetでも基盤はできますが、勉強していくと自分用にカスタマイズしておいたほうがスムーズです

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <!-- head情報-->
</head>
<body>

  <!-- script -->
</body>
</html>
```

# スマホ対応用のビュー設定

```html
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
```
今や必須のスマホ対応
記述は毎回一緒なのでとくにいじることはないでしょう
Edge用の記述も一緒にいれておきましょう

# ページディスクリプション(ページの説明)

```html
  <meta name="description" content"ページの内容を表す文章">
```

# 検索エンジンのクロールから除外する

絶対に除いてもらえるものではないので注意です

```html
  <meta name="robots" content="noindex,nofollow">
```

# OGPタグ
ツイッターやファイスブックでリンクされたときの表示の設定

```html
  <meta name="twitter:card" content="summary_large_image" /> 
  <meta name="twitter:site" content="ユーザー名" />
  <meta property="og:title" content="ページタイトル" />
  <meta property="og:type" content="website">
  <meta property="og:url" content="絶対パス" />
  <meta property="og:image" content="画像のURL" />
  <meta property="og:site_name" content="サイト名" />
  <meta property="og:description" content="記事抜粋" />
```

content内をページに合わせて入力  
summaryかsummary_large_imageを選べます  
個人的にはlargeが好みです  
og:typeはトップページだとwebsiteかblog,下層ページはarticle  
htmlにもprefixを追加します

```html
<html lang="ja" prefix="og: http://ogp.me/ns#">
```

# link系も追加

よく使うものを設定しておきましょう

```html
  <link rel="stylesheet" href="">
```

私は

- ファビコン
- Bootstrap
- fontawesome
- google font

を初期設定で追加しています


# body前に追加するscriptタグ設定

```html
<script src="./js/config/jquery-3.3.1.min.js"></script>
<script src="./js/config/popper.min.js"></script>
<script src="./js/config/popper-utils.min.js"></script>
<script src="./bootstrap-4.1.3-dist/js/bootstrap.min.js"></script>
<script src="./js/index.js"></script>
```
jquery, Bootstrap, 基本的なJavascriptファイルを読み込んでいます  
よく使うライブラリがあれば設定しておきましょう  

jqueryやBootstrapはファイルを設定しています
あまりないと思いますがバージョンが変わって不具合でるとめんどくさいのでCDNは使用しません  
好みですね

# フォルダ構成
パスが変わってしまうのでフォルダ構成もきめておくと良いです  
私は

- bootstrap
- script
  - config
- css
- public
  - ページ1.html
  - ページ2.html
- index.html

としています
新しいスキルなどで構成は変わると思うので参考程度に

# まとめ
記述はほとんどかわらないのに覚えるのはけっこう時間とられるし、めんどう  
ぜひ自分のテンプレート作ってみましょう
記述の仕方も忘れがちなので、自分なりのコメントもいれておくと便利かも
Dockerの基本をまとめてみた

## 基本事項

- Linuxでのみ作動
- **CLI**
- カーネルをホストと共有
- インフラ(OS)とアプリケーションを同梱

### メリット

- 起動時間が短い  
    = インフラ(=コンテナ)を毎回作りなおすImmutableInfrastructureと相性がいい


## ライフサイクル

- 実行中

- 停止
    - 異常終了時
    - 正常終了時

    停止状態では再実行が可能
    かつ、停止直前の状態を保持している

- 破棄

    明示的に破棄しないとディスクに残る

## Dockerfile/Docker image/Docker containerの関係

- Dockerfile ≒ クラス定義書
- Docker image ≒ クラス定義書から自動生成されたクラス
- Docker container ≒ 上記のクラスのインスタンス

![dockefileToContainer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609106/3b4a1f31-fac8-0647-2519-e21b98170e45.png)


## 参考
[Docker/Kubernetes 実践コンテナ開発入門](https://www.amazon.co.jp/dp/B07GP1Q3VT)
【TypeScript/JavaScript】switchを使って変数に値を代入する

```typescript
const determine = (value: string): string | void => {
  switch (value) {
    case 'A': {
      return 'a'
    }
    case 'B': {
      return 'b'
    }
    default:
      throw new Exception() // it depends
      break
  }
}
```

```shell
const value = determine('A')
```
パーミッションについての覚書

##permissionとは
linuxにはファイル一つ一つに管理権限があり、それを書き換えないとブラウザで表示できなかったりすることがある。
それをpermissionと呼び、必要に応じて書き換えていく。

##permmission周りでエラー

```
Fuel\Core\FuelException[Error]:
Unable to create or write to the log file. Please check the permissions on /var/www/html/**/src/fuel/logs/2020
```
このとき、logsのディレクトリ にpermissionを与えてあげる必要があった。
`chmod`を使って許可を与えてあげる

```
chmod 707 logs
```

私の場合はsshの接続先でファイルのパーミッションを与えてあげる必要があった。

[参考]
https://eng-entrance.com/linux-permission-basic

こちらがさらに分かりやすかったです。
http://www.tohoho-web.com/wwwxx012.htm
Slack botのカスタムレスポンスでメンションを飛ばす方法

任意の文字列で指定のメンションが飛ぶように設定してみましょう

### １）ワークスペースのカスタマイズ画面に行く
<img width="521" alt="スクリーンショット_2020-05-26_11_47_15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644108/1e4a32c9-f68e-474b-8da6-67a347f93648.png">

### ２）slackbotのタブを表示
<img width="725" alt="スクリーンショット_2020-05-26_11_47_43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644108/ccb3d5f5-9c4c-7b91-0abc-16250b7626a9.png">

### ３）このメンションがslackのdisplaynameなどコピペしてもうまくいかないので
<img width="740" alt="スクリーンショット_2020-05-26_11_48_35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644108/08aeaa0d-ef9d-5598-66b4-5967e253d5e0.png">

### ４）アナリティクスに移動します
<img width="203" alt="スクリーンショット_2020-05-26_11_47_31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644108/0345dde1-29bf-1610-cdd9-33c860dd4b22.png">

### ５）Membersのタブを表示
<img width="423" alt="スクリーンショット_2020-05-26_11_48_53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644108/e778c727-8d71-cbd9-43eb-63aeb532a0ba.png">

### ６）Edit ColumnsでUsernameを表示させます
<img width="337" alt="スクリーンショット_2020-05-26_11_46_38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644108/7d0923d8-9153-d20d-7253-b1586852cffb.png">

### ７）この列に表示されたUsernameを
<img width="991" alt="スクリーンショット_2020-05-26_11_49_23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644108/bba53897-266d-ee81-38cf-f8f63d4f871a.png">

### ８）、Slackbot respondsに打ち込むだけです。
スペースで複数にメンション
改行でランダムにメンション
<img width="740" alt="スクリーンショット_2020-05-26_11_48_35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644108/94e2a125-22cd-2997-75e0-3b50bed69eda.png">


以上
PhpStorm pstorm コマンドでターミナルからプロジェクトを開く

PhpStorm をインストールすると `pstorm` コマンドも一緒にインストールされていました。(今日知った)

```shell-session
$ which pstorm
/usr/local/bin/pstorm
```

```shell-session
$ pstorm <プロジェクトのパス>
```

でプロジェクトを開くことができます。
カレントディレクトリのプロジェクトを開く場合は下記のコマンドで開きます。

```
$ pstorm .
```

## 参考

- https://pleiades.io/help/phpstorm/working-with-the-ide-features-from-command-line.html
MacOSのMS Teamsで他人のアイコンが更新されない問題

#経緯
<details><summary>全員アイコンが一緒事件</summary>
私の通っている学校でMicrosoft Teamsによる遠隔授業が始まったものの，
学生自身に自分の名前を設定できる権限を与えてくれなかった．
そこで，全員に設定された名前はメールアドレス(所属+学籍番号+@~~.jp)そのままとなった．
しまいにアイコンはアドレスの頭文字Aを取られ，授業中やそのチャットで誰が誰だか判別が付かなくなる状態．<br>
教員以外の学生全員が©︎みたいなアイコンにされているんですよ，耐えらんないよね．
個人的には全員個々のプロフィール画像に変更して欲しいと思ってます．<br>
その矢先，プロフィール画像変えた人の画像がいつまで経ってもこちら側に反映されないし，</details>
Teamsの再インストールも面倒でキャッシュの場所(の記事)見つけました．って話です．

Officeに関するキャッシュは他にもたくさんあるけどTeamsのキャッシュはここにしか無かった感じです．
App Storeからのインストールじゃないからだと思います．知らんけど．

#目的
MacOS上にインストールされているMicrosoft Teamsのキャッシュを消して，
いつまで経っても反映されない他人のアイコン・プロフィール画像の更新・再ロードを行うこと．

#環境

+ macOS Catalina 10.15.4
+ zsh 5.7.1 (x86_64-apple-darwin19.0)
+ Microsoft Teams 1.3.00.8663

##キャッシュの場所
lsコマンドで中を覗くと16進16桁_0というバイナリファイルがたくさん出てくるのに加えて，
index-dirというディレクトリ，その中にはthe-real-indexというバイナリファイルがあることがわかります．

```zsh
~/Library/Application\ Support/Microsoft/Teams/Cache/
```

##キャッシュの削除
もうどれ消したらいいかわかんないよね．
全消去です．排除します．

```zsh
$ rm -rf ~/Library/Application\ Support/Microsoft/Teams/Cache/
```

#結果
Teamsを再起動したらちゃんとアイコンは更新されていたことで，
アイデンティティ溢れる変更をした人たちの判別がつきやすくなりました．
めでたし．:clap::clap:

また，キャッシュを消したと言ってもログアウトされるなどの状態にはならず，
本当に**必要なファイルは消えなかった**模様.

ところでアイコンとプロフィール画像の違いって何？
アイコンが広義のプロフィール画像ってことでいい？

#参考文献
- [Microsoft Teams: How to clean cache - Albandroid's Memory](https://albandrodsmemory.wordpress.com/2019/01/04/microsoft-teams-how-to-clean-cache/)
家で本場！簡単!ガーリックライスのレシピを紹介

本日のステーキブログは、【家で本場!!!簡単!ガーリックライスのレシピ】動画をアップしました。
【家で本場!!!簡単!ガーリックライスのレシピ】は20分で本場の味が再現できるレシピ動画です。
是非見てください。
youtbeの登録お願いします！

https://thesteak.tokyo/othercook/garlicricerecipe/
#Ruby の正規表現置換でマッチ結果に対してメソッド実行する ( 例: 小文字を大文字にする例 ) 

- カッコを使ってキャプチャする
- gsub + ブロック記法で マッチ結果に対して好きなメソッドを実行できる

```rb
"ab cd ef".gsub(/(ab|ef)/) { "#{$1.upcase}" }
# => "AB cd EF"
```

# Bad Case

ブロックでないと、複数個のマッチ結果がある場合に、置換結果が全て同じものになってしまう

```rb
"ab cd ef".gsub(/(ab|ef)/, "#{$1.upcase}")
# "EF cd EF"
```


# 参考

[How to change case of letters in string using RegEx in Ruby - Stack Overflow](https://stackoverflow.com/questions/15627434/how-to-change-case-of-letters-in-string-using-regex-in-ruby)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3169











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
AndroidStudioでのデバッグログを使ったデバッグ

#AndroidStudioでのデバッグ方法
ソフト開発をしていても予期しない動作（思い通りに処理されない）になったとき、実機やエミュレータでの表示で確認するには限界があります。

##ソース上での工夫
分岐の結果どっちに処理が進んだのかがわからない場合は、その気になる行にてデバッグ出力を行います。

**Log.d("Sample","root 1")**
このように記述します。

##デバッグログ
デバッグ画面の下、コンパイル状況などが表示されるログの下にタブがあるのでLogcatをクリックします。
初期状態だとアプリを実行する度に色々な情報が来て追えなくなりますが、ログ画面の上の方に「Verbose」と表示されるところを「Debug」に変更し、さらにその右に「Sample」と入力すれば上記のデバッグ出力を確認する事が出来ます。
コンパイルエラーが出るとそっちのログ画面に移りますので注意です。

**Log.d("Sample","root 1")**
ログとして i つまり Debugとして出力します。エラーの場合はErrorなど最適な出力もあります。
「Sample」はログを捕まえたいときの検索キーのようなものです。
「root 1」の部分がログとして残ります。

変数の中身を表示する $i や ${i+1}なども使えます。

デバッグログはデバッグを実行する度に自動的にクリアされます。

##デバッグログのメリット
実行時に何らかのエラーが出て最初の画面すら表示されなかったり、ボタンを押しても反応が無かったり、データを得られているはずなのに処理が思い通りに動かない、などの場合はデバッグログを使って

1.その位置に処理が来ているか？
2．いくつか処理を行っている時のどの段階でおかしいのか
3.得られた値は期待通りなのか？

を調べるときに有効です。
それ以上の動きを追うためにはブレークポイントや変数の評価などを使った方が良いです。
SlackライクなOSSチャットツール「Mattermost」をkubernetes上に導入する

合同会社kumanoteの田中です。（[こちら](https://kumano-te.com/activities/deployed-mattermost-with-gke)にデプロイ作業をメモしています。）

新興企業を中心に、メールやIPメッセンジャーなどの運用から、Slackなどのチャットツールに移行が進んできていると思います。

弊社では、Slackを使ってきましたが、ユーザー数が多いプロジェクトなどでは、コストがややかさんできたり
セキュリティ的にまずい内容のモニタリングなどにやや課題がありました。

少し調べてみると、Slackのようなチャットツールのセルフホストできるアプリがあり、そちらを試験導入することにしました。

検討に上がったのは以下です。

- [Rocketchat](https://rocket.chat/)
- [Mattermost](https://mattermost.com/)

どちらも良いなあと思いつつ、より機能が豊富そうなMattermostを採用することにしました。

私はkubernetesを最近よく使っていて、特に管理系のツール類をk8s clusterを作って、
そこに載せて管理しています。
Mattermostについても、kubernetes（GKE）を使ってデプロイできました。

以下のような構成になります。（以下は使った、Dockerhubのimage達）

- nginx:1.14.0-alpine -(proxy)-> mattermost/mattermost-prod-app:5.20.1 -(read/write)-> postgres:9.5.6-alpine

  - nginxでwebサーバー側をたて、mattermost-prod-appのサービスにproxyします。
  - mattermost-prod-appはpostgresqlv9.5.6を利用しています。


より詳細なk8sの設定ファイル等は以下からご覧ください。
https://kumano-te.com/activities/deployed-mattermost-with-gke

以上です。