OmniAICreator/Qiita-1.07M huggingface dataset:
Python環境構築

# 本記事の位置づけ
本記事は私がPCが故障して環境が色々とリセットされる状態になったので、WSL2のインストールを行ってPythonの環境を準備するまでの過程をまとめたものになります。

とりあえずでPythonを触る初心者向けというよりは、ある程度Pythonを触っているor触るつもりの中級者向けの環境構築になるかと思いますが、参考になれば幸いです。

# 対象の環境
Windows 11
Ubuntu 20.04.03LTS

# 下準備
## Windowsの機能の有効化
Windowsの設定(Win + I)でシステム > オプション機能 > Windowsのその他機能を選択してください。
選択後のメニューからLinux 用 Windowsサブシステム、Hyper-V、仮想マシンプラットフォームを選択してください。

## WSLの設定およびインストール
画面下部の検索欄で「cmd」と入力して出てくるコマンドプロンプトを管理者として起動しましょう。
その後、以下のコマンドを順に実行してください。

```
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

```
wsl --set-default-version 2
```

# WSLのインストール
以下のコマンドを入力してインストールしてください。
```
wsl --install -d Ubuntu-22.04
```

起動後の画面でユーザー名とパスワードを入力してください。（これはWindowsのものと一致していなくても大丈夫です。ただ、大文字とかだとエラーになるので注意）

## 私がはまったポイントと解決法
### はまったポイント1
私の環境ではwsl --install -d Ubuntu-22.04を実行したのちに起動したメニューで以下のエラーが出力されました。
WslRegisterDistribution failed with error 0x800704　
（軽く調べた感じだと、Kasperskyの影響でうまくインストールができないっぽい）

### 解決法1
以下のコマンドを実行。
```
wsl --update
```

### はまったポイント2
何等かの問題でインストールをやり直すと、以下のエラーが発生する可能性があります。

ディストリビューション 'Ubuntu-22.04' のインストール プロセスが次の終了コードで失敗しました: 4294967295。
Error code: Wsl/InstallDistro/WSL_E_INSTALL_PROCESS_FAILED

### 解決法2
wsl -lを入力してディストリビューションの一覧を確認して、その後、wsl --install -d Ubuntu-22.04などとディストリビューションを指定することで登録を解除してください。

この後はもう一度インストールを実行すれば大丈夫です。（このエラーが出ているということは、インストールは完了していると思うのですぐにUbuntuが起動するかと思います。）

# Pipのインストール
以下のコマンドを実行してください。
```
sudo apt update
sudo apt upgrade -y
```
この後、以下のコマンドでpipをインストールしてください。
```
sudo apt install -y python3-pip
```

# エイリアス登録
以下のコマンドを入力してbashrcの内容を編集してください。
```
vi .bashrc
```

以下の内容をファイルの末尾に追記してエイリアスの設定およびパスの設定を行ってください。
```
alias python="python3" 
alias pip="pip3" 
export PATH="$PATH:/home/(ユーザ名)/.local/bin"
```

以下のコマンドで上記の設定内容を変更してください。
```
source ~/.bashrc
```


# その他
Ubuntu 20.04.6だとPythonのバージョンが古いのでpipenvとか使いたい人はPyenvを導入する必要性があります。
22.04だとPythonのバージョンは3.10.12でPipenvが使えたので私はとりあえずPyenvを入れていません。
(20.04.6でセットアップした端末には入れました...)
また機会があれば追記します。

# 追記：2024/02/03
22.04.06のほうでなぜかpipenvが使えなかったので結局pyenv導入しました。
以下に導入の際の操作を記します。

## Pyenvのインストール操作
実行したコマンドを順に記しておきます。
```
git clone https://github.com/pyenv/pyenv.git ~/.pyenv

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc

source ~/.bashrc

sudo apt-get install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
```
BigIPによる別環境(実機→VE等)へのUCSのリストア

# 概要

F5のBIGIPというロードバランサーを運用していく際、
別のBIGIP環境にUCSをインストールさせて検証環境を作成したりすることがあるので。その方法を記載する。

# ucsの取得

## GUI（Configuration utility）での取得

ダッシュボードにアクセスして`System → Archive`順に押下する。
その後、`Create`ボタンを押下する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/c0b910c9-920b-1df6-2b60-a3cf5e3f7542.png)

その後`File Name`欄に任意の名前を入力したあと、`Finish`を押してバックアップ取得する。
ローカルに残しておきたい場合は、その後`Download`を押して取得しておく。

## CLIでの取得
以下のコマンドを使用して、ucsファイルを取得する。
```
tmsh save sys ucs $(echo $HOSTNAME | cut -d'.' -f1)-$(date +%H%M-%m%d%y)
```
その後ローカルに残す場合はscp,sftpを用いてucsファイルをローカルに取得する。

## マスターキーの取得

以下のコマンドを実行する。
```
f5mku -K
```
これを実行したら、英数字が出力されるので、それを保存しておくこと。後のucsにマスターキーを設定していた場合の処理に必要になる。


# UCSファイルからのリストア

UCSファイルからのリストアは個人的に**全てCLIで行う事を推奨する。**
その理由は主に以下の通り。

- GUIでリストアする場合、`no-license `などの制限ができないため、誤ってライセンスを上書きしてしまう可能性がある。
    - 仮想版のBigipの場合、もし失敗してしまうとAllowmove処理を行わないといけない。
    - 実機で誤ってリストアしてしまった場合の対処は不明。
- ucsファイルにマスターキーを設定している場合、マスターキーの変更をGUIで行う事ができない。

## ライセンス、マスターキーなどのバックアップ
以下のバックアップを、ucsを読み込む予定のBIGIPにて行う事。
```
cp -p /config/bigip.license /var/tmp/bigip.license
```
その後、ucsもバックアップする。
```
tmsh save sys ucs $(echo $HOSTNAME | cut -d'.' -f1)-$(date +%H%M-%m%d%y)
```

### マスターキーの設定
ucsにマスターキーを設定している場合、以下のように設定する。
```
f5mku -r <ucs取得元bigipのkey_value>
```

```:コマンド例
f5mku -r kymIVFGfmVBnSGaSA
```

## コマンドによるリストア
UCSファイルを確認する。デフォルトは`/var/local/ucs/`にある
```:コマンド例
[root@sample:Standby:Disconnected] config # cd /var/local/ucs/
[root@sample:Standby:Disconnected] ucs # ls
2024042001_sample.jp.ucs  config.ucs  cs_backup.ucs  tmp
```

次に、`tmsh`と入力し、tmosモードに入る

その後、`load sys ucs <バックアップファイル名> [no-license] platform-migrate`で読み込む。
- `[no-license]` をつけることで、ライセンス以外の部分のucsを読み込む。**誤ってつけないとライセンスが上書きされてしまうため注意すること。**
- `platform-migrate`で、異なるプラットフォームでの筐体に自動で差分を調整してリストアを実行してくれる。
    - 過去には`platform-check`という内容だったらしいが、それは古いらしい。

その後以下のコマンドを実行した後で、プロンプトが、読み込んだucsの状態が読み込まれている事を確認する。

読み込まれていれば、これにてリストアは終了。


:::note alert
HA構成のBIGIPを作成する場合は、両方の機器で、移設元のucsを読み込む必要がある。
そのため、`tmsh load sys ucs [ucs名] no-license [実機<=>VEなどの場合は platform-migrate ]`
を、Active&Standy側両方で実行すること。
:::

# 参考サイト

https://my.f5.com/manage/s/article/K13132

https://my.f5.com/manage/s/article/K61904000#:~:text=When%20the%20platform-migrate%20option%20is%20given%20to%20%27tmsh,concurrent%20UCS%20loads%20and%20saves%20them%20from%20happening.

https://changineer.info/network/bigip/bigip_operation_backup.html#google_vignette

https://my.f5.com/manage/s/article/K82540512
【Python】プロキシ認証環境下でpipコマンドを使用する方法

# はじめに
こんにちは。ryoです。  
この間、プロキシ認証環境下でpipコマンドでパッケージをインストールしようとしたところプロキシによってpipが上手くいかなかったので、その場合の対処法を備忘のためにまとめます。  
環境はWindows10です。  

# 結論
プロキシ認証環境下でpipコマンドを使用するためにはpipコマンドの--proxyオプションにプロキシ認証用のユーザー名＜username＞とパスワード＜password＞を指定すればOKです。  
また、＜domain.com＞にはプロキシのドメイン名もしくはIPアドレスを、＜port＞はプロキシのポート番号を指定してください。  
（企業ネットワークの場合、プロキシのドメイン名、ポート番号は企業内で指定されています。）
```bash
python -m pip install パッケージ名 --proxy http://<username>:<password>@<domain.com>:<port>
```

# その他
今回はpipのオプションとしてプロキシの認証情報を設定する方法を実践しましたが、その他方法として、事前に環境変数としてプロキシ認証情報を設定しておくという方法もあります。  
事前に環境変数として設定しておくことで毎回のpip実行時にプロキシ認証情報を設定しなくて良いので、手間が減ります。  
詳しくは以下のリンクをご参照ください。    
https://zero-cheese.com/10710/


# まとめ
本記事ではプロキシ認証環境下でのpipコマンドを使用する方法について紹介しました。  
ご覧いただきありがとうございました。
備忘録：メール送信機能の実装(Laravel8)

## はじめに
備忘録として、メール送信機能の実装方法についてまとめた

## 開発環境
Laravel 8
Laravel-permission
※宛先判定のため、Laravel-permissionパッケージを導入

## 実装したいこと
ブラウザ上で送信したい本文を入力し、指定する宛先に送信する

## 環境構築
**.env**ファイルにメールサービスの設定を追加する。
```php:.env
#Gmailを使用する例

MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your_email@gmail.com
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=from@example.com
MAIL_FROM_NAME="${APP_NAME}"
```

## Markdown Mailableクラスの作成
*Mailable*クラスを作成
同時に*Markdown*を使用することを指定する
```php:bash
php artisan make:mail SendEmail --markdown=emails.notification
```

*App\Mail\SendEmail.php* と*resources/views/emails/notification.blade.php* が作成される

## 入力ページの作成
作成された*resources/views/emails/notification.blade.php*に、宛先の選択と本文を入力できるように記述する
```php:notification.blade.php
<form action="/send-notification" method="post">
    @csrf
    <div>
        <p>宛先</p>
        <select name="destination">
            <option value="all">全員</option>
            <option value="user">ユーザー</option>
        </select>
    </div>

    <div>
        <p>本文</p>
        <textarea name="message"></textarea>
    </div>
    <div>
        <button type="submit">メール送信</button>
    </div>
</form>
```

## Mailableクラスの編集 
```php:SendEmail.php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendEmail extends Mailable
{
    use Queueable, SerializesModels;

    public $details;

    public function __construct($user,$message)
    {
        $this->user = $user;
        $this->message = str_replace("\n","\n",$message);
    }

    public function build()
    {
        return $this->subject('メールのタイトル')
                    ->markdown('emails.notification')->with('[message => $this->message]';
    }
}
```

## Markdown ビューの編集
*resources/views/emails/notification.blade.php*を編集し、*Markdown*形式でメールの内容を記述する

```php:notification.blade.php
@component('mail::message')
# タイトル

{{ $message }}

@component('mail::button', ['url' => ''])
Button Text
@endcomponent

Thanks,<br>
{{ config('app.name') }}
@endcomponent

```

## メール送信機能の処理
メール送信機能の処理を*Controller*に記述する
```php:Controller
use App\Mail\Notification;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Spatie\Permission\Models\Role;

public function sendNotification(Request $request) {
    $destination = $request->input('destination');
    $message = $request->input('message');

    if ($destination === 'all') {
        $users = User::all();
    } elseif ($destination === 'user') {
        #rolesを持っていないuserを取得
        $users = User::doesntHave('roles')->get();
    }

    foreach ($users as $user) {
        Mail::to($user->email)->send(new Notification($user, $message));
    }

    return back();
}
```

# 以上
やる気が出ない人のCodewars

# はじめに
アイデアはあるのになぜかコード書けないマンです。

年始からこれはまずいので、
とりあえず[Codewars](https://www.codewars.com/dashboard)で「コードを書く」という最低限だけやろうと思います。
# 問題

[今回の問題](https://www.codewars.com/kata/55cbc3586671f6aa070000fb/train/haskell)

原文
```
This function should test if the `factor` is a factor of `base`.

Return `true` if it is a factor or `false` if it is not.

## About factors

Factors are numbers you can multiply together to get another number.

2 and 3 are factors of 6 because: `2 * 3 = 6`

- You can find a factor by dividing numbers. If the remainder is 0 then the number is a factor.
- You can use the mod operator (`%`) in most languages to check for a remainder

For example 2 is not a factor of 7 because: `7 % 2 = 1`

Note: `base` is a non-negative number, `factor` is a positive number.
```

Google先生
```
この関数は、 が`factor`の因数であるかどうかをテストする必要があります`base`。

`true`それが要因であるか`false`そうでないかを返します。

## 要因について

因数は、掛け算して別の数値を得ることができる数値です。

2 と 3 は次の理由から 6 の因数です。`2 * 3 = 6`

- 数値を割ることで因数を求めることができます。余りが 0 の場合、その数値は因数です。
- ほとんどの言語でmod 演算子 ( `%`) を使用して剰余を確認できます。

たとえば、次の理由から 2 は 7 の因数ではありません。`7 % 2 = 1`

注:`base`は負ではない数、`factor`は正の数です。
```
簡単な問題ですが、丁寧な問題文かつしっかり基礎に忠実でいいですね。好き

問題文で求められているのは、
「"base"と"factor"の2つの数字を用意するから、"factor"が"base"の因数かどうか調べて」
ってことですね。

（個人的には"因数"より"約数"のほうがしっくりきますが……）


今回はHaskellで書きます。サンプルコードというか、最初のコードは以下。
```hs
module CheckFactor where

checkForFactor :: Int -> Int -> Bool
checkForFactor base factor = error "don't forget your code"
```
# 解決方法
問題文にある通り
「`mod`(剰余)を用いて、余りがあるか=割り切れるかどうか」
がわかれば、因数（約数）かどうかがわかりますね。

余りがない=割り切れる=true
余りがある=割り切れない=false
となればよい。


さて、Haskellの剰余はどうするんだっけな…%じゃなかった気がするな…

Q. haskellの剰余を求める式はどう書く？
A. Haskellで剰余（余り）を求める式は、mod 関数を使って書くことができます。

ですよね！

ということで
```hs
module CheckFactor where

checkForFactor :: Int -> Int -> Bool
checkForFactor base factor = base `mod` factor == 0
```
でAttempt。クリア！submitで完了。
# 終わりに
くっっっっっっそ簡単なコードを書いただけですね。最低限！有言実行！！
でも、とりあえず満足。Haskellの美しさのおかげかな。

……なんて思ってた時期が僕にもありました。

```hs
module CheckFactor where

checkForFactor :: Int -> Int -> Bool
checkForFactor = (.) (== 0) . mod
```
なるコードを発見。これは…どういう挙動なんだ？
GPT先生に聞けばわかるか…と思ったら！

### 次回、[GPT、1行のコードを理解できない！！](https://qiita.com/kohki_takatama/items/978c584397e6a57a2046)

# コラム
## 因数と約数の違い by GPT先生
数学の「因数」と「約数」の違いを中学生にもわかるように説明します。

1. **約数（やくすう）**：
   - 約数は、ある数を割り切ることができる数のことです。
   - 例えば、6の約数は1, 2, 3, 6です。これは、6を割り切ることができる数だからです。
   - つまり、約数は「割り算」に関連しています。

2. **因数（いんすう）**：
   - 因数は、ある数を乗算の組み合わせで表すときの数のことです。
   - 例えば、6の因数は1, 2, 3, 6ですが、これらは6 = 1 × 6 または 6 = 2 × 3 のように6を乗算の組み合わせで表すことができる数です。
   - 因数は「乗算」に関連しています。

簡単に言うと、約数は「割り算」で、因数は「かけ算」で関連する数です。また、因数は式や方程式を因数分解するときに使われますが、約数は数の性質を調べるときに重要です。例えば、約数を使って素数を判断することができますが、因数は式を簡単にするために使われます。
VsCode – 特定のファイル/言語でだけファイルの自動エンコード判定を有効にする (JSON) + 言語モードの一覧を見る

# CSVの例

```
  "[csv]": {
    "files.autoGuessEncoding": true
  }
```

言語の場合は `[言語名`] を書く

# 言語モードの一覧を見る

Change Language Mode から一覧が見られるようだ

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/f53369d1-5026-4e09-af5c-4a4ac9785247)

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/a8c72b4e-8897-4a56-bf9b-e398b11cac36)


# チャットメンバー募集


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

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


# Twitter

https://twitter.com/YumaInaura
React Native 遷移ができない

React Nativeのバージョンはreact@18.2.0です。

```
npm install react-router-native
```
を実行後、以下のソースコードを書いたのですが何も表示されません。

プロジェクト作成後の初期画面は表示されていました。

ボタンを表示し遷移をする方法を教えてください。

```App.tsx
import * as React from "react";
import { NativeRouter, Route, Link } from "react-router-native";
import Home from "./src/Home";

function App() {
  return (
    <NativeRouter>
      <Route path="/" Component={Home} />
    </NativeRouter>
  );
}

export default App;
```

```sec/Home/index.tsx
import React from "react";
import { View, Text, Button } from "react-native";
import { Link } from "react-router-native";

const Home = () => {
  return (
    <View>
      <Text>Home Screen</Text>
      <Link to="/">
        <Button title="Index" />
      </Link>
    </View>
  );
};

export default Home;
```

よろしくお願いします。
Fargate上のGitLab起点でECSを更新するGitOpsを実現したい

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

この記事ではGitLab起点でECSを更新するCICDパイプラインのアーキテクチャを決める流れを解説しています。

具体的には以下流れで説明します。

- 解決したい課題の整理
- 今回使うAWSサービスの整理
- アーキテクチャの策定
- 策定したアーキテクチャで達成できたこと

AWSの区分でいう「Level 400 : 複数のサービス、アーキテクチャによる実装でテクノロジーがどのように機能するかを解説するレベル」の内容です。

# この記事を読んでほしい人
- DevOpsエンジニアがアーキテクチャを決めるときにどのような思考フローを踏んでいるか知りたい人
- ECSを更新するCICDパイプラインのアーキテクチャを知りたい人
- AWS Certified DevOps Engineer Professionalを目指している人

# 前回までの流れ
[こちら](https://qiita.com/tech4anyone/items/184c04b4ffc2ac6a99e9)の記事で以下のアーキテクチャを策定しました。
![](https://storage.googleapis.com/zenn-user-upload/3bb72ec8e2f1-20240104.png)

# 解決したい課題の整理
現在、解決したいと思っている課題は以下になります。
- GitLabにコミットしたECSの定義を使ってGitOpsを実現したい
- CICDパイプラインを実行した後、実行完了までの間はマネジメントコンソールを見たくない

ということで、これをどうやって解決するか考えていきましょう。

# 今回使うAWSサービスの整理
今回使う代表的なAWSサービスの概要とベストプラクティスは[前回](https://qiita.com/tech4anyone/items/184c04b4ffc2ac6a99e9)同様です。


# アーキテクチャの策定
ここからはやりたいことを順番に考えながらアーキテクチャを策定していきます。
## GitLabにコミットしたECSの定義を起点にCIを実現したい
ECSはコンテナサービスになるのでイメージのビルドが必要になります。
そこでコンテナのCICDのCIはコンテナイメージのビルド、と定義してここからはアーキテクチャ検討をしていきます。

まず、Fargate上のGitLabに必要な定義はすべてコミットしてある前提です。
今回のアーキテクチャではGitLabからCodeCommitにミラーリングされるので、ここを起点にCIが動作します。

CIではイメージのビルドと後段のパイプラインで必要なるアーティファクトの作成を実行します。
アーティファクトにはタスクの定義であるtaskdef.json、作成したイメージの詳細を記載するimageDetail.json、動作を定義するappspec.ymlが含まれます。

これらをまとめると以下のようなアーキテクチャになります。
![](https://storage.googleapis.com/zenn-user-upload/e157998b4c16-20240104.png)

## GitLabにコミットしたECSの定義を起点にCDを実現したい
続いてCD部分です。
CIで作成したイメージとアーティファクトをもとにECSを更新していきます。

まずは、作成されたイメージとアーティファクトを見てデプロイしてよいかの承認フェーズが欲しくなるのでそれを追加してみます。
![](https://storage.googleapis.com/zenn-user-upload/98118cff044e-20240104.png)

承認した後は実際にデプロイをしていきますがこれにはCodeDeployを利用します。
CodeDeployを利用するメリットは一時的に新旧二つのコンテナが併存しトラフィックシフトによるデプロイが実現できることです。
これにより、サービスのダウンタイムを大幅に減らすことができます。

これらをまとめると以下のようなアーキテクチャになります。
![](https://storage.googleapis.com/zenn-user-upload/8c0c3c4ecdd3-20240104.png)

## GitLabにコミットしたECSの定義を起点にChatOpsを実現したい
そして、例によってパイプラインが動作している間ずっとマネジメントコンソールをみているのは嫌なのでチャットに通知を行います。今回だと、イメージのビルドが終わった時とデプロイのトラフィックシフトが完了したときに通知を飛ばすとよさそうです。
![](https://storage.googleapis.com/zenn-user-upload/67c78c742ccd-20240104.png)

さらに、管理用のアカウントと開発用のアカウントでクロスアカウントの動作をさせる必要があります。
具体的にはCodeCommitと別のアカウントでパイプラインを動作させたいということです。

これらをまとめると以下のようなアーキテクチャになります。
![](https://storage.googleapis.com/zenn-user-upload/b3370c0a8821-20240104.png)

# まとめ
本記事ではGitLab起点でECSを更新するGitOpsを実現する方法をまとめました。

今回策定したアーキテクチャで実現できたのは以下の項目です。
- GitLabにコミットしたECSの定義を起点にイメージのビルドを実行するCI
- GitLabにコミットしたECSの定義を起点にECS関連の資材を作成するCD
- マネジメントコンソールを確認する必要があるタイミングでチャットに通知を飛ばすChatOps

次回はLambdaのCICDを考えてみたいと思います。
エンジニアに転職して2年が経ちました

# 2年経って...

エンジニアに転職して2年が経ちました。2年間で一通りの開発経験が積めたと思います。
   - JavaScriptライブラリを活用して、フロント実装
   - pythonでバックエンド実装
   - セールスフォース導入サポート
   - 提案活動/受注

（過去記事）
   - [エンジニアに転職して３週間が経ちました](https://qiita.com/to-nakashima/items/036911e186b2acd115eb)
   - [エンジニアに転職して1年が経ちました](https://qiita.com/to-nakashima/items/dce24aa75ce5c5844787)

# これから

1. 実現したいライフスタイルから逆算した働き方を追求

   - エンジニアを目指した理由の一つが、好きな時に好きな場所で働けるライフスタイルを実現したかったからです。
   - その点セールスフォース導入サポート業務は、クラウド環境で完結するのでリモートワークが非常にやりやすい開発プラットフォームだなと感じてます。(要件定義/運用定着フェーズを除く)
   - 今後は、本業務を定型化して、パッケージ製品として展開していきたいと考えており、私と同じようなライフスタイルを志向している人とチームを組んだりして、協力しながら事業を拡大していければなと考えています。


2. 優秀なエンジニアと比べない、ニッチ分野で勝負

   - どこの業界でもぶち当たる、周りが優秀問題。優秀に加えて、技術が好きで仕方ない人が実在するので、そこと張り合うのは初めからあきらめましょう/別の世界線に力を注ぎましょうというのが私の考えです。(技術の掘り下げに喜びを持てる人/切磋琢磨が楽しい人は除く)
   - 過去の経験(会計事務所に勤務)＋苦にならないこと(ノーコード開発/たぶんがっつりコード書きたい人にとっては苦痛)＋得意なこと(クライアントとの関係性構築)を掛け合わせれば、エンジニアとして技術面でエッジが効いてなくても「会計事務所をメインターゲットに＋セールスフォース導入サポートができる＋わりとちゃんと話せるエンジニア」として、現実的な生存戦略が描けそうな気がしています。でもまあやってみないと分からないので、楽しみにながらTRY＆ERRORしていきたいと思います。
ネットワークが繋がらない最小構成のままElixirをasdfではなくソースコードビルドしてインストールする〜Arch LinuxをT2チップを備えない古いIntel Macにインストールしようとする日々その7

この記事は，Ubuntuはよく使うが，Arch Linuxは初めてという私 @zacky1972 が，まずは手近なT2チップを備えていない古いIntel MacにArch Linuxをインストールして習得していく過程を記録する駄文の7回目です．前回まででMac Pro(Mid 2010)へArch Linuxをインストールしたもののネットワークも繋がらない最小構成でしたが，この状態でもElixirをインストールできることを立証しました．ただし，ErlangはソースコードビルドしたもののElixirはasdfのインストールであったため，Elixirを使用するにはrootでログインして使用する必要がありました．そこで，今回はElixirもソースコードビルドして，任意のユーザーがElixirを使用できるようにします．

## シリーズ

1. [Arch LinuxをブートできるUSBメモリを用意する](https://qiita.com/zacky1972/items/9f447f9a11f91e90f6e8)
2. [デュアル・ブート環境にするためにパーティションを区切る](https://qiita.com/zacky1972/items/4b3d8240ff1f4a599908)
3. [いよいよArch Linuxをインストールする](https://qiita.com/zacky1972/items/da1db6795b84151186ab)
4. [ネットワークの設定を見る](https://qiita.com/zacky1972/items/fcce6bdeaf2b87697e3f)
5. [Mac Pro (Mid 2010)にArch Linuxをインストールする](https://qiita.com/zacky1972/items/2904a0a07f9335fdb2de)
6. [ネットワークが繋がらない最小構成のままElixirをインストールして実行してみる](https://qiita.com/zacky1972/items/9a145632c6c12c650bed)
7. ネットワークが繋がらない最小構成のままElixirをasdfではなくソースコードビルドしてインストールする(本記事)

## `fdisk -l`の結果

Mac Pro (Mid 2010)の2024年1月4日現在の`fdisk -l`の結果は次のとおりです．

|Device   |Size  |Type                |
|:--------|-----:|:-------------------|
|/dev/sda1|  200M|EFI System          |
|/dev/sda2|488.9G|Linux filesystem    |


## 再度USBメモリブート

1. Arch Linux live USBメモリをMac Pro(Mid 2010)に挿す
2. optionキーを押しながら起動する
3. USBメモリを選択して起動する
4. `mount /dev/sda2 /mnt`
5. `arch-chroot /mnt`

その後，`pacman -Syyu` として，パッケージをアップグレードしておきます．

## Elixirのソースコードインストール

手順はこちらに書いてあります．

https://elixir-lang.org/install.html#compiling-from-source

今回は，latest releaseをインストールしたいと思っています．2024年1月4日現在の最新版は1.16.0です．下記のようにダウンロードします．

```bash
cd
curl -OL https://github.com/elixir-lang/elixir/archive/v1.16.0.zip
```

続いて，次のようにビルドします．

```bash
cd elixir-1.16.0
make clean compile
```

しばらくかかります．コンパイルが終わったら，次のようにインストールします．

```bash
make install
```

これで，`/usr/local/bin`に`elixir`がインストールされます．ライブラリは`/usr/local/lib/elixir`にインストールされていました．

## asdfの設定をクリアする

このままだとasdfを優先して読み込むようになっていますので，asdfの設定をクリアします．

```bash
cd
cat .bashrc
```

次のように表示されており，asdfの設定だけが入っている状態です．

```
. $HOME/.asdf/asdf.sh
```

これを削除します．

```bash
rm .bashrc
```

一旦，`arch-chroot`環境を抜けて再度入り直します．

```bash
exit
arch-chroot /mnt
```

次のように確認をします．

```bash
echo $PATH
which elixir
```

無事，asdfの設定がクリアされていましたので，`.asdf`を消します．

```bash
cd
rm -rf .asdf
```

## 起動して確認

次に再起動してSSDで`elixir`を起動できることを確認します．

```bash
exit
reboot
```

2024年1月4日時点での起動シーケンスは下記の通りです．

1. rEFIndの起動で，F2またはInsertを2回押して，カーネル・パラメータの編集画面に移行する．
2. 末尾に`reboot=pci`を足して，Enterキーを押す．
3. ユーザーでログインする

次のようにElixirがユーザーモードで実行できることを確認しました．

```bash
which elixir
elixir -v
iex
iex> 1..10 |> Enum.map(& &1 * 2)
```
wslでelixir その126

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
LivebookでAtCoderやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/60f1e44f-8c8c-a5ff-40ff-6ca8c9c11224.png)


# サンプルコード
abc245 c

```
defmodule Main do
	alias MyIO, as: IO
	def next_token(acc \\ "") do
		case IO.getn(:stdio, "", 1) do
			" " ->
				acc
			"\n" ->
				acc
			x ->
				next_token(acc <> x)
		end
	end
	def input(), do: IO.read(:line) |> String.trim()
	def ii(), do: next_token() |> String.to_integer()
	def li(), do: input() |> String.split(" ") |> Enum.map(&String.to_integer/1)

	defp output({x, y, _, _, _, _, _}) do
		if x || y, do: "Yes", else: "No"
	end
	def judge(_, {x, y, a0, b0, [a | as], [b | bs], k}) do
		x1 = judge(x, a, a0, k)
		x2 = judge(y, a, b0, k)
		y1 = judge(x, b, a0, k)
		y2 = judge(y, b, b0, k)
		{x1 || x2, y1 || y2, a, b, as, bs, k}
	end
	defp judge(f, n, n0, k), do: f && abs(n - n0) <= k
	defp solve([1, _], _, _), do: "Yes"
	defp solve([n, k], [ai | as], [bi | bs]) do
		1..n - 1
		|> Enum.reduce({true, true, ai, bi, as, bs, k}, &judge/2)
		|> output()
	end

	def main() do
    nk = li()
		as = li()
		bs = li()
		solve(nk, as, bs)
		|> IO.puts()
	end
end
```

# 実行結果

```
{["5 4\n9 8 3 7 2\n1 6 2 9 5\n", "4 90\n1 1 1 100\n1 2 3 100\n",
  "4 1000000000\n1 1 1000000000 1000000000\n1 1000000000 1 1000000000\n"],
 ["Yes\n", "No\n", "Yes\n"]}
-- TEST 0 --
OK
-- TEST 1 --
OK
-- TEST 2 --
OK

```

以上。
dockerコンテナ環境作成

6年前にCentOS7.6で構築した検証環境をubuntu22.04.3TLSへ移行するのでメモ

### 環境
仮想化：VMware Workstation-playre17またはVMware workstation-pro17（どちらも確認済み）
ホスト：Windows10またはWindows11pro（どちらも確認済み）
ゲスト：ubuntu22.04.3TLS

### docker環境構築

``` sh:パッケージリストを更新 && パッケージの最新バージョンをインストール
$ sudo apt update
$ sudo apt upgrade -y
``` 
 
``` sh:Dockerのインストールに必要なパッケージをインストール
$ sudo apt install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
```
``` sh:Dockerの公式GPGキーを追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
``` 
※apt-keyは非推奨になったらしく警告が出たが機能はするのでそのまま進む

``` sh:Dockerのリポジトリをシステムに追加
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
```
``` sh:パッケージリストを再度更新
$ sudo apt update
```
``` sh:Docker本体と関連ツールをインストール
$ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
``` sh:現在のユーザーをDockerグループに追加
$ sudo usermod -aG docker $USER
```
``` sh:Dockerのバージョンを確認
$ docker --version
```
### docker-compose環境構築
``` sh:Docker Composeをインストール
$ sudo apt install docker-compose
```

``` sh:Dockerバージョン確認
$ docker --version
Docker version 24.0.7, build afdd53b
```
``` sh:Docker-composV1バージョン確認
$ docker-compose --version
docker-compose version 1.29.2, build unknown
```
``` sh:Docker-composV2バージョン確認
$ docker compose version
Docker Compose version v2.21.0
```
https://docs.docker.com/compose/install/linux/
上の公式ページによるとDocker ComposeV2がDockerエンジンに統合されてインストールされたらしい、ということは個別のDocker-compos(V1)のインストールは不要かもしれない。



### 参考にしたページ
https://zenn.dev/rg687076/articles/ac8c4f7e592e57

https://docs.docker.com/compose/install/linux/


### 投入ログ
[docker_install_log](https://github.com/38pinn/miwa/blob/master/docker_install_log)
2024 年、バックエンドの開発のトレンドは？

## 2024 年、バックエンドの開発のトレンドは？

ということを考えたときに、2 年前にこんなことを調べた。

https://qiita.com/e99h2121/items/98edea4e4a462a7dcf81

2024 年、似たような記事を見つけると以下など。

https://www.linkedin.com/pulse/trends-2024-backend-web-development-levi-s-blown-2rnqf/?trk=article-ssr-frontend-pulse_more-articles_related-content-card

2 年前、私は自力で翻訳してまとめていました。

## ChatGPT に翻訳して要約してもらう

2 年前と今とで違うのは ChatGPT がいること。以下すべて引用:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/af101d2d-1018-a012-21b9-236c8140a34c.png)


>2024年のバックエンドとWeb開発のトレンドについて、以下の内容が挙げられています。

>AIと機械学習の統合：バックエンド開発において、AIと機械学習は重要な役割を果たしています。コード生成、セキュリティと品質の向上、個人化、予測分析、および推奨システムなど、これらの技術を利用して、開発プロセスを効率化し、ユーザーエクスペリエンスを向上させることが可能です。

>サーバーレスアーキテクチャ：サーバーレスアーキテクチャ（FaaS）は、サーバーの管理を排除し、コードの記述と関数の展開に焦点を当てることで、拡張性とコスト効率を向上させます。AWS、Microsoft Azure Functions、Google Cloud Functionsなどのプラットフォームで提供されており、画像の識別、マルチメディアの処理、チャットボットやアシスタントの作成など、さまざまなビジネスで活用できます。

>エッジコンピューティング：データ処理を分散させ、エッジに近づけることで遅延を最小限に抑え、リアルタイム性を向上させます。待ち時間の削減、生産性の向上、帯域幅の節約、リアルタイムデータ処理が可能となります。

>ゼロトラストアーキテクチャ（ZTA）：伝統的な周辺保護モデルに挑戦する最新のサイバーセキュリティアプローチであり、組織がユーザーやデバイスを自動的に信頼しないことを前提としています。認証、最小特権アクセス、マイクロセグメンテーション、データの暗号化などが重要な原則として挙げられています。

>IoT（モノのインターネット）：物理的なデバイスがインターネットを介してデータを収集・交換するIoTは急速に発展しています。AWS、Azure、Google Cloudなどのプラットフォームを利用して、IoTアプリケーションのためのシステムを構築することが重要です。

>エルゴノミックキーボード：直接的には関連しないが、開発者にとって重要なトピック。長時間のタイピングやコーディング作業において、快適性と健康を考慮したエルゴノミックキーボードが注目されています。快適さと健康を重視することで、生産性が向上し、作業中の中断が減少するとされています。

>これらのトレンドは、2024年のバックエンドとWeb開発において重要な役割を果たし、開発者や製品所有者にとって有益な方向性を示しています。



## ほか参考

近年はそんな、まとめ記事を読むより、ツールを駆使した方が色々情報にたどり着けそうだなという感想です。それがまさに AI の技術を利用して、開発プロセスの効率化を図る って話なのかもしれないです。

https://radixweb.com/blog/best-backend-frameworks

https://www.turing.com/resources/backend-frameworks

メモがてら、「Top 10」フレームワークは以下らしい。

> 4. Top 10 backend frameworks in 2024
4.1. 1. Laravel
4.2. 2. Django
4.3. 3. Spring Boot
4.4. 4. Ruby on Rails
4.5. 5. ASP.NET Core
4.6. 6. Express.js
4.7. 7. NestJS
4.8. 8. Koa.js
4.9. 9. Flask
4.10. 10. Phoenix

以上です～。
【Wagtail】 Formsのデータをモデル別でフィルタする

Form builderを使うと、お問わせフォームなどが管理画面で入力項目のフィールドの内容や数を、
自由に追加・編集・削除することができる。

https://docs.wagtail.org/en/latest/reference/contrib/forms/

このフォームから送信されたデータは、管理画面の"Forms"というメニューが追加され、
ここでフォームごとに一覧でデータを見ることができる。

このデータを、自作のテンプレートで特定のフォームに絞り表示したいということがあったのでやり方をメモする。


フォームに投稿されたデータを扱うには、FormSubmissionを使用する。

```python:moedls.py
#フォームに投稿されたデータの取得
from wagtail.contrib.forms.models import FormSubmission

```

また、データはこのようにすれば取得できる。


```python:moedls.py
from wagtail.contrib.forms.models import FormSubmission

    ///省略///
    
    submissions = FormSubmission.objects.all()
    
    ////省略///
    

```
ただし、これでは全てのデータが取得される。
フォームごとに抽出するには、slugをフィルタ条件にして絞り込む。
slugとは、ページにアクセスするときのパラメータで、管理画面でprometeという入力項目である。

```python:moedls.py
    submissions = FormSubmission.objects.filter(page_id=FormPage.objects.get(slug='prometeの入力内容').id)
```
AivenによるUptime開発者会議の紹介

<font color="Grey">*[Introducing the Uptime Developer Conference by Aiven](https://aiven.io/blog/introducing-the-uptime-developer-conference-by-aiven)の翻訳です。*</font>

2022年2月18日

# AivenによるUptime Developer Conferenceの紹介

2022年9月14日～15日にアムステルダムで開催されるUptime Conference。オープンソースデータコミュニティに直接会い、クラウドにおけるあらゆるデータについて語り合いましょう！

今年の9月に**Uptime**と呼ばれる開発者カンファレンスを開催することを[ニュース](https://twitter.com/aiven_io/status/1489237310600327171)でご存知かもしれません。このブログポストでは、カンファレンスとその対象者について、よくある質問について説明します。Uptimeの**Call for Presentations**は募集中ですので、もしすでに講演のアイデアがおありでしたら、[CFPフォーム](https://sessionize.com/uptime-conference-2022/)から**3月9日**までにご提出ください。


## アップタイムとは？


Uptimeはオープンソース技術に焦点を当てた**クラウドデータインフラ会議**です。オープンソースデータコミュニティが一堂に会し、複雑なシステムの構築と運用に関するベストプラクティスを共有することを目的としています。


これは開発者向けのカンファレンスであり、自他共に認める完全なオタクである私たちは、可能な限り技術的な内容を詰め込みたいと考えています。もちろん、対面のイベントなので、社交の場と刺激的な会話のための時間は十分に残しておくつもりだ！


このイベントは9月14日、15日にアムステルダムの[Pakhuis de Zwijger](https://dezwijger.nl/)で開催されます（ウェブサイトはほとんどオランダ語なので、オランダ語が話せない方はごめんなさい。）この会場は車でも公共交通機関でもアクセスしやすく、私たちの前にも多くの技術イベントが開催されています。


## アップタイムは誰のためのもの？


このカンファレンスは、開発者、アーキテクト、データエンジニア、DevOpsプロフェッショナル、そしてオープンソースデータに情熱を持つすべての人を対象としています。PostgreSQL®、Apache Kafka®、Redis™、Apache Flink®、Grafana®などのオープンソースツールのユースケースや、データエンジニアリング分野とクラウドインフラストラクチャにおけるベストプラクティスに焦点を当てています。


以下はカバーする予定のトピックの一部です：


* クラウドデータアーキテクチャ
* データエンジニアリング
* 分散システム
* 開発者ツール（Observability、モニタリングとアラート、SREとパフォーマンス）


## 面白そうですね。どうすれば参加できますか？


この度、[プレゼンテーション募集](https://sessionize.com/uptime-conference-2022/)を開始しましたので、皆様の魅力的なアイデアをお待ちしております！私たちの最優先事項は、聴衆に最高の学習体験を提供することです。オープンソースデータツールに関する最もエキサイティングで有益な講演を募集しておりますので、ご提案をお持ちの方は、**2022年3月9日までに[CFPフォーム](https://sessionize.com/uptime-conference-2022/)からご提出ください。


初めて講演する人や、まだ具体的なアイデアがない人も、ためらわずに思い切って参加してください。あなたの提案が受け入れられるかどうか、あまり心配しないでください。私たちのチームは、投稿のプロセス全体を通してあなたをサポートします。**[uptime-speakers@aiven.io](mailto:uptime-speakers@aiven.io)**を通じて私たちにご連絡ください。私たちは、あなたのアイデアのブレストや指導を喜んでお手伝いします。


## まとめ


この秋のアップタイムへの参加や講演に興味を持っていただければ幸いです。イベントに関する詳しい情報が必要な場合は、**[uptime-hello@aiven.io](mailto:uptime-hello@aiven.io)**までいつでもご連絡ください。9月にアムステルダムでお会いできることを楽しみにしています！


イベントの最新情報はツイッターでフォローしてください：<https://twitter.com/uptimecon>。
抽選ツール開発②

***抽選ツール***を改良して、名前とお題を結びつけるようにしました。




```python3
####################################################
###   お題抽選ツール
####################################################

#ランダムモジュールを呼び出す
import random
#配列を定義する
array1 = []
array2 = []
#人数変数
N = 0
#正の整数が入力されるまで繰り返す
while True:
  try:
    N = int(input("登録人数を指定してください\n"))
    if N <= 0:
      raise ValueError("error!")
    else:
      break
  except ValueError as e:
    print("文字列、小数、負の整数、0を入力しないでください")
    print("正の整数を入力してください")

#配列に名前を登録する
for i in range(0,N):
  name = input("名前を入力してください\n")
  array1.append(name)

#配列にお題を登録する
for j in range(0,N):
  title = input("プレゼンのお題を入力してください\n")
  array2.append(title)

#配列の要素をランダムに並べる
random_array1 = random.sample(list(set(array1)),N)
random_array2 = random.sample(list(set(array2)),N)

#ランダムに並べた名前を1行ずつ出力する。
for k in range(0,N,1):
  man1 = random_array1[k]
  title1 = random_array2[k]
  print(man1 + "さんのプレゼンのお題は" + title1 + "です")
```
mindの研究 その61

# 概要
mindが、謎なので調べてみた。
練習問題やってみた。

# 練習問題
mindでweb serverを書け。九九を実装せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6d86f729-d718-80c5-f72c-d4027a2f8b8a.png)


# サンプルコード

```

九九とは
　数1は　変数
　数2は　変数
　変換後は　文字列実体　長さ　2048
　変換後を　クリア
　変換後に　「HTTP/1.1 200 OK」を　追加し
　０DＨを　変換後に　一文字追加し
　０AＨを　変換後に　一文字追加し
　変換後に　「Content-Type: text/html」を　追加し
　０DＨを　変換後に　一文字追加し
　０AＨを　変換後に　一文字追加し
　０DＨを　変換後に　一文字追加し
　０AＨを　変換後に　一文字追加し
　変換後に　「<html><head><meta charset='sjis'/></head><body><h1>server side mind</h1><form method='get' action='index.html'>」を　追加し
　変換後に　「入力：<input type='text' name='q' size='30'><input type='submit' value='送信'><br><textarea rows='15' cols='50'>」を　追加し
　　9を　回数指定して
　　　回数を　数1に　入れる
　　　9を　回数指定して
　　　　回数を　数2に　入れる
　　　　数1に　数2を　掛けて　文字列変換し　変換後に　追加し
　　　　「 」を　変換後に　追加し
　　　繰り返す
　　　０DＨを　変換後に　一文字追加し
　　　０AＨを　変換後に　一文字追加し
　　繰り返す
　変換後に　「</textarea></form></body></html>」を　追加し
　変換後を　返すこと
。


メインとは
　ホスト名は　文字列
　ポート番号は　変数
　待ちソケットは　変数
　データソケットは　変数
　エラーコードは　変数
　文字列１は　文字列
　文字列2は　文字列
　単語1は　文字列
　「localhost」を　ホスト名に　入れ
　40001を　ポート番号に　入れ
　ホスト名と　ポート番号と　１個で　ｌｉｓｔｅｎし　待ちソケットに　入れ
　エラー？
　ならば
　　エラー文字列で　重大エラー
　つぎに
　ここから
　　「start」を　一行表示する
　　待ちソケットで　ａｃｃｅｐｔし　データソケットに　入れ
　　エラー？
　　ならば
　　　「エラー：」を　エラー出力し　エラー文字列を　一行エラー出力し
　　　打ち切り
　　つぎに
　　ここから
　　　データソケットから　ハンドル指定で一行読み出し　文字列１に　入れる
　　　データ終り？
　　　ならば
　　　　「[EOF]クライアントが終了しました。」を　一行表示する
　　　　打ち切り
　　　つぎに
　　　文字列１から　単語切り出し　単語1に　入れ
　　　もし　単語1が　「GET」に　等しい文字列
　　　ならば
　　　　「get」を　一行表示し
　　　　九九を　文字列2に　入れ
　　　　文字列2を　データソケットに　ハンドル指定で一行書き込み
　　　　打ち切り
　　　つぎに
　　　もし　単語1が　「POST」に　等しい文字列
　　　ならば
　　　　「post」を　一行表示する
　　　　九九を　文字列2に　入れ
　　　　文字列2を　データソケットに　ハンドル指定で一行書き込み
　　　　打ち切り
　　　つぎに
　　繰り返し
　繰り返し
。





```


以上。
[YaSTガイド] openSUSEでmDNSの名前解決ができない

## 概要
弊環境
- openSUSE Leap 15.5
    - NetworkManager 1.38.6
    - avahi-daemon 0.8
    - avahi-dnsconfd 0.8
## 現象
```
YaST → セキュリティとユーザ → ファイアウォール 
→ ゾーンの設定(public, trusted等) → サービス
```
にて、

```mdns```を許可したのに```ssh daresore@hogehoge.local```をしたり、Firefox等のブラウザのURLバーに入力しても、うまく名前解決ができない(繋がらない)

## 対処
```
YaST → セキュリティとユーザ → ファイアウォール 
→ ゾーンの設定(public, trusted等) → ポート
```

にて、
```TCP/UDP 5353番```を許可する

> ポート範囲	TCP/UDP	サービス	詳細	情報
> 5353	tcp	mdns	Multicast DNS	IANA
> 5353	udp	mdns	Multicast DNS	IANA

[Port 5353 (ポート5353) | PORT INDEX](https://hi-nemos.com/port/?port=5353)

## 結果
名前解決できるようになっているハズデス汗
2024/1/4主にITとかセキュリティの記事

ビジネスパーソンが覚えておきたいChatGPTを業務で利用する時のリスク(1/2)
https://dime.jp/genre/1711588/

2023年のSNSと子どもを振り返る【後編】～Twitter変貌、生成AI、法律改正(1/2)
https://ascii.jp/elem/000/004/176/4176740/?rss

ヤバイ「コンピュータウイルス」5選(1/2)
https://nazology.net/archives/119389

警官もだまされた！押した瞬間アウト…韓国で被害拡散「訃報スミッシング」(1/2)
https://www.afpbb.com/articles/-/3498688?cx_part=top_category&cx_position=2
UbuntuでLet's Encryptを使用してSSL証明書を作成する方法

## Let's Encryptとは

Let's Encryptは無料のオープンソースの証明書発行機関で、インターネットセキュリティを強化するために設立されました。ユーザーは簡単にSSL/TLS証明書を取得し、Webサイトの安全なHTTPS接続を実現できます。Let's Encryptは自動化されたプロセスを提供しており、証明書の取得と更新を容易に行えるため、特に小規模なWebサイトや個人の開発者にとって理想的な選択肢です。

## SSL照明証の重要性

SSL（Secure Sockets Layer）証明書は、インターネット上で情報を安全に送受信するために不可欠です。SSL証明書を使用すると、Webサイトとそのユーザー間のデータが暗号化され、第三者によるデータの盗聴や改ざんを防ぐことができます。これは、特に個人情報や金融情報などの機密データを扱うWebサイトにとって重要です。さらに、SSL証明書はWebサイトの信頼性を高め、Googleなどの検索エンジンによるランキング向上にも寄与します。

## Let's Encryptのインストール

```
sudo apt-get install letsencrypt
```

## SSL証明書の発行

まずはnginxを停止する

```
sudo systemctl stop nginx
```

それから以下のコマンドで証明書を取得する。`your_domain`のところはドメイン名を指定する。

```
sudo letsencrypt certonly --standalone -d your_domain.com
```

このようなメッセージが出たら、証明書の発行が成功した。

```
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/your_domain/fullchain.pem
   Your key file has been saved at:
```

## nginxの設定

以下の例は`your_domain.com`に対する設定です。

```nginx:/etc/nginx/sites-available/your_domain.com
server {
  listen 80;
  server_name localhost your_domain.com;
  return 301 https://$host$1$request_uri;
}

server {
  listen 443 ssl http2;
  ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
```

## 証明書の更新

### 手動の場合

SSL証明書の有効期限は90日なので、まだ期限が切れないうちに更新する必要があります。

更新するには、まずはnginxを停止して、SSLを更新して、それからnginxを起動するフローです。

```
sudo systemctl stop nginx
sudo letsencrypt renew
sudo systemctl start nginx
```

これによってウェブサーバーが一旦停止されるのが留意点。

### 自動の場合

cronで自動化することができます。設定するには `sudo crontab -e`コマンドを実行して、それから以下の内容を入れます。

```
# Renew the Let's Encrypt SSL certificates at 3:00 AM on the 1st of every month
00 03 01 * * sudo systemctl stop nginx; sudo letsencrypt renew; sudo systemctl start nginx
```

保存してから反映されます、サーバーの再起動は必要ありません。

これによって、毎月1日の朝3時に、nginx停止 → SSL証明書更新 → nginx起動というフローで自動的にSSL証明書が更新されます。

午前3時を設定する理由は、その時にサイトを利用するユーザーがあまりいないからです。
【Shopify】theme コマンドについて

:::note alert
編集中
:::

# shopify theme init
Gitリポジトリからローカルにテーマのコピーを作成する。
コピーされるテーマは、デフォルトで「Dawn」。

```
shopify theme init
```

その際に、名前を入力することになりますが、これはコピーしたテーマをローカルで保管するフォルダ名。
フォルダの名前付けと、コピーしたいテーマを選択したい場合は下記コマンド。

```
shopify theme init [フォルダ名] -u[コピーを作成したいテーマのgitリポジトリのURL]
```
# shopify theme check

<!--
GitHub連携
・https://goriderep.com/blogs/news/shopify-github#:~:text=Shopify%E3%81%AE%E7%AE%A1%E7%90%86%E7%94%BB%E9%9D%A2%E3%81%8B%E3%82%89%E3%80%81%E3%80%8C%E3%82%AA%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%82%A2%E3%80%8D%3E%E3%80%8C,%E6%83%85%E5%A0%B1%E3%82%92%E5%85%A5%E5%8A%9B%E3%81%97%E3%81%BE%E3%81%99%E3%80%82
こちらの生地のほうが新しい

・https://skillhub.jp/blogs/324
-->

<!--
shopify theme コマンドについて
https://zenn.dev/kosuke_shopify/articles/1ca293392a3d5b
<!--
Zip格納されたCSVファイルをHTTPレスポンスから直接取り出す

## TL;DR　

オープンデータを提供しているサイトから、ZIPファイルに格納されたCSVファイルをダウンロードし、データを取り出す際、ダウンロードしたファイルを一旦保存して処理するアプローチを取りたくなかったので、HTTPレスポンスからストリーム経由で直接データ抽出するアプローチを採用してみました。

HTTPクライアントにはfaradayを採用していますが、通信周りの処理見直しは必要なものの、他のライブラリでも大丈夫だと思います。

他の方の参考になれば幸いです。

### 留意点

HTTPレスポンスが分割されるケース（チャンク形式）に耐えられるか確認してません。

``` ruby

require 'faraday'
require 'stringio'
require 'zip'

class FetchCsvService

  BASE_URL = 'https://www.opendata.metro.tokyo.lg.jp/'

  def initialize
    @conn = Faraday.new(BASE_URL) do |builder|
      builder.request :url_encoded
      builder.adapter Faraday.default_adapter
    end
  end

  def fetch

    response = @conn.get do |req|
      req.url 'gesui/yosanan4.zip'
    end

    if response.success?
      Zip::File.open_buffer(StringIO.new(response.body)) do |files|
        files.each do |file|
          next unless file.name.end_with?('.csv')
          csv = file.get_input_stream.read.encode('utf-8', 'sjis', invalid: :replace, undef: :replace, replace: '').split("\n")

          puts "=== " + file.name.encode('utf-8', 'sjis') + " ==="
          csv.each do |row|
            # ここに具体的な処理を記述
            puts row
          end
        end
      end
    else
      puts "Request failed with status #{response.status}"
      puts response.headers
      puts response.env.url
      response.status
    end
  end

end

```


```:結果
～　略　～
建設事業費,,,"180,000",,"180,000",,0,
=== 令和４年度予算要求概要資料CSVファイル/yosanyoukyuR4_08.csv ===
,,,,,,,（単位：千円）,
事項１,事項２,４年度見積,３年度予算,増 減,建設事業区分・規模,,区分１,区分２
流域下水道建設費,,"14,500,000","14,500,000",0,管渠工事,２ か所,,
財源内訳,企業債,"894,000","790,000","104,000",水再生センター,７ か所,,
財源内訳,国庫補助金,"8,630,000","8,595,000","35,000",,,,
財源内訳,市町村建設負担金,"2,910,000","2,930,000","-20,000",,,

～　略　～

```
DOTweenPro用のTMPro文字アニメーションをタグで指定できるようにしたテキストボックスを作った

# はじめに
コチラのタグ機能を実装ついでに作りました。
これを使って実装しているため以下の記事も見てください。

https://qiita.com/bloody_sweets/items/8a81af0b6e1aac6eb062

https://qiita.com/bloody_sweets/items/4cf76f24e7683662a923

# Github
[TMP_DOTweenTemplate](https://github.com/Blood421/TMP_DOTweenTemplate)

# 使い方
1. DOTween Pro(有料)をAssetStoreからインポート
2. GithubからTMP_DOTweenTemplateAll.unitypackageをダウンロードしてインポート
デモシーン入りなので最初にそこを見てください。
以下動画は手順動画です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/s3huEFANOf8?si=ZbI3VqIFhPrM954V" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
DOTweenPro用のTMProの自作タグで囲んだ文字をアニメーションさせるシステムを作った

# はじめに
DOTweenProのTMPro文字アニメーションのテンプレを作ったあとこんなのあったら便利だなで作りました。

https://qiita.com/bloody_sweets/items/4cf76f24e7683662a923

# Github
[TMP_DOTweenTemplate](https://github.com/Blood421/TMP_DOTweenTemplate)

# 使い方
1. DOTween Pro(有料)をAssetStoreからインポート
2. GithubからTMP_DOTweenTemplate.unitypackageとTMP_DOTweenTagAnimator.unitypackageをダウンロードしてインポート

デモシーン入りなので最初にそこを見てください。
以下動画は手順動画です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/wZhgYKYnL5Q?si=QkITO54P26YMUmza" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

このコンポーネントをアタッチすることを忘れずに動画の手順で設定すると動作します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/3ad1cd0c-9cc3-6d04-8df4-17fb40e02c4b.png)

# 最後に

これを使ったテキストボックスがコチラにあるのでよかったらみてください

https://qiita.com/bloody_sweets/items/6a0a2c0f11dbf1100c9a
NetplanやNetworkManagerが導入されていない環境で一時的にネットワークを疎通させたいときのコマンド


NetplanやNetworkManagerが導入されていない環境において、一時的にネットワークを疎通させたい時は、次のように設定します。（NetplanやNetworkManagerは後からdnfやaptでインストールすることを想定）

# 設定例

## 条件
- NICは `eth0`
- IPアドレスは `10.1.0.11` を割り当てる
- サブネットは `/24` (`255.255.255.0`)
- デフォルトゲートウェイのIPアドレスは `10.1.0.1`
- DNSサーバは Google Public Dns (`8.8.8.8`) をとりあえず指定 ( `/etc/resolve.conf` は一切設定されていない＝空の状態であることを想定）

## コマンド

```
# ip addr add 10.1.0.11/24 dev eth0
# ip route add 10.1.0.1 dev eth0
# ip route add default via 10.1.0.1
# nameserver 8.8.8.8 > /etc/resolve.conf
```
DOTweenPro用のTMPro文字アニメーションテンプレートを作った

# はじめに
毎回DOTweenProを使って文字アニメーションを実装するが面倒だったのでテンプレートを作ることにしました。

# Github
[TMP_DOTweenTemplate](https://github.com/Blood421/TMP_DOTweenTemplate)

# 使い方
1. DOTween Pro(有料)をAssetStoreからインポート
2. GithubからTMP_DOTweenTemplate.unitypackageをダウンロード後インポート
デモシーン入りなので最初にそこを見てください。
以下動画はデモシーンの実行動画です。

アニメーションの種類は通常の透過度や移動などが16種類、マテリアルアニメーションが7種類、アニメーションの複合が5種類あります。

<iframe width="560" height="315" src="https://www.youtube.com/embed/NGESUCFSfkE?si=aaemdOA5Xb_ea_mi" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


基本的にはコンポーネントをアタッチしてPlayメソッドを呼ぶだけです。
色のアニメーションの場合こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281232/1e68d70d-9db6-dce3-35c0-33bd208d24c4.png)

# 最後に

これを使ったものがコチラにあるのでよかったらみてください

https://qiita.com/bloody_sweets/items/8a81af0b6e1aac6eb062

https://qiita.com/bloody_sweets/items/6a0a2c0f11dbf1100c9a
ゼロ除算のショートハンド

## 何をしたか

よくありそうな除算の結果を少数切り捨てして、0除算の場合は任意の値(例えばゼロとかエラー文字列)を返す式を短く書く方法を研究した結果こうなりました。

``` js
function divide(a, b) {
  return a / b | 0;
}
```

論理和(`||`)じゃなくてビット論理和( `|`)です


## 何故こうなるのか

JavaScriptにおいて数値は内部的に64ビットの浮動小数点数（IEEE 754形式）として扱われるが、ビット演算は32ビット整数で行われるため、この過程で浮動小数点数から整数への変換が行われます。
またJavaScriptでは、`a / b`のbが0の場合、結果は`Infinity`または`-Infinity`になります。これらは浮動小数点数の表現であり、次のビットパターンで表されます。


### `Infinity`の64ビット二進数表現の変換過程

```
0111111111110000000000000000000000000000000000000000000000000000
```

上位32ビット（切り捨てられる部分）:
01111111111100000000000000000000

下位32ビット（残される部分）:
00000000000000000000000000000000

### `-Infinity`の64ビット二進数表現の変換過程

```
1111111111110000000000000000000000000000000000000000000000000000
```
上位32ビット（切り捨てられる部分）:
11111111111100000000000000000000
下位32ビット（残される部分）:
00000000000000000000000000000000

変換過程で`Infinity`や`-Infinity`は、IEEE754形式の浮動小数点数で特定のビットパターンを持ちます。しかし、これらの値を32ビット整数に変換する際にビット情報が失われ、「丸め込まれる」結果となり0になります。

## 結局のところ実用的じゃないとは思う

ビット演算は`Math.floor()`など関数用いるよりパフォーマンスに優れるという情報も見かけましたが未検証です。

ここまで調べてみて非常に興味深い挙動だったのですが、多分一般的で無さすぎて可読性が劣ってしまいます。

あと32ビット整数が表現できるのは、符号付き整数として最大約±2.1億（具体的には-2,147,483,648から2,147,483,647まで）の範囲で、これを考慮していると短く書こうとした目的から外れてしまう結果になる気がします。


```
> 2147483648|0

-2147483648
```

実用に用いるのはやめて無難にこんな感じにします…

``` js
function divide(a, b) {
  const result = a / b;

  if(Number.isFinite(result)) {
  // エラーハンドリング
  }

  return Math.floor(result);
}

```
Scala 3 の opaque type で型クラスを宣言する際の注意点

## はじめに

Scala 3 で `opaque type` という Haskell の `newtype` に似た機能が実装されました。
https://dotty.epfl.ch/docs/reference/other-new-features/opaques.html
`opaque type` で型クラスを宣言する時にハマったので、その備忘録として残しておきます。
Scala の version は 3.3.1 現在のものとします。

## 背景

以下の型クラスを定義します

```scala
trait Eq[A] {
  def eqv(x: A, y: A): Boolean
}
```

この型クラスを String で宣言します

```scala
given Eq[String] with {
  override def eqv(x: String, y: String) ＝ x ＝＝ y
}
```

このような状態で String の opaque type を定義します。

```scala
object MyStringWrapper:
  opaque type MyString = String
  object MyString:
    def apply(value: String); MyString = value
```

MyString は `MyStringWrapper` の外だと String と違うため Eq のインスタンスとはなっていないです。実際に試してみるとコンパイルエラーとなるのがわかります。
```scala
summon[Eq[String]].eqv("a", "b") // こっちは OK

import MyStringWrapper.MyString
summon[Eq[MyString]].eqv(MyString("a"), MyString("b")) // MyString は Eq のインスタンスではないのでコンパイルエラー
```
MyStringWrapper に対して型クラスを宣言していきます。

## Opaque Type で型クラスを宣言する

### 間違えた実装

最初に考えたのが、`MyString` は `String` を ラップしたようなものなので、その情報を使うように以下のように実装しました

```scala
object MyStringWrapper:
  opaque type MyString = String
  object MyString:
    def apply(value: String); MyString = value
    given Eq[MyString] with {
      override def eqv(x: MyString, y: MyString) = summon[Eq[String]].eqv(x, y)
    }
```

この実装はコンパイルエラーにならず一見良さそうに思いますが実際に実行してみると、値が返ってこなくなります。

```scala
import MyStringWrapper.MyString
summon[Eq[MyString]].eqv(MyString("a"), MyString("b")) // コンパイルエラーとならないが実行すると値が返ってこない
```
### 何が行けなかったのか

opaque type は同一 scope 内だと、type alias とみなされます。[^1]
先ほどの実装だと、`MyString` と `String` が同一の型とみなされて無限ループとなり値が返ってこなかったようです。[^2]
[^1]:within the scope, it is treated as a type alias, but this is opaque to the outside world where, in consequence https://dotty.epfl.ch/docs/reference/other-new-features/opaques.html
[^2]:ここに詳しい挙動について説明があります https://github.com/circe/circe/issues/1829#issuecomment-969658521

### 別のスコープで実装するようにする

```scala
object MyStringWrapper:
  opaque type MyString = String
  object MyString:
    def apply(value: String): MyString = value
    extension (x: MyString) def value: String = x


object GivenMyString:
  import MyStringWrapper.MyString
  import MyStringWrapper.MyString.value
  given Eq[MyString] with {
    override def eqv(x: MyString, y: MyString): Boolean =
      summon[Eq[String]].eqv(x.value, y.value)
  }
```

`MyString` の スコープ外から、定義した時別の型として扱われるため、変換用のメソッド `value` を定義しています。実行すると値が返るようになります。

```scala
import MyStringWrapper.MyString
summon[Eq[MyString]].eqv(MyString("a"), MyString("b")) // false となる
```
## まとめ
Play framework も Scala 3 が対応されたことにより Scala 3 を使う機会がこれから増えるようになると思い Scala 3 を入門してみましたが、opaque type のところではまってしまいました。もし参考になるのであれば幸いです。また面倒な実装となっているのでこれよりも良い方法がある場合は是非とも教えてほしいです。
Vapespring

<a href="https://www.vapespring.com/">VAPESPRING</a>

<a href="https://www.vapespring.com/products">Products |</a> <a href="https://www.vapespring.com/flavors">Flavors |</a> <a href="https://www.vapespring.com/blog">Blog |</a> <a href="https://www.vapespring.com/videos">Videos |</a>  <a href="https://www.vapespring.com/pods">Pods</a>
AWS ChatBotからAmazon Qを活用する

# 実施した内容
https://blog.serverworks.co.jp/chatbot_amazon_q

# メモ1(AWS CLI)
AWS CLI を実施する時は適切なIAMロールが追加で付与が必要。
例えば以下のようにEC2の一覧を見ようと思って叩きたい場合は
```sh
@aws ec2 describe-instances --region ap-northeast-1
```
![スクリーンショット 2024-01-03 23.49.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292878/996358b7-2afa-c04a-05f5-a47aa9056e5a.png)

IAMロールに`AmazonEC2ReadOnlyAccess`のポリシー追加が必要。
叩いてみると、いくつかパラメータを聞かれるが Skip していると値が返ってくる。
![スクリーンショット 2024-01-03 23.52.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292878/9b0613da-e3ae-8c0e-b732-f10749fd3cd0.png)


# メモ2(英語での質問/リソース確認)
リソースも確認できるようだが、リソースを確認するための質問の仕方が分からない・・・
例にならって聞いてみてもAWSドキュメントを案内される。
AWSリソースを読み取って回答はしてくれない。
AWSリソースが気になるならAWS CLIで渡すしかないのかな・・・？

EC2は`What EC2 Resources do I have?`で表示された。(5リソースだけ・・・)

```sh
@aws Do you have an Amazon EventBridge rules?
:1:Best practices when defining Amazon EventBridge rules - Amazon EventBridge
...example of resource policies, see Multi-account design patterns with Amazon EventBridge on GitHub. Monitor rule performance Monitor your rules to make sure they are performing as you expect...

:2: Amazon EventBridge rules - Amazon EventBridge
...of rules: Topics Creating Amazon EventBridge rules that react to events Using Amazon EventBridge Scheduler with Amazon EventBridge Creating an Amazon EventBridge rule that runs on a...

:3: Sending and receiving Amazon EventBridge events between AWS accounts - Amazon EventBridge
...bus in another account as a target is part of creating the rule. To create a rule that sends events to a different AWS account using the console Follow the steps in the Creating Amazon EventBridge rules that react to events procedure. In the Select targets step, when prompted to...
```
![スクリーンショット 2024-01-04 0.03.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292878/faee4800-9dec-a5a0-7f1c-f64ce8a8e406.png)

```
ちなみにどれもダメだった・・・AWS CLI を案内された。
@aws What Amazon EventBridge rules Resources do I have?
@aws What EventBridge rules Resources do I have?
@aws What EventBridge Resources do I have?
```


# メモ3(日本語での質問)
https://aws.amazon.com/jp/about-aws/whats-new/2023/11/aws-chatbot-q-conversations-teams-slack/
![スクリーンショット 2024-01-04 0.04.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292878/ea608738-7ac2-60c2-daf7-c9f633011ece.png)
質問してみたが、想定した回答は返ってこなかった。
![スクリーンショット 2024-01-04 0.07.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2292878/6fc121c5-c4f1-fc30-932a-31da83b17d53.png)


# 最後に
セットアップ自体は簡単に終わりました。
ただ、実用イメージはあまり湧きませんでした。
AWS CLI ベースでリソースを確認していくしかないのであれば、shスクリプトでも書いた方がスマートな気がします。
あとは日本語対応、適切な質問方法が分かると利用頻度が上がりそうですね。
GitHub認証 ローカルで動かす OAuth-practice

Next.js + Supabase <=ローカル開発環境を作成

# OAuth 2.0のフロー

GitHub の OAuth 2.0 のフローを説明します。

Next.jsのアプリがGitHubの認証プロバイダーにアクセスします。
そうするとコードを取得できます。
そのコードをそのままもう一度GitHubの認証プロバイダーに送信します。

GitHubの認証プロバイダーはそのコードを検証します。
検証が正しかった場合、アクセストークンを発行します。

そうするとGitHubの認証プロバイダーからアクセストークンが送られてきます。

アクセストークンを持っていると、そのアクセストークンが生存している間は、Next.jsのアプリはGitHubのユーザーであることを証明できます。





注意点
環境変数.envファイルではダブルクォーテーションで囲みます。
localhost は 127.0.0.1 にします。
末尾にスラッシュはつけません。

良い例
`http://localhost:54321/auth/v1/callback`

悪い例
`http://localhost:54321/auth/v1/callback/`



# GitHub認証

GitHubのOAuth Appを新規作成します。
そうするとGitHub認証の環境変数が取得できます。

ローカル開発環境用のGitHub認証ができる環境変数を取得します。

## GitHubへアクセス

最初に GitHub

https://github.com

にアクセスします。

右上のユーザーが表示されているアイコンから
Settings
そして
左サイドバーの
Developer settings
を選択します。

GitHub Apps

https://github.com/settings/apps

そうすると↑この場所に来るので、ここから

左サイドバーの
OAuth Apps
を選択します。

次に、
右上の 「New OAuth App」 ボタンを押します。

必要な項目を埋めていきます。

```
Application name
oauth-practice (適当な名前)

Homepage URL
http://localhost:3000

Authorization callback URL
http://localhost:54321/auth/v1/callback

```

※↑ローカル開発環境の場合

項目を埋めたら 緑色の 「Register application」 ボタンを押します。

そうすると、次の項目の値が生成されます。

```
Client ID
85ff....

Client secrets
af8a....

```

取得したClient ID等を .env に書き込みます。




```.env
GITHUB_CLIENT_ID={GITHUBのクライアントID}
GITHUB_SECRET={GITHUBのクライアントシークレット}

```

例

```.env
GITHUB_CLIENT_ID="85ff...."
GITHUB_SECRET="af8a...."

```

※ ↑環境変数はダブルクォーテーションで囲みます。




OAuth登録時のローカルでの設定例

※名前は自由につけます。

※ローカルで動かすには、URLは `localhost` ではなく `127.0.0.1` にする必要があります。

![Qiita GitHubOAuth登録情報.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/e52868ff-ae1f-6570-6ecc-99ecc2aef6fb.png)

※Supabaseでの設定が 127.0.0.1 と固定されているため(だと思う)

GitHub側では `localhost` を `127.0.0.1` 自動変換してくれないため(だと思う)



# Supabaseの設定ファイル

GitHub
と
Google
の例


```supabase\config.toml
[auth.external.github]
enabled = true
client_id = "env(GITHUB_CLIENT_ID)"
secret = "env(GITHUB_SECRET)"
redirect_uri = "http://127.0.0.1:54321/auth/v1/callback"

[auth.external.google]
enabled = true
client_id = "env(GOOGLE_CLIENT_ID)"
secret = "env(GOOGLE_SECRET)"
# Overrides the default auth redirectUrl.
redirect_uri = ""

```


Local Development | Supabase Docs
https://supabase.com/docs/guides/cli/local-development#use-auth-locally
【React】useEffectで非同期処理を行う方法

## 無名async関数

```react
useEffect(() => {
  (async () => {
    await sampleFunc()
  })()
}, [])
```

## async関数

```react
useEffect(() => {
  const sample = async() => {
    await sampleFunc()
  };
  sample()
}, [])
```