OmniAICreator/Qiita-1.07M huggingface dataset:
master(main)へのpushを禁止するテンプレートを作ろう

# はじめに
gitを通ぶってジットと呼びます。嘘です。[にわのわ](https://twitter.com/niwa_nowa)です。

masterへ直pushし、もろもろのgithub actionsが走り、
runfailedメールを受け取ることがまれによくあります。
githubには[masterへの直pushを禁止する機能](https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule)がありますが、
毎度設定するのはしんどいです。
ですのでテンプレート化しましよう。

# テンプレートリポジトリを作成する
githubには便利なことにテンプレートリポジトリという機能があります。
https://docs.github.com/ja/repositories/creating-and-managing-repositories/creating-a-template-repository

ということでトップページからぽちぽち作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590707/13f84bb2-9176-30ab-d480-1934f0c5ef04.png)

ついでなのでMITライセンスをデフォルトにするよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590707/ba2d0e6d-b38b-19b3-d314-b4ee52bed13d.png)

settings > General
Template repositoryにチェックを入れる。
![githubsettings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590707/63fba93f-a3a0-f93d-c971-b5c1ccd9bf93.png)

# 直push禁止設定を入れる
上の方でリンクで紹介したこれはテンプレートに反映されないよ

https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule

ということで、.githooks/pre-pushに設定を入れる。
```sh
#!/bin/bash

# pushを禁止するブランチ
readonly MASTER='main'
readonly RELEASE='^.*release.*$'  # 「release」文字列を含む全てのブランチ

while read local_ref local_sha1 remote_ref remote_sha1
do
  if [[ "${remote_ref##refs/heads/}" = $MASTER ]]; then
    echo -e "\033[0;32mDo not push to\033[m\033[1;34m master\033[m \033[0;32mbranch\033[m"
    exit 1
  fi
  if [[ "${remote_ref##refs/heads/}" =~ $RELEASE ]]; then
    echo -e "\033[0;32mDo not push to\033[m\033[1;34m release\033[m \033[0;32mbranch\033[m"
    exit 1
  fi
done
```

これを実行して完成 ~~本当はcloneするだけ、templateを選択するだけで直pushを禁止したかった~~
```
git config --local core.hooksPath .githooks
```

ok
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590707/a81902b5-3525-88ab-eece-88b68c9fc243.png)

~~参考~~まるパクリ

https://zenn.dev/aya_ryo/articles/c49f7606e928b0

# おわりに
.github/hooks/pre-push でよしなに
or
.git/hooksだけバージョン管理できるようにとかできないんですかね？
[LINE WORKS] vConsoleでWOFFアプリをデバッグする

# はじめに
LINE WORKSのAndroid/iOSアプリ上でWOFFアプリの動作確認をする際に、開発者ツールの表示もできないため、何か動作に異変があった場合にデバッグが難しく、HTMLを修正して画面上やアラートでログを表示するといったことも限界があります。

スムーズなデバッグを行うために、「vConsole」を活用することができます。

https://github.com/Tencent/vConsole

# サンプルコード
https://github.com/lineworks/woff-starter-app  

LINE WORKSが提供するWOFFのサンプルコードでもvConsoleを利用しています。

# vConsoleを追加する

vConsoleの追加方法は簡単で、以下のコードをHTML内に入れるだけです。

```html
<!DOCTYPE html>
<html lang="en">
    <head>
        ....
    </head>
    <body>
    
        <!-- VConsole -->
        <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
        <script>
            // VConsole will be exported to `window.VConsole` by default.
            var vConsole = new window.VConsole();
        </script>
        <!-------------->
        
        ....
```

# vConsoleでWOFFのログを見る
vConsoleを入れたWOFFアプリを立ち上げると、右下に「vConsole」ボタンが表示されます。

(画面はiOS版)

![IMG_1623のコピー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241369/1e25ff64-e32c-c35a-7406-aeec1898d9e8.png)

これを押すと、コンソール画面が立ち上がり、ログやシステムログ・ネットワークログといった一般的な開発者ツールでみられる情報が表示されるようになります。

`console.log()` で出力したログも、「Log」でみられるようになるため、動作を見ながら、このvConsoleでコンソールログも確認できるようになります。

![IMG_1624.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241369/31ee2cb8-8ba8-bc3c-9245-20043c78b4fe.png)

# 参考
vConsoleが合わない場合は代替として「Eruda」という類似のツールもあります。

https://github.com/liriliri/eruda

# まとめ
WOFFアプリの開発をスムーズにするためのツールとしてvConsoleはおすすめです。

各種機能については、vConsoleのリポジトリの情報を参照ください。

https://github.com/Tencent/vConsole
【未経験エンジニア】受託開発事業部に配属されて4ヶ月が経って気づいたこと

こんにちは:hatched_chick:
私は新卒1年目で7月から受託開発事業部に配属され、現在はflutterでスマホアプリ開発の案件に参画しています。

早いもので受託開発事業部に配属されて、４ヶ月経ちました。
本当に、あっという間です。あと半年で後輩ができることに不安が募りました。

そこで、この4ヶ月でどんな気づきを得て成長をしたのか、先輩方から受けた指摘と共に振り返ってみました。
皆さんは、最近どんな成長をしましたか?




# 目次
[1.はじめに](#1-はじめに)
[2.質問の仕方](#2-質問の仕方)
[3.タスクの優先順位を見極める](#3-タスクの優先順位を見極める)
[4.リーダブルコード](#4-リーダブルコード)
[5.最初の作業は方向性を確認](#5-最初の作業は方向性を確認)
[6.プログラムの仕組みの理解](#6-プログラムの仕組みの理解)
[7.エラー文を読み、調べること](#7-エラー文を読み、調べること)
[8.おわりに](#8-おわりに)

# 1. はじめに
今回は自分が受けた指摘を一部ですが、6個挙げてみました:raised_hand_tone1:

# 2. 質問の仕方
簡単に聞こえますが、非常に難しくつまずきました。
特に、テキストベースでの質問です。
質問する際には、
* **何で質問したのか**
* **何を試したか**
* **自分はそれに対して、どう思っているのか**
* **どんな答えが欲しいのか**

を具体的かつシンプルに述べる必要があります。

私はこれができていませんでした。
今までの生活で、テキストで質問するのはLINEくらいでしたので
短文と絵文字伝わっていたんです。もし説明が長くなってしまうなら、
電話をしていました。
業務になると、無駄なラリーを生んでしまうので
質問の受け手の時間を割いてしまいますし、電話ができる時間も限られてきてしまいます。
質問するときは、相手の立場に立つことを重要視しなくてはいけないと気づくことができました。


# 3. タスクの優先順位を見極める
今日やらなきゃいけないことと明日でもいいことを見極めることの大切さを学びました。
配属されてまもない頃に渡されたタスクはスマホアプリのホーム画面の模倣で、
flutterのチュートリアルと共に進めていました。
早くタスクを片さなきゃという気持ちと、早くできる様にならなきゃという焦りで、
業務時間が終わっても夜遅くまで勉強して、夢でもコードを書いていました。
一見、頑張ってる風ですが、自分の身体面と向き合えていなかったのです。
もし、タスクがもう1つ追加されたとしたら、あの当時の私はパンクして体調を崩して仕事を休むだろうし、
周りの付き合いも全て切り捨てるでしょう。

そんな性格の私に、上司からタスクの優先順位を教えてもらいました。

**1番目に重要度と緊急度が両方高いタスク**
**2番目に重要度は高い一方で緊急度が低いタスク**
**3番目に重要度は低い一方で緊急度が高いタスク**
**4番目に重要度と緊急度が両方低いタスク**

私が戦っていたタスクは優先度最下位でした笑
時間内に終わらなければ、明日に回していいものだったんですね〜
当時の私は、気づきませんでした:sob:

# 4. リーダブルコード
リーダブルコードとは、
「他の人が読んだ時に、コードの意味を理解するまでの時間を短くできるコード」のことです。
開発をする際に、動けばいいじゃんと思っていたのですが、開発するのは1人ではないので自分以外の人のためにもリーダブルコードを心がけなくてはいけないことを肌で実感しました笑
初めて作ったアプリの模倣のコードは今見ると、ナニコレ:joy:となりました。
* 500行のコード
    * 長すぎ、重複したものが多い
    → 半分のコード量にできる
* AnataniSectionという謎の自作widget名
    * このwidgetは何の役割をしているのかが全くわからない
    → 一目見て、どこに表示されるものか理解できる名前にする

動きは正常で、完成しました。
、、、が
改修が非常に大変でした。まず、
謎のコードを探すところに時間がかかるし、重複しているので改修箇所が多く
見落とししてしまいます。
まだ自分だけ使用したコードなので、許すとして、
誰かがこのようなカオスコードを改修しろと言ってきたら
絶対腹立ちますよね:rage:
気をつけて、コードを書く様にします:bow_tone1:

# 5. 最初の作業は方向性を確認
報連相大事ですよね
特に作業の初めは、作業を渡した人の期待値に沿って作成されているのか
を確認する作業が必要です。
私は、これでいいかな〜と作業して、何個か作成し終わった後に
不足があったりして、勿体無い作業時間をとってしまいました。
入念に確認！、不安じゃなくてもとりあえず確認！
叩き込みます:ok_woman:


# 6. プログラムの仕組みの理解
サイトのコードをコピペして持ってきた時に、
動きを理解せず、使っていると痛い目見ます。
チュートリアルなんて、まさにそうだと思います。
答えをコピペして持ってくれば、完成しちゃうんですから:smirk:
flutterのチュートリアルが全然理解できていないのに、チュートリアル完了してしまって、アプリ模倣の際に何もできず、何を勉強してきたんだろうと思いました。
頭と体を使わないと覚えませんね〜

エラー解消の際にも、
コードに根拠を持たせるためにも、仕組みを学ぶことは非常に大事です。


# 7. エラー文を読み、調べること
開発してて、エラーが出ることは日常茶飯事です
配属当初に環境構築をしていた際にターミナルに出てきた☠️マークのエラーは、
とても怖かったです。壊れるんじゃないかと考えていました。
ただ、最近はエラー文は正解へのヒントだと思う様になりました。
どこが悪いですと教えてくれるんですから！お医者さんと同じですね〜
ただ、真っ赤な画面や☠️マークはどうにかなりませんかね笑
もっとユーザーに優しい印象を与えてくれれば、温かい気持ちで治してあげますよ〜と思うのに:joy:

エラー文の解消の仕方は私の直属の先輩の記事にわかりやすく書かれています！
[【Flutter初学者向け】真っ赤な画面と効率的に戦えてますか？](https://qiita.com/suga_slj/items/b5ead49ab3431f894a1e)

# 8.おわりに
ここまで読んでいただきありがとうございました:bow_tone1:
いかがでしたでしょうか？
本当に初歩的なことですが、できていなかったことが沢山ありました。
この4ヶ月で出来ないことに気づくことができたので、直していくというアクションができるのです。
日々お勉強ですね！！
いつもはflutterの技術系の記事を投稿しているのですが、こういったポエム系の記事は
自分自身に向き合えて新しい発見を見つけられると書きながら感じました:blush:

いいねしてくれたらスキップして喜びます:rabbit:
Alibaba CloudのPolarDBの徹底分析シリーズ

https://qiita.com/dennis_wang/items/eff3a3993e4b590cfaca

https://qiita.com/dennis_wang/items/2b92122841817a2657dd

https://qiita.com/dennis_wang/items/7ce9b4954a7a70a4a89b

https://qiita.com/dennis_wang/items/f134d0e45fa5c5390317

https://qiita.com/dennis_wang/items/6a636276250f5409b528

https://qiita.com/dennis_wang/items/a076d395b24d34f99990

https://qiita.com/dennis_wang/items/ce0ffe4768dfd938baaf

https://qiita.com/dennis_wang/items/31f564a76fbd10e9fa20

https://qiita.com/dennis_wang/items/daf14952bbbd7ae2b539

https://qiita.com/dennis_wang/items/33d1109c75fb12a090f5

https://qiita.com/dennis_wang/items/866d44c720b0a7c35e25

https://qiita.com/dennis_wang/items/a4b0b53c0ffa0b9758a1
アクティブキュー #blueprism

# アクティブキューとは？
実は数年前の6.7時代にはもうあった（もっと前からあったかもしれない）んですが、いまひとつ話題にのぼらない地味な機能です。
なんでそんな扱いなのかというのは機能を知ると察せられます。

# どこにあるの
ここです。
![制御室](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/f1368552-6d5f-04e0-21e2-549a3bb0fef3.png)
制御室のキューとスケジュールの間にあります。
[公式の説明はこちらのリンクからご覧ください。6.10のガイド](https://bpdocs.blueprism.com/bp-6-10/ja-jp/active-queues.html)
[こちらが公式6.9のガイド](https://bpdocs.blueprism.com/bp-6-9/ja-jp/active-queues.html)

公式の説明は、親切であろうとする心は感じられるんですが、これだったらいっそ英語でお願いします……というわかりづらさがなくもない。

ざっくり言うと
「このキューにアイテムが入ったら、このRRを使ってこのプロセスで処理してね！」
という機能です。

# 設定
## 材料
- プロセス
    - 制御室に公開されている
    - スタートアップパラメータがない
    - キュー処理のループにIsStopRequested()がある
- RR

試しにこういうサンプルのプロセスを作ってみました。
Pendingのキューアイテムを取得して、1秒待って完了マークするだけの内容です。
![サンプルプロセス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/656ca2e4-6f39-7fd5-c74e-d7b0bca1739b.png)

## 作り方
### システム＞リソース＞管理
1. リソースグループを新規で作成します。

2. 作成したリソースグループの中にRRを入れます。
プールのようにリソースが確保されちゃうわけではないので、用がないときは他でも単独で自由に使えます。

### システム＞ワークフロー＞ワークキュー
1. 当該キューの「アクティブキュー」のチェックボックスをONにします。
2. プロセスとリソースグループをプルダウンから選択します。

### 制御室
「アクティブキュー」のところに、今作成したリソースグループが表示されています。
中身を見ると、こんなかんじ
![キューにアイテムを格納したところ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/e7b344b9-df3f-9e94-b7f9-e0c131cd1ea2.png)

「使用可能なリソース」の数は、リソースグループに入れたRRの数です。
「ターゲットリソース」は初期値が0。▲をクリックして、使用したいRR数まで増やします。「使用可能なリソース」の数が最大値です。


# 使い方
当該キューにアイテムを格納すると
指定したプロセスが、指定したRRの数だけ自動で始まって
![自動で始まって完了したプロセス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/77a54bf1-c996-9dd8-0d09-c12e44561854.png)

キューを即時で処理してくれます♪
![queue_nakami.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/c97534ad-c42d-fa57-554f-9cb76817bcb4.png)

# 解決できていない問題
## リソースグループのRRは使い切り
上図の、キューアイテムを全部完了にしたところの画面の「ターゲットリソース」欄を見ると、さきほど「使用可能なリソース」の数まで増やしたはずの値が「0」に変わっています。

つまり、リソースでプロセスが実行されて完了したら、そのリソースは再利用されないのです。
1個のプロセスが完了すると、「ターゲットリソース」の値が1減ります。
そして、「ターゲットリソース」の値が0になったら、キューにアイテムが入ってきてももう処理してくれないのです。
人間が手で「ターゲットリソース」の値を増やしに行ってあげる必要があります。

やったー！この機能があったら、ライセンス1個占有してキュー監視プロセスをグルグル実行し続けるやつをやらなくて済むんじゃん！
……と一瞬糠喜びしたんですが、そううまい具合にはいかない模様。

## Login Agentどうする問題
RRを使う前にLogin AgentでLoginしないといけない場合は、どう指定したらいいかが不明です。
スケジュールならタスクを順番に登録すればいいのですけど……。

# 終わりです
端的に言うと「この機能が何に使えるかよくわからん」のであんまり話題にならないっていうね……。
でもせっかくいい機能があるので（※前からあった）、これのいい使い途を見つけたいです。
主要バックエンド言語5つの特徴解説

# 主要バックエンド言語5つの特徴解説

プログラミング言語はそれぞれに独自の特徴と用途があり、開発者の選択に大きな影響を与えます。Ruby、PHP、Python、Java、Goは、特に人気のある言語で、それぞれ異なる特性を持っています。初心者にも理解しやすいように、これらの言語の基本的な特徴と用途について解説します。

## Ruby

### シンプルさと生産性

Rubyは、シンプルで読みやすい構文を持つプログラミング言語です。その設計思想は「プログラミングの楽しさ」に重きを置いており、開発者が直感的にコードを書けるように設計されています。

#### ウェブ開発の強み

- **Ruby on Rails**：RubyのフレームワークであるRailsは、ウェブアプリケーションの開発を迅速化する多くの機能を提供します。
- **MVCアーキテクチャ**：RailsはMVC（Model-View-Controller）アーキテクチャに基づいており、整理されたコード構造を促進します。

## PHP

### ウェブ開発のための言語

PHPは、主にウェブ開発に使用されるサーバーサイドのスクリプト言語です。PHPはHTMLと密接に統合されており、動的なウェブページの生成に適しています。

#### 幅広い利用

- **WordPress**：世界中の多くのウェブサイトがPHPをベースにしたWordPressで構築されています。
- **柔軟なデータベース統合**：PHPはMySQLなどの多くのデータベースと容易に統合できます。

## Python
### 柔軟性と読みやすさ

Pythonは、その高い可読性と明瞭な構文で知られています。初心者にも理解しやすく、多目的に使用できる汎用言語です。

#### 広範囲の用途

- **データサイエンスと機械学習**：Pythonは、データサイエンス、機械学習、AI開発に広く利用されています。
- **フレームワークとライブラリ**：DjangoやFlaskなどの強力なフレームワークを持ち、ウェブ開発も容易です。

## Java

### 堅牢性と移植性

Javaは、オブジェクト指向プログラミング言語で、その堅牢性、セキュリティ、移植性で高い評価を受けています。"Write Once, Run Anywhere"（一度書けばどこでも動く）の理念のもと、多くのプラットフォームで動作します。

#### 企業環境での利用

- **大規模システム**：エンタープライズアプリケーションや大規模システムの開発に適しています。
- **Androidアプリ開発**：Androidのアプリ開発にも広く使用されています。

## Go（Golang）

### 効率とパフォーマンス

GoはGoogleによって開発されたプログラミング言語で、高いパフォーマンスと並行処理の容易さが特徴です。シンプルで効率的な構文により、大規模なプログラムの開発とメンテナンスが容易になります。

#### システムプログラミングに適した言語

- **クラウドとネットワーキング**：Goは、クラウドベースのサービスやネットワーキングアプリケーションの開発に適しています。その高速な実行速度と並行処理機能が、効率的なシステム構築を可能にします。
- **マイクロサービスアーキテクチャ**：マイクロサービスの実装にも適しており、小さくて独立したサービスを効率的に開発できます。

## 各言語の比較

### 特徴と利点

- **Ruby**：開発者の生産性を高めるシンプルさと強力なフレームワークが特徴。
- **PHP**：ウェブ開発に特化し、WordPressなどのプラットフォームで広く利用されています。
- **Python**：その汎用性とコードの可読性で、データサイエンスからウェブ開発まで幅広く使用されます。
- **Java**：企業環境やAndroidアプリ開発での使用が多く、移植性と堅牢性が魅力です。
- **Go**：高速な実行速度と並行処理機能により、システムプログラミングとクラウドサービスに適しています。

### 選択の考慮点

言語の選択は、プロジェクトの要件、チームの経験、および将来のメンテナンスや拡張性に依存します。各言語の特性を理解し、プロジェクトに最適なものを選ぶことが重要です。

- **プロジェクトの要件**：アプリケーションの目的や機能、対象プラットフォームに基づいて最適な言語を選ぶ必要があります。例えば、ウェブアプリケーションならRubyやPHP、大規模なエンタープライズシステムならJavaが適しています。
- **チームのスキルと経験**：開発チームの既存の知識と経験も、言語選択に影響します。チームが既に特定の言語に精通している場合、その言語を使用する方が効率的かもしれません。
- **将来の拡張性とメンテナンス**：将来的なアプリケーションの拡張やメンテナンスの容易さも、言語選択の重要な要素です。開発後のサポートやコミュニティの活発さも考慮に入れると良いでしょう。

## まとめ

Ruby、PHP、Python、Java、Goはそれぞれ独自の特徴と強みを持つプログラミング言語です。Rubyは生産性と開発のしやすさに優れ、PHPはウェブ開発に特化しています。Pythonはその汎用性で多岐にわたる領域で使われており、Javaは企業環境やAndroid開発に強いです。Goは高速な実行と並行処理の容易さでシステムプログラミングに適しています。これらの言語の特性を理解し、プロジェクトのニーズに応じて適切なものを選択することが、効率的なソフトウェア開発への鍵となります。
Really Simple CSV Importerで登録したカスタムフィールドをCustom Field Suiteに反映する

Really Simple CSV Importerで登録したカスタムフィールドはそのままでは
プラグインが認識しません。
Advanced Custom field や Smart Custom Fieldsには対応方法が見つかりましたが、
Custom Field Suiteでは見つけれず。
データベースを除くと、wp_cfs_valuesにメタデータを登録されてないと、認識できないようです。
幸いデータ登録用のAPIがあったので、それを利用します。
https://mgibbs189.github.io/custom-field-suite/api.html

CSVインポート時のフックはpost id が確定させる必要があるので、
really_simple_csv_importer_post_saved
を使用します。

以下コード
``` php
add_filter( 'really_simple_csv_importer_post_saved', function ($post) {
	global $wpdb;
	
	try {
		// CFSで登録したメタデータの項目を取得
		$cflds = CFS()->find_fields( [
			'post_id' => $post->ID,
		] );
		$metaKeys = array_column($cflds, 'name');
		$metaKeysPlaceHolder = implode(', ', array_fill(0, count($metaKeys), '%s'));
		// CFS登録にメタデータ取得
		$curMeta = $wpdb->get_results(
			call_user_func_array([$wpdb, 'prepare'], array_merge([
				"SELECT * FROM $wpdb->postmeta WHERE post_id = %d AND meta_key IN ({$metaKeysPlaceHolder})"
			], [$post->ID], $metaKeys))
		);
		// 標準メタデータは不要なので削除
		$wpdb->query(
			call_user_func_array([$wpdb, 'prepare'], array_merge([
				"DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key IN ({$metaKeysPlaceHolder})"
			], [$post->ID], $metaKeys))
		);
		// CFSでメタデータ登録
		CFS()->api->save_fields(array_column($curMeta, 'meta_value', 'meta_key'), ['ID' => $post->ID]);
	} catch ( Exception $e ) {
		// ログ出しとか
	}
}, 10 );
```
フットプリントエディターでパッドのリナンバー on KiCad7



KiCadのフットプリントで、パッドをコピーしたのだけどパッド番号が同じになってしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b81fa6f2-119c-49f7-b8cd-20c0e1b482d2.png)

リナンバーはどうするんだったかな? 備忘録。
# 環境
KiCad7

# 操作

フットプリントエディターで、適当なパッドを右クリックで「パッドをリナンバー」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6b36d743-e415-e013-a44f-060148d87aab.png)

1番から順につけていくのなら得日変更せずに「OK」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d2bc909e-0724-c899-8495-18f3939b6f9b.png)

1番パッドから順にクリックしていきます。今回のような場合はマウスのボタンを押しっぱなしにしてドラッグが簡単!


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/96d78b5b-e8ae-81a1-9213-8ad58b7b62ae.png)

ダブルクリックで確定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e443e7cc-acea-81c7-e56f-d4d8d7bfe668.png)
AWS CLI経由でSSM接続できなくなって何とかなった

## 概要
CLIのアクセスキー誤りでCLI経由のSSM接続が出来なくなって、なんとかなった

## 環境
- クライアント側：Windows 10
- サーバ側：Amazon Linux

## やったこと
こんな感じのconfigファイルで
```config 
Host instance-id
    User username
    IdentityFile /path/to/prvate_key
    ProxyCommand "C:\Program Files\Amazon\AWSCLIV2\aws.exe" ssm start-session --target instance-id --document-name AWS-StartSSHSession --parameters portNumber=%p
```

こんな感じで接続しようとした
```bash
$ ssh instance-id
```

403エラーが出た
```
An error occurred (403) when calling the StartSession operation: Server authentication failed: <UnauthorizedRequest><message>Forbidden.</message></UnauthorizedRequest>
```

インスタンス側のログに接続を試みた形跡が無かったので、ここでクライアント側の何らかの設定不備を疑う。STSの認証情報を確認したらこんなエラーが出た
```bash
$ aws sts get-caller-identity

An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity 
operation: The security token included in the request is invalid.
```

そういえば別のアカウントのアクセスキーをCLIに登録してた気がする…ので`/.aws`配下をすべて削除後、再度`aws configure`でアクセスキーを登録し直し。(参考①)


```bash
$ aws configure
AWS Access Key ID [None]: **********************
AWS Secret Access Key [None]: *************************
Default region name [None]: your_region_name
Default output format [None]: json
```

認証情報を見てみる。
```bash
$ aws sts get-caller-identity
{
    "UserId": "*************************",
    "Account": "************",
    "Arn": "arn:aws:iam::************:user/username"
}
```
通った！ので再度ssh接続してみる。
```bash
$ ssh instance-id

Last login: Wed Nov  8 12:29:43 2023 from *******

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI    
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/ 
```

トラブルシュート成功！

## 参考
https://qiita.com/docdocdoc/items/d847ec8c0390c04b6279
systemctl edit で書き込めない

# 事象
`systemctl edit firewalld.service`にて最下部に設定値を書き込み、保存すると、下記エラーが出て書き込めない。
```
Editing "/etc/systemd/system/firewalld.service.d/override.conf" canceled: temporary file is empty.
```

なお、環境は以下の通り
```
# cat /etc/redhat-release
CentOS Stream release 9
# uname -r
5.14.0-234.el9.x86_64
```

# 原因
よくよく編集画面を見てみると、「 Lines below this comment will be discarded」（このコメント以下の行は破棄される）とある。
「### Anything between here and the comment below will become the new contents of the file」と「### Lines below this comment will be discarded」の間に記述する必要があったため、最下部に記入した設定値が無効となって、空判定されているのだった。

```
### Editing /etc/systemd/system/firewalld.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file

<---ここに設定を記述する--->

### Lines below this comment will be discarded

### /usr/lib/systemd/system/firewalld.service
# [Unit]
# Description=firewalld - dynamic firewall daemon
# Before=network-pre.target
# Wants=network-pre.target
# After=dbus.service
# After=polkit.service
# Conflicts=iptables.service ip6tables.service ebtables.service ipset.service nftables.service
# Documentation=man:firewalld(1)
#
# [Service]
# EnvironmentFile=-/etc/sysconfig/firewalld
```

# 参考
https://github.com/systemd/systemd/issues/24208
「打造令人矚目的海外實習CV」


在今天的競爭激烈的就業市場中，[海外實習](https://www.apexcharity.org/news/3/87)對於個人和職業發展來說是一個極具價值的經驗。然而，要獲得理想的海外實習機會，你需要一份引人入勝的[英文履歷](https://www.apexcharity.org/news/3/91)（CV），以及一份精心製作的Statement of Purpose。本文將指導你如何製作一份令人印象深刻的海外實習CV，讓你的申請脫穎而出。

1. 強調專業技能和經驗

在你的海外實習[CV](https://www.apexcharity.org/news/3/88)中，首先要強調你的專業技能和相關經驗。列出你在學術、實習或志願工作中所獲得的技能，特別是那些與你申請的實習職位相關的技能。這些技能可以包括語言能力、軟件應用、專業課程、專業證書等。通過清晰而具體的描述，讓雇主知道你擁有滿足職位需求的資格。

2. 強調國際經驗

海外實習CV的一個關鍵部分是突顯你的國際經驗。這包括你在其他國家的留學經歷、志願工作、遊學計畫、文化交流等。請描述你在國際環境中學到的事情，以及如何適應不同的文化和工作方式。這將有助於證明你在跨國合作和多元文化環境中具有適應能力。

3. 重點突顯成就和領導力

無論你申請的海外實習職位是什麼，都應該突顯你的成就和領導力。列出你在學術、實習、社會服務或校內活動中的成就，並描述你在這些領域中的領導作用。這可以包括項目管理、團隊合作、學術研究成果等。雇主喜歡看到具有積極性和貢獻精神的申請人。

4. 精心編寫Statement of Purpose

你的[Statement of Purpose](https://www.apexcharity.org/news/3/90)是你申請海外實習的橋樑，應該表達你的動機、目標和期望。在這份文件中，說明為什麼你想參加這個實習計畫，以及你對該領域的熱情。提供具體的例子，展示你為什麼是最適合這個機會的人選。確保仔細編輯並檢查語法和拼寫錯誤，以確保表達清晰，令人印象深刻。

總之，製作一份令人矚目的海外實習CV需要精心的計劃和編輯工作。強調你的專業技能、國際經驗、成就和領導力，並撰寫一份引人入勝的Statement of Purpose，這將有助於提高你獲得海外實習機會的機會。這是一個重要的步驟，能夠為你的職業生涯帶來巨大的影響。
プロジェクト管理における「責任の比重」について

# 概要

私は、様々な現場・プロジェクトに参画してきました。
改めて、「責任」という言葉について深く考えたので、その内容をまとめます。

# 責任とは何か

責任とは何か考えたことはありますか。
責任とは、何か問題があったときに謝ることではありません。

責任とは、**依頼された内容に対して達成すること**です。

# 責任の比重について

PM(プロジェクトマネージャー)、PL(プロジェクトリーダー)、開発メンバーの3人の構成で考えてみます。

下のような**責任の比重**が理想ですよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/29156a16-7297-d209-ccfc-02aae128a282.png)

**責任の比重** の操作が行われると、こんなプロジェクトも存在します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/6a2e5c21-a7d2-e268-24af-a2d9ea5ebcad.png)


# 責任の比重の操作

責任放棄や責任転嫁など、**責任の比重**は操作が可能です。
上司側のほうがある程度操作が有利に操作すること可能かと思います。

下の例だと、PLが進捗管理など本来の責務を怠っているのですが、正論を言っているようで開発メンバーに責任を押し付けています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/c5be8d07-0689-50db-3ce2-e2bee4dc7aa9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/8a269655-0977-b196-c356-3d0f3ee45ec0.png)


上記の例以外にも、**責任の比重**を操作する方法は、色々とあります（悪用厳禁です）
- 「そんな話聞いてない」ととぼける
- 「前から言ってると思うけど..」と存在しない話をでっち上げる
- 「この仕事どのくらいでできる？」と言質を取った上で「できると言ったよね」と詰める

など...



# 責任の比重が崩壊すると..

**責任の比重**が崩壊すると、プロジェクトが進まなくなります。

その役職の本来の責務を行われず、部下が役割を担うことでキャパオーバーしてしまったり、仕事を放棄されてしまうとそこでエスカレーションが止まってしまうため、仕事が回らなくなるのは当然です。

# どうしたらいい？

上司側と部下側で対策を説明します。

## 上司側

- **依頼する内容について正しく精査する**

「無理な仕事は断る」「次年度のタスクにする」など制御することで、キャパオーバーや遅延を防げます。

- **能力に合った作業の割り振りを行う**

割り振るタスクは、部下の能力+αくらいがベストだと思います。
そのため、部下の能力を見極める能力が必要です。

- **定期的に進み具合を確認する**

進捗確認の間隔が細かすぎると、マイクロマネジメントになってしまうのですが、部下からの報告がないから知らなかったは、ただの責任放棄です。

- **進捗が悪い場合は、キャッチアップの対策をとる**

進捗が悪い場合に「残業してでもやれ！」ではなく、割り振りの変更、スケジュールを調整などのキャッチアップの対策をすることで、部下は信頼して付いてきます。

- **部下の報告が正しいかの見極める**

今回説明した内容だと、PMが原因が本当に開発メンバーにあるのかを見極めることができると、責任の比重は補正されます。

報告内容をそのまま受け入れるのではなく、「なぜ、そんなことが起きたのか」「根本の問題は何か」を突き詰めることで、今後プロジェクトは改善されていきます。

## 部下側

- **報連相を行う**

報連相をしっかり行うことで、上司との信用ができます。
問題があった場合でも頑張ってくれていることは理解してくれるので、フォローしてくれたり、責任を受け持ってくれたりします。

- **メモを取る・内容を上司に確認する**

口頭でのやり取りには、必ず言った言わない問題が発生します。
議事録やメールなどテキストベースで残すことで、責任の押し付けが削減されます。

- **無理なら「難しい」と言う**

部下の能力を見極められていない上司は、キャパオーバーを無視して依頼してきます。責任は依頼されたことに対して達成することなので、無理なら「難しい」と言ってしまったほうが良いです。

それを受けて上司は、調整してくれたりキャッチアップしてくれます。


- **責任の比重が操作されている場合は、別の誰かに相談する**

上司に「責任の比重」を操作をされている場合は、その上司に相談してもなにも変わりません。別の誰かに相談することで、問題が発覚したり、必要のない責任を取り除くことが可能です。


# まとめ

今回は、プロジェクト管理における**責任の比重**について、私の考えをまとめてみました。

読んでいただけた方に考えるきっかけになれば嬉しいです。
ご意見等ありましたら、コメントをいただけると幸いです。

以上、ここまで読んでいただきありがとうございました。
NuGet で取得したパッケージが include 解決できなかった時の対処

結論から言えば、[cpprestsdk](https://github.com/microsoft/cpprestsdk) を VisualStudio2022 で使おうとした、おま環の話でした。

# パッケージを NuGet でインストールする
`ツール` `NuGet パッケージマネージャー` `ソリューションの NuGet パッケージの管理` からウィンドウを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/2c45f8b9-4a9c-5f69-2679-f140293c2b6a.png)
参照欄で `cpprestsdk` を検索して、パッケージを探します。いくつか出てきますが、今回は公式が公開している新しいものを選びます。追加するプロジェクトをチェックし、インストールを押せば完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/1a48a959-c1fd-ee9c-399e-a20481f4b7fd.png)
プロジェクトのルートディレクトリに `packages` が作成され、ソースファイルが追加されます。

## Include の解決に失敗する
```c++
#include <cpprest/http_client.h>
```
通常はインストールすればパス解決もされるはずですが、読み込みに失敗します。これは上記でインストールしたバージョンが `v142` となっており、つまり VisualStduio2019 用のパッケージとなっていることが原因でした。
```\packages\cpprestsdk.v142.2.10.15\build\native\cpprestsdk.v142.targets
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup Condition="'$(Force-Enable-cpprestsdk)' == '' And ('$(PlatformToolset)' != 'v142')">
    <Disable-cpprestsdk>true</Disable-cpprestsdk>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Force-Disable-cpprestsdk)' != ''">
    <Disable-cpprestsdk>true</Disable-cpprestsdk>
  </PropertyGroup>
```
`PlatformToolset` で `v142` を指定するか、`Force-Enable-cpprestsdk` の指定を追加する必要があるようです。
```Project.vcxproj
  <PropertyGroup Label="UserMacros">
    <Force-Enable-cpprestsdk>true</Force-Enable-cpprestsdk>
  </PropertyGroup>
```
プロジェクトファイルで上記を追加して解決。
terraform module の github リポジトリの README を見やすくする


# tl;dr

- この記事は[terraform Advent Calendar 2023](https://qiita.com/advent-calendar/2023/terraform)の4日目です
- 細かすぎて伝わらないシリーズ的な何か
- github に上がっている terraform module の README のテーブルが見にくいので枠を広げる chrome extention を紹介します

# 見にくい

- terraform のモジュールリポジトリはだいたい同じテンプレートに沿っているんだけど、Input/Output のテーブルが見にくいと思うんです
- 例えばこう [terraform-aws-vpc/README.md at master · terraform-aws-modules/terraform-aws-vpc](https://github.com/terraform-aws-modules/terraform-aws-vpc/blob/master/README.md)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44420/4990ed5f-ed25-94f0-2f37-f9025d5e14c9.png)

- ワイドなディスプレイなのに横幅がコレなのちょっとつらいですよね

# 見やすくすると

- chrome のエクステンションを使ってこう（見やすい！）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44420/8e18ccc5-ae10-a448-749e-c9d2d64b88d3.png)


# どうするか

- Stylus とかお好きなようにすればいいと思う（てゆうかしてる人のほうが多い気がする）
- 今回は次のような人におすすめ
    - そんなに労力はかけたくない
    - github を chrome で普段遣いしている
    - chrome extention をちょっと理解したい
- 手前味噌ですがこちらをどうぞ [officel/github-web-cosmetic: A simple Google Chrome extention to provide better visualization of github.com on large screen.](https://github.com/officel/github-web-cosmetic)
- 書いてあるとおり、リポジトリを適当なところに clone して、chrome に設定するだけです
- マニフェストとCSSを見てもらえばわかるとおり、特別なことは何もしていません
- github.com/\*/\* なページの時に横幅を画面いっぱいに使えるようにしています 

# えんじょい（終わりに）

- module を初めて使う時とか、バージョンアップした時とか、ブラウザで見ますよね？ドキュメント
- これでちょっと見やすくなったと思ってもらえたらいいかなと思います
Raspberry Pi 4 SDカード　初期起動が失敗する

# SDイメージの作成

イメージャーソフト：Raspberry Pi Imager  
SDカードの容量：16GB
OS:Ubuntu Desktop 23.10(64bit)
 [Other general-purpose OS]->[Ubuntu]->[Ubuntu Desktop 23.10(64bit)]

 # RaspberryPi4 起動 …FATAL error-code:45

 本体にSDカードを挿入して起動。
 ・・・しばらくすると、FATAL　error-code:45の表示が出て起動しない。

 Ubuntu Coreなどに変更して再度試みるが、今度は起動を繰り返してしまう。

 error-code から調べてみると、以下の内容に行きつきました。

 ["FATAL error-code 45" Booting from USB](https://forums.raspberrypi.com/viewtopic.php?t=330278)

 最後のほうで気になる記述　"HTTP network booting"　が・・・

 まさか、ネットワークにつながっていないからか。。。

 # ネットワークを接続

 RJ-45ポートにインターネットに接続できるLANを接続し、起動してみました。

 ・・・
 ・・・
 ・・・起動した・・・
 
# つまり・・・

外部ネットワークにつなげられないと初期化できないということ。
インストール途中でWiFiとか選択できるとか思いますよね・・・。

# 注意点

インストール完了後もLANケーブルの有無に関係なく２回に１回はFATAL error-code:45が出現して起動しません。

一時的なテスト用に使用するため、これ以上の追及をしていません。どうしても起動しないと困る場合には、さらに調査する必要がありそうです。
tableau計算周り

tableauの集計周りは初めて触る人にとってはマストで理解しないといけない部分なので、まとめてみました。
結論的に内容は下記の内容になります。
・集計、非集計の混在はできない
・集計関数は2回できない
上記のことを以下で解説していく

## 集計、非集計の混在はできない

| 都道府県 | 個数 | 売上 |
|:-:|:-:|:-:|
| 東京都 | 1 | 100 |
| 東京都 | 4 | 500 |
| 大阪府 | 7 | 800 |
| 大阪府 | 2 | 300 |

集計関数というのはその列全体を計算対象に入れる。
対象に非集計の状態は個別に見ていく。

東京目線で見た時に、SUM([個数])は5個、[個数]単体でみると1個と4個がありどちらを優先すべきかわからなくなる。
つまり計算不能。

<b>この関数の集計および非集計の引数を混在させることはできない。←エラーが出る</b>

### 集計と非集計では計算結果も変わる

例えば

SUM([売上])/SUM([個数])

この場合は東京目線では600÷5が計算され、120となる。
一方で

[売上])/[個数]

集計関数なしの場合は個別に計算となる。
100÷1+500÷4=225

結果が変わってしまう。

## 集計関数は2回できない

SUM( [個数] )とSUM(SUM( [個数] ))って一緒な為、単純に意味がない。
tableauのリレーションシップについて調べてみた

今回はデータ結合のリレーションシップというものがとても便利ではある反面、まだ初心者である私の中ではブラックボックス化しすぎて、今後何か問題が起きた際に対処できる気がしなかったので、早めに理解と記録を残しておくことにしました。
まずリレーションシップの公式な説明としては以下となっています。

>「固定された出力を分析前に作成する結合とは異なり、リレーションシップは分析中に複数の表を組み合わせてデータを集計し、Viz 内のフィールドとフィルターに基づいて、必要な詳細レベルでデータにクエリを実行します。」

個人的によくわからなかったので、以下でまとめました。

## 結論

**※結合計算以外はリレーションシップを使うと良い**

キーとして使いたいそれぞれデータの持ち方が違い、データの形を合わせる必要がある場合は結合計算が必要になるため、リレーションが使えない。
逆にそれ以外は基本リレーションを使っておけば良い。
(認識としてこのような大まかな認識は大いによろしくないですが、tableauを触ってまだ一ヶ月も経っていないため、あれやこれや色々把握するよりも、問題に出会えば少しずつ対処して覚えていくようにします。2023/9/21現在以降何か発見すればこちらの記事に追記していきます。)

上記認識で今後リレーションシップを活用しつつ、個人的な知識の定着としてリレーションシップを以下でまとめてみました。

## 実際の挙動

### リレーションシップの場合
| 注文NO | 注文日付 | 注文数量 |
|:-:|:-:|:-:|
| A |  2020/1/10 | 100 |
| A |  2020/1/11 | 50 |
| B |  2020/1/12 | 200 |
| C |  2020/1/13 | 300 |


＋(注文NOで集計)

| 注文NO | 注文日付 | 返品数量 |
|:-:|:-:|:-:|
| A |  2020/2/1 | 150 |

↓

| 注文NO | 注文数量 | 返品数量 |
|:-:|:-:|:-:|
| A |  150 | 150 |

### ジョインの場合
| 注文NO | 注文日付 | 注文数量 |
|:-:|:-:|:-:|
| A |  2020/1/10 | 100 |
| A |  2020/1/11 | 50 |
| B |  2020/1/12 | 200 |
| C |  2020/1/13 | 300 |


＋(注文NOで集計)

| 注文NO | 注文数量 | 返品数量 |
|:-:|:-:|:-:|
| A |  2020/2/1 | 150 |
| A |  2020/2/1 | 150 |

↓複製されてしまう

| 注文NO | 注文数量 | 返品数量 |
|:-:|:-:|:-:|
| A |  100 | 150 |
| A |  50 | 150 |

結果下記のように返品数量が間違った値で結合されてしまう

| 注文NO | 注文数量 | 返品数量 |
|:-:|:-:|:-:|
| A |  150 | 300 |

## まとめ
他にも調べるとイメージを持って取り組むことが大事なようでしたので、どんどんタスクを進めながら、何か知識に進展があれば追記しています。
【備忘録】ラズパイ4でdocker+Gitea

## はじめに
dockerでgiteaを動かす手順の備忘録です。

## dockerのインストール
いつものやつです
```title:アップデート
sudo apt update
sudo apt full-upgrade
```
dockerのインストール方法
参考：[Raspberry Pi 4でDockerのインストール方法 2023年度版](https://raspida.com/rpi4-docker-install)

```title:dockerのインストール
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

#Dockerをユーザー権限で実行できるようにグループに追加する。
sudo usermod -aG docker ユーザー名
```

## docker-composeのインストール
docker-composeのインストール方法
参考：[docker composeのインストールと動作確認](https://blog.pedalclecle.com/docker-compose-install/)
```title:docker-composeのインストール
wget https://github.com/docker/compose/releases/download/v2.3.3/docker-compose-linux-armv6
sudo cp docker-compose-linux-armv6 /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

#動作確認
docker-compose --vserion
```

## dockerでgiteaをインストール
参考：[Raspbian stretch にdocker-composeでGiteaをインストールできた](https://ytyaru.hatenablog.com/entry/2019/08/11/000000)
```title:ラズパイでgiteaを動かせるイメージをpull
docker pull kapdap/gitea-rpi
```
```title:作業するディレクトリの作成
mkdir gitea
cd gitea
```
作成したgiteaフォルダの中にdocker-compose.ymlファイルを作成
```title:docker-compose.ymlファイル作成
version: "2"

networks:
  gitea:
    external: false

services:
  server:
    image: kapdap/gitea-rpi:latest
    environment:
      - USER_UID=1000
      - USER_GID=1000
    networks:
      - gitea
    volumes:
      - ./gitea:/data
    ports:
      - "3000:3000"
      - "222:22"
    depends_on:
      - db

  db:
    image: jsurf/rpi-mariadb
    environment:
      - MYSQL_ROOT_PASSWORD=gitea
      - MYSQL_USER=gitea
      - MYSQL_PASSWORD=gitea
      - MYSQL_DATABASE=gitea
    networks:
      - gitea
    volumes:
      - ./mysql:/var/lib/mysql
```

```title:docker-composeでインストール＆起動
#dockerとdocker-composeコマンドはsudoを付けないと権限で怒られる
sudo docker-compose up
```

以上でgiteaが動くようになったと思われるので確認する
http://ラズパイのipアドレス:3000

諸々の設定は以下を参考
参考：[Raspbian stretch にdocker-composeでGiteaをインストールできた](https://ytyaru.hatenablog.com/entry/2019/08/11/000000)

## おわりに
docker-composeのコマンドが見つからないとか言われたり、giteaが上手くインストールされなかったりしたので、うまくいった方法を備忘録として保存しておきます。

## 参考サイト様まとめ
[Raspberry Pi 4でDockerのインストール方法 2023年度版](https://raspida.com/rpi4-docker-install)
[docker composeのインストールと動作確認](https://blog.pedalclecle.com/docker-compose-install/)
[Raspbian stretch にdocker-composeでGiteaをインストールできた](https://ytyaru.hatenablog.com/entry/2019/08/11/000000)
Gaugeですべてのテストが通っているのに全体としてテストが失敗してしまう

# はじめに

仕事で`gauge`を活用しているのですがその中でおきたトラブルが2度目だったのにもかかわらず解決に時間がかかってしまったのでまとめます

# 問題

`Gauge`のテストを実行すると以下のようにすべてのテストが成功しているのに全体としてはエラーになりました

```
Successfully generated html-report to => /var/test/e2e/gauge/reports/html-report/index.html
 
Specifications:	7 executed	7 passed	0 failed	0 skipped
Scenarios:	16 executed	16 passed	0 failed	0 skipped
 
Total time taken: 2m46.315s
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  02:55 min
[INFO] Finished at: 2023-11-08T10:20:25+09:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.thoughtworks.gauge.maven:gauge-maven-plugin:1.5.0:execute (default-cli) on project initial-e2e: Gauge Specs execution failed. null: GaugeExecutionFailedException -> [Help 1]
```
# 解決方法

テスト実行前のログにエラーがありました

```
[ParseError] test/e2e/gauge/specs/display.spec:27 Scenario should have atleast one step => ''
```

実際に該当ファイルを見ると以下のような状態で、コメントだけのテストが存在していました

```display.spec
# Display

## メインページ
ログインする
テーブルが表示されている
```

コメントだけのspecはエラーになるのでなくしたところうまくいきました

# おわりに

ログをよく読むのが大事と何度も思っていますが、今回もだめでした
Power Automateでサイトの管理者権限がないとエラーになってしまうアクション一覧

Sharepoint Onlineコネクタのアクションで、アクションの接続アカウントがサイトの管理者権限を保有していないとエラーが発生してしまうアクションを列挙します。見つけた時に追加していく感じです。

|アクションの英語名|アクションの日本語名|
|---|---|
|Update item |[項目の更新](https://learn.microsoft.com/ja-jp/connectors/sharepointonline/#%E9%A0%85%E7%9B%AE%E3%81%AE%E6%9B%B4%E6%96%B0)|
|Create New Folder|[新しいフォルダの作成](https://learn.microsoft.com/ja-jp/connectors/sharepointonline/#%E6%96%B0%E3%81%97%E3%81%84%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC%E3%81%AE%E4%BD%9C%E6%88%90)|
Pythonでデコレータを使用する

## 初めに
デコレーターは、関数を引数として受け取り、それを修飾（拡張または変更）してから返す別の関数です。
主に関数の再利用性を高め、コードをより読みやすく、管理しやすくするために使用されます。

## デコレーターの基本
```python
def my_decorator(func):
    def wrapper():
        # 何か前処理
        func()
        # 何か後処理
    return wrapper
```
my_decorator はデコレータです。これは、func という関数を引数として受け取り、wrapper という新しい関数を返します。wrapper 関数内で、func が呼び出される前後に追加のコード（前処理や後処理）を実行することができます。



```python:デコレーターを使用する
@my_decorator
def my_function():
    print("Hello from my function!")
```
この例では、my_function 関数は my_decorator でデコレートされます。つまり、my_function を呼び出すときに実際には wrapper 関数が呼び出され、my_function の中身は wrapper 関数の中から呼び出されます。

## 引数と戻り値を持つデコレータ
引数や戻り値を持つ関数にデコレータを適用する場合、wrapper 関数内で *args と **kwargs を使用して、任意の数の位置引数やキーワード引数を受け取るようにします

```python
def my_decorator(func):
    def wrapper(*args, **kwargs):
        # 何か前処理
        result = func(*args, **kwargs)
        # 何か後処理
        return result
    return wrapper
```

デコレータは関数の実行時間を計測したり、ログを出力したり、キャッシュやエラーハンドリングを行ったりと多様な用途に使用できます。
例えば、関数の実行時間を計測するデコレータは次のようになります。

```python:使用例
import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time} seconds to run.")
        return result
    return wrapper

@timing_decorator
def my_function():
    # 長い処理
    pass
```
このデコレータを使うことで、任意の関数の実行時間を簡単に計測できます。


## 各関数が実行される前に、特定の属性があるかチェックを行うデコレーター

```python
def decorate_all_methods(method_decorator: Callable) -> Callable:
     def class_decorator(cls):
         for name, obj in vars(cls).items():
             # コンストラクタ以外のメソッドをデコレートする
             if callable(obj) and name != "__init__":
                 setattr(cls, name, method_decorator(obj))
         return cls
     return class_decorator
	 
 
 def check_logger(method: Callable) -> Callable:
     @wraps(method)
     def wrapper(*args, **kwargs):
         _self = args[0]
         # _self._loggerがセットされていない場合はdebugログを出す
         if _self._logger is None:
             print(
                 "Logger instance isn't set on the Module. "
                 "Please use it via ModuleHandler")
             raise Exception
         res = method(*args, **kwargs)
         return res
     return wrapper
```
### decorate_all_methodsクラス
このクラスはデコレーターを引数に取ります。
デコレーター対象の呼び出し可能オブジェクト、つまりメソッドに対して、```setattr```で引数のデコレータを追加しています。

つまり、```setattr```によって、クラス内の各メソッドにデコレータが適用され、元のメソッド名でアクセスした際にデコレータを介して実行されるようになります。

### check_logger
追加したいデコレーターの機能を定義しています。
```decorate_all_methods```クラスでメソッド追加時には、```wrapper```関数を返しているので、```check_logger```内の```wrapper```関数がメソッドに追加されることになります。
その追加された```wrapper```関数は```_self._logger```属性が存在することを確認し、なければエラーを出しています。
存在する場合は```method(*args, **kwargs)```で実際のメソッドが実行されます。

また```@wraps```では、```@wraps```でラップされた関数が、オリジナル(実際)の関数のメタデータを保持できるようになります。
今回だと```method(*args, **kwargs)```のmethodは実際のメタデータが含まれているので実際のメソッドを実行することができるのです。
Google My Business API 実施するために必要なこと

## はじめに
Google My Business APIの備忘録です💁
初心者です😅
間違えてる部分多々あると思います。
もし見つけた場合、ツッコミいただけると助かります🙇


## 内容
Google My Business APIを取り扱うにはいくつかの基準がある。

### Google My Business APIはすぐには取得できない。
Googleに申請後に審査が完了次第利用が可能になっているサービス。

Googleフォームにて必要情報を入力してからGoogleからの許可を取得してからAPIを利用することができる。

[Google My Business API 前提条件](https://developers.google.com/my-business/content/prereqs?hl=ja#request-access)


## GCPにてプロジェクト作成が必要。
Google API Console でプロジェクトを作成し、そのプロジェクトの Business Profile API へのアクセス権をリクエストする必要。

[Google API Console](https://console.cloud.google.com/cloud-resource-manager?hl=ja)
[アクセスリクエストフォーム](https://docs.google.com/forms/d/e/1FAIpQLSfC_FKSWzbSae_5rOpgwFeIUzXUF1JCQnlsZM_gC1I2UHjA3w/viewform?hl=ja)

## Gmailにドメイン入っていないといけない
〇〇＠gmail.com　ではなく　
〇〇@会社名.com になるドメインが必要。

:::note warn
注意点
* Gmailドメインは毎月の料金が発生する。
* Gmailドメインには、いくつか種類がある（.com、.net、.orgなど）
* メールホスティングサービスが必要。（Google Workspaceなど）
:::

## ウェブサイトドメインとGmailドメインがリンクしてなければいけない。
会社で運用している
「ウェブサイトのドメイン」
「Gmailのドメイン」がリンクしていないと

:::note info
押さえておくべき点🧠
* Google My Business APIを使うには事前に許可を取るための申請が必要。
* 会社のGmailドメインを取得していないといけない。
* 会社のウェブサイトのドメインとGmailドメインがリンクしてないといけない。
* 会社のドメイン作成にはランニングコストがかかる
:::

## 参考にしたサイト
[Business Profile API](https://developers.google.com/my-business/content/basic-setup?hl=ja)
Amazon CodeGuruの超詳細解説

# はじめに
この記事はDevOps on AWS大全の一部です。
DevOps on AWS大全の一覧は[こちら](https://qiita.com/tech4anyone/items/b06f88035d27c6ef13b2)。

この記事ではAWS CodeGuruとはどういうサービスで何ができるのかを超詳細にまとめています。

具体的には以下流れで説明します。
- Amazon CodeGuruとは
- Amazon CodeGuruの仕組み
- Amazon CodeGuru for Advance

AWSの区分でいう「Level 200：トピックの入門知識を持っていることを前提に、ベストプラクティス、サービス機能を解説するレベル」の内容です。

# この記事を読んでほしい人
- Amazon CodeGuruがどういうサービスか説明できるようになりたい人
- Amazon CodeGuruを採用するときのベストプラクティスを説明できるようになりたい人
- AWS Certified DevOps Engineer Professionalを目指している人

# Amazon CodeGuruとは
ソースコードのレビューとアプリケーションパフォーマンスに関する推奨を行ってくれる機械学習ベースのサービスです。

![](https://storage.googleapis.com/zenn-user-upload/625e7e255864-20231108.png)

CodeGuru Securityは以前、CodeGuru Reviewerとして提供されていたものでソースコードを解析し、推奨の修正内容を提示してくれます。

一方、CodeGuru Profilerはアプリケーションパフォーマンスの最適化に関する解析を行い、推奨の修正内容を提示してくれます。

1つのサービスの中に2つの機能があると思えばよいでしょう。

# Amazon CodeGuruの仕組み
## CodeGuru Security
CodeGuru Securityは重大な問題、セキュリティ脆弱性、見つけにくいバグの特定を機械学習と自動推論を用いて実現します。

CodeGuruはリポジトリ系あるいはIDEと統合して利用します。

リポジトリ系で統合できるのは以下になります。
- GitHub
- GitLab
- Bitbucket
- AWS CLI
- AWS CodePipeline

続いてIDEとの統合についてです。
IDEとの統合はCodeReviewer時代はなかった統合です。
IDEとの統合が登場しCodeGuruの利便性が非常に上がっています。

具体的には以下IDEと統合されています。
- Amazon SageMaker Studio
- JupyterLab
- Visual Studio Code with AWS Toolkit
- IntelliJ IDEA with AWS Toolkit

また、スキャン対象として対応しているのは以下言語/ソースコードです。
- Java
- JavaScript
- Python
- C#
- TypeScript
- CloudFormation
- Terraform

これもCodeGuru Reviewerと比較して大幅に拡充されているので実プロジェクトで採用しやすくなりました。

補足程度にトレーニング方法を書いておきます。
Amazon CodeGuruはロジスティック回帰とニューラルネットワークを組み合わせたルールマイニングと教師ありMLモデルを使用してトレーニングされています。
なお、教師データはオープンソースとAmazonが持っているソースコードです。

## CodeGuru Profiler
CodeGuru Profilerはアプリケーションの実行時の動作を理解するのに役立ちます。
例えば定常的なロギング動作で過剰なCPUを消費していることの特定などが可能です。

CodeGuru Profilerはアプリケーションのパフォーマンスを向上させるだけではなく、ヒープサマリの提供や、冗長なコードの特定も行ってくれます。

これによりソースコード的にもリソース的にも最適化されたアプリケーションの構築を補助します。

# Amazon CodeGuru for Advance
## LambdaへのCodeGuru Profiler統合
CodeGuru ProfilerをLambdaで作成したアプリケーションに適用するためには通常とは異なる手順をとる必要があります。

具体的にはFunction DecoratorとしてLambda関数のZipファイルに追加する、あるいはLambda関数の設定でCodeGuru Proflierを有効にする、の2パターンの手順が存在します。

Function Decoratorとして書く時の例は以下の通りです。
```python
from codeguru_profiler_agent import with_lambda_profiler

@with_lambda_profiler(profiling_group_name="MyGroupName")
def handler_name(event, context):
    return "Hello World" 
```

code_profiler_agentを記載して依存関係をLambda関数のZipファイルあるいはLambda Layersに追加しましょう。

Lambda関数の設定で有効にするときにはマネジメントコンソールでLambdaの画面に行きLambda関数の設定から有効化しましょう。

また、どちらの手順であってもLambdaの実行ロールに必要な権限の追加を忘れないようにしてください。

# まとめ
この記事ではAWS CodeGuruとはどういうサービスで何ができるのかを超詳細にまとめました。

- Amazon CodeGuruとは
- Amazon CodeGuruの仕組み
- Amazon CodeGuru for Advance

次回はEC2 Image Builderを超詳細解説します。
【ネットワーク】セキュリティ強化！ゼロトラストネットワークとは？

こんにちは！
今回はセキュリティ対策としてゼロトラストネットワークについて紹介します！
最後まで読んでいただけたら嬉しいです！

![istockphoto-1184871451-1024x1024.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524127/c87c3209-df12-a01b-d4cf-67c480924d16.jpeg)



## 1,ゼロトラストネットワークとは何か？
ゼロトラストネットワーク（Zero Trust Network）は、情報セキュリティのアプローチであり、ネットワーク内の全てのデバイスやユーザーを信用せず、信頼関係なくセキュリティを確立することを目的としています。伝統的なセキュリティモデルでは、内部ネットワークと外部ネットワーク（通常、インターネット）の間に明確な境界があり、内部のリソースには信頼がおかれていました。しかし、ゼロトラストネットワークでは、ユーザーやデバイスがネットワークに接続する際に常に認証と認可を必要とし、内部ネットワークでもトラフィックの可視性と制御を行います。

↓イメージ
![スクリーンショット 2023-11-08 11.18.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524127/779e6265-8c4a-4fac-3158-d684446d1b9e.png)



## 2,ゼロトラストネットワークの主な原則

<dl>
  <dt>最小特権の原則</dt>
  <dd>ユーザーとデバイスは、必要な権限だけを持ってアクセスでき、余計な権限を持たないようにします。</dd>
  <dt>マイクロセグメンテーション</dt>
  <dd>ネットワークを小さなセグメントに分割し、セグメント間の通信を制限することで攻撃の拡大を防ぎます。</dd>
  <dt>ゼロトラストアーキテクチャ</dt>
  <dd>ネットワーク内のリソースへのアクセスは、常に認証、認可、暗号化された通信を経由します。</dd>
  <dt>可視性と監査</dt>
  <dd>ネットワーク内でのトラフィックをモニタリングし、不正なアクティビティを早期に検出します。</dd>
  <dt>セキュリティ分析とインテリジェンス</dt>
  <dd>ユーザーとデバイスのアクティビティを分析し、異常な挙動を検出するためのセキュリティインテリジェンスを活用します。</dd>
</dl>

## 3,ゼロトラストネットワークの実装パターン３選
#### ・ゼロトラストセグメンテーション
ネットワーク内のリソースをセグメント化し、セキュリティポリシーに基づいてアクセスを制御します。セグメンテーションは、ネットワーク内の各セグメントがお互いにアクセスする前に認証と認可を要求します。

#### ・マイクロセグメンテーション
マイクロセグメンテーションは、ネットワーク内のセグメントを非常に小さなセグメントに分割する方法です。各セグメントは独自のセキュリティポリシーを持ち、セグメント間の通信は最小限に制限されます。

#### ・ゼロトラスト認証とアクセス制御
ユーザーとデバイスのアイデンティティ管理を強化し、ゼロトラスト認証とアクセス制御ポリシーを設定します。これにはマルチファクタ認証（MFA）の導入も含まれます。

参考：
・https://www.zscaler.jp/zpedia/how-to-implement-zero-trust
・https://www.ashisuto.co.jp/security_blog/article/202110-zerotrust3.html

## 4,ゼロトラストネットワークの将来性
今回は4個の将来性を紹介します。
#### ・セキュリティの進化
ゼロトラストネットワークは、伝統的なネットワークセキュリティモデルの不足点を補完し、新たな脅威に対応するセキュリティフレームワークとして注目されています。将来のセキュリティ脅威に対応するために、ゼロトラストの原則が採用されるでしょう。

#### ・モバイルとクラウドの普及
ユーザーはモバイルデバイスやクラウドベースのアプリケーションを利用することが増えています。ゼロトラストは、ユーザーの場所やデバイスに依存しないセキュリティを提供し、モバイルとクラウドの普及に合わせて重要性を増します。

#### ・コンプライアンス要件の増加
データプライバシーやセキュリティに関する法規制が増加しており、組織はコンプライアンス要件を満たす必要があります。ゼロトラストは、これらの要件を満たすためのセキュアなアクセス制御を提供します。

#### ・リモートワークの拡大
COVID-19の影響により、リモートワークが一般的になりました。ゼロトラストは、リモートワーカーへのセキュアなアクセスを実現し、遠隔での作業をサポートします。

## 5,終わりに
以上で、ゼロトラストネットワークについての紹介を終わります！
今回も最後まで読んでいただき、ありがとうございました！
では、また次の記事で〜！
【超基本】AWSLambdaでRubyコードデプロイのやり方

どうもこんにちは。

今回は、業務でAWS LambdaでRubyコードをデプロイしたのでそのやり方を紹介していきます。

# AWS Lambdaとは

AWS公式ページの言葉を引用すると、

「**サーバーをプロビジョニングまたは管理せずにコードを実行できるようにするコンピューティングサービス**」です。

要するに、サーバーを使用せずにコードを実行することができる。いわば「**サーバーレスアプリケーション**」を構築することができるサービスということです。

# AWS Lambdaを使用するメリット

1. サーバーが必要ない
2. 最大で998個の処理を同時に行うことができる
3. 実行時間とリソース使用量によって料金が決まるため、低コストで使用できる
4. Lambdaはイベント駆動型のため、さまざまなサービスのイベントをトリガーにコードを実行することができる
5. 他のAWSサービスと連携して実装することができる
5. AWSのIAMを使用して関数の実行権限を細かく設定できる
7. AWSのVPCの設定を行うことでセキュリティは安心

などなどです！

# 構築方法

## 0. AWSコンソールにログインしてAWSLambdaのダッシュボードに遷移する

## 1. 「関数の作成」をクリックする

画面右上の「関数の作成」をクリックすると、作成画面へ遷移します。

![スクリーンショット 2023-11-07 20.47.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711491/8af4321e-9fc3-69a3-0cf4-ecf42a1d57d0.png)

## 2. 必要な情報を入力していく

作成画面では、以下の３つを設定します。

- Lambda関数名: 自分の好きな名前を入れてください。
- ランタイム: Ruby3.2（ここではプログラミング言語とそのバージョンを選択します。）
- アーキテクチャ: x86_64

![スクリーンショット 2023-11-07 20.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711491/cf0d5ba5-ced5-bf16-1ef8-bc746fee8dcb.png)

入力したら「関数の作成」ボタンをクリックします。

## 3. 作成された関数の確認

手順2で関数が作成されたので、関数のコードを確認してみます。

以下のようなRubyコードがエディタに入力されているはずです。

```ruby
require 'json'

def lambda_handler(event:, context:)
    # TODO implement
    { statusCode: 200, body: JSON.generate('Hello from Lambda!') }
end
```

## 4. テスト

コードタブの横にテストというタブがあります。それをクリックすると、テストを実行できる画面に遷移します。

以下のようにテストの情報を入力していきます。

- イベント名: 好きな名前を入れてください
- イベント共有の設定: 他のユーザーと共有する必要がないならプライベートでOKです
- テンプレートオプション: hello-worldでOKです
- イベントJSON: JSON形式で関数に渡すテストデータを作成します。初期コードであればそのままでOKです

![スクリーンショット 2023-11-07 21.13.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711491/547164ab-5be4-12ad-254d-5c0250e1175d.png)

「テスト」ボタンをクリックすると、テストが実行され結果が画面に表示されます。

![スクリーンショット 2023-11-07 21.18.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711491/e8e97f05-9c57-95fc-54a4-4d68595bb4df.png)

結果画面にはテストの結果が表示されます。（緑ならテスト成功、赤ならテスト失敗）

今回のコードでは、Lambda関数が実行されたらJSON形式で文字を出力するだけのコードなので、以下の結果が出力されます。

```JSON
{
  "statusCode": 200,
  "body": "\"Hello from Lambda!\""
}
```

# 引数を渡してコードを実行

次はLambda関数に引数を渡してコードを動かしてみます。

## 関数の書き換え

まずはLambdaのコードを以下のように修正します。

```ruby
require 'json'

def lambda_handler(event:, context:)
    # TODO implement
    name = event['Parameters']['name']
    age = event['Parameters']['age']

    "私の名前は#{name}です。年齢は#{age}歳です。"
end
```

## テストのパラメータを修正

テストのイベントJSONを以下のように書き換えます。

```json
{
    "Parameters": {
        "name": "太郎",
        "age": "25"
    }
}
```

## テストの実行

テストボタンを押すと、以下のような結果が出力されると思います。

```json
"私の名前は太郎です。年齢は25歳です。"
```

# まとめ

今回はLambdaの基本的な使い方をまとめてみました。

また別の記事でローカルで開発した関数をLambdaにデプロイする方法を書こうと思います。
マクロを使ってLaravelの標準ヘルパー関数を拡張する

# きっかけ
2次元配列で、中身の配列の順序を入れ替えるという汎用的な共通処理を追加したかったのだが、ユーティリティクラスを作るか、ファサードで実装するかなど迷っていた。

# Laravelには配列を扱うヘルパー関数がすでにある
よくよく考えると、LaravelにはArrという標準で配列を操作するヘルパー関数が存在するので、同じように配列を操作するヘルパー関数クラスを別途に作るのはナンセンス過ぎると判断。そこでArrヘルパー関数を拡張することにした。

https://readouble.com/laravel/8.x/ja/helpers.html#arrays

# Arrヘルパー関数の拡張

ヘルパー関数の拡張にはマクロを使用する。マクロの説明については以下を参照されたい。

https://readouble.com/laravel/10.x/ja/http-client.html?header=%25E3%2583%259E%25E3%2582%25AF%25E3%2583%25AD

既存のサービスプロバイダを汚さないように。専用のプロバイダを用意する。
bootクラスにマクロを使った拡張メソッドを実装する。
```
<?php

namespace App\Providers;

use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider;

class ArrayMacrosServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        //
    }

    public function boot(): void
    {
        Arr::macro('swap', function ($array, $index1, $index2):array
        {
            if (isset($array[$index1], $array[$index2])) {
                list($array[$index1], $array[$index2]) = [$array[$index2], $array[$index1]];
            }

            return $array;
        });
    }
}
```

続いて、`config/app.php`のprovidersに登録する。
```
    'providers' => ServiceProvider::defaultProviders()->merge([
        /*
         * Package Service Providers...
         */

        /*
         * Application Service Providers...
         */
        //色々なサービスプロバイダが登録されている・・・

        App\Providers\ArrayMacrosServiceProvider::class,//ここに追加
    ])->toArray(),
```

以下のように利用できるようになる。
最初に第一パラメータを参照渡しにしていたが、これはうまく動かなかった。
※参照渡しにこだわる理由もなかったので、入れ替えごの配列を返す形に変更した。

```
$items = Arr::swap($items, $index1, $index2);
```

同じような責任を持つクラスが重複するのは、車輪の再発明（Reinventing the wheel）にも通ずるところがある。クラスの膨張（Class Bloat）にも繋がるので、注意したいところ。
Docker データ永続化について（Dockerボリュームとバイマウント）

## 概要

- Dockerボリュームをちゃんと知らなかったので簡単にまとめる。

## Dockerコンテナの特性とデータの永続化

セオリーとしてコンテナ系の環境はフットワーク軽くコンテナを作り、フットワーク軽くコンテナを壊す。そうなると問題なのがコンテナ壊すとデータが保持できないということになる。
そこでデータを永続化させるための方法が自分が知ってる限り２つある。

- ホストPCのディレクトリをマウント（バイマウント）
- Dockerボリュームを使用

前者の場合イメージ通り、ホストPC側のディレクトリをマウントすることでデータだけはホストPC側で持ち、動作する部分はコンテナ側で持つというものである。
後者もデータの保持場所はホストPCということは変わりない、しかし前者のようにディレクトリとして実際に見える場所に永続化データを置かない。どうやらDockerが管理する領域にデータを保存するっぽい

## Dockerボリュームのメリット

Dockerボリュームを使うと下記のようなメリットがあるらしい。

### 抽象化

- Dockerが管理する領域で永続化することで、ホストPC側のディレクトリの権限やファイルシステムの種類などの面倒な部分を気にしなくて良くなる。異なるOSでも不安要素が減る。

### 単純化

- Dockerが管理する領域なので、いい意味でも悪い意味でも開発者がいじれない場所にデータが永続化される。開発者が具体的なファイルパスを管理する必要がなくなる。

## Dockerボリュームのデメリット

上記のメリットの裏返しに加え下記のようなデメリットが有るらしい。

### ディレクトリ構造をホストPC側でも表現したい場合

- Dockerボリュームはディレクトリ構造を持たないので不向き

### 永続化データを直接参照する場合

- 例えばMinioコンテナを立てて画像をDockerボリュームで永続化してしまうと直接参照できない。

## Dockerボリュームを使いたい場合

- docker-composer.ymlを使って起動コンテナの管理をしている場合下記のように指定すればボDockerボリュームを使えるらしい。

    ```docker-compose.yml
    db-volume:/var/lib/postgresql/data:cached
    ```

- 逆にバイマウントを使いたい場合は下記のように指定する。（ホストPCの`db/data`というディレクトリをマウントする場合）

    ```docker-compose.yml
    ./db/data:/var/lib/postgresql/data
    ```

## 既存Dockerボリューム一覧

- コンテナ起動中に下記を実行することで既存のボリューム一覧を確認する事ができる。

    ```
    docker volume list
    ```

## 既存Dockerボリューム削除

- 下記を実行すると指定されたボリュームを削除する事ができる。（永続化されているデータももちろん消えるので注意する。）

    ```
    docker volume rm VOLUME NAME
    ```
Docker PostgreSQLコンテナが起動しない

## 概要

- 今までMySQLのDBコンテナを使っていたが、訳あってPostgreSQLのコンテナに返る事になった。
- DBコンテナがエラーで起動せずちょっと詰まったので簡単にまとめておく。

## 問題までの経緯

- docker-composer.ymlのdbサービスで下記のように記載した。

    ```docker-composer.yml
    db:
      build:
        context: ./.hoge/db
        dockerfile: Dockerfile
      ports:
        - 3542:5432
      environment:
        POSTGRES_DATABASE: hoge_app
        POSTGRES_USER: hoge_app
        POSTGRES_PASSWORD: xxxxxxxx
        TZ: "Asia/Tokyo"
      volumes:
        - db-volume:/var/lib/postgresql/data:cached
    ```

- `docker-composer up`実行しコンテナの起動を試みた。

## 問題発生

- 下記のエラーがでてdbサービスのコンテナが起動しない。

    ```
    YYYY-MM-DD HH:MM:SS initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
    YYYY-MM-DD HH:MM:SS initdb: hint: If you want to create a new database system, either remove or empty the directory "/var/lib/postgresql/data" or run initdb with an argument other than "/var/lib/postgresql/data".
    ```

## 解決までの経緯

- ちょっと調べたところどうやらDBのデータ永続化ボリュームにすでにデータがあるためdbサービスを初期化できない旨のエラーっぽい。
- ホストPCで下記コマンドを実行してボリューム一覧を確認する。

    ```
    docker volume ls
    ```

- 下記のように出力された。（testって付いてる方はテストコード用のdbのボリューム）

    ```
    DRIVER VOLUME NAME
    local hoge-app_db-volume
    local hoge-app_test-db-volume
    ```

- どうやら`hoge-app_db-volume`の方のボリュームが存在し、空じゃないから初期化できずエラーになるっぽい。
- すでにDBで保存している情報は失われるが、下記コマンドを実行して当該のボリュームを削除した。

    ```
    docker volume rm hoge-app_db-volume
    ```

- 再び`docker-composer up`をすると問題なくコンテナが起動した。