dockerを安くデプロイしたい【備忘録】【読みづらい】

# はじめに
ローカルでdockerを用いて簡単なアプリケーションを作った。
それをデプロイしようと思ったのだが、なんせ高い。
amazonのVPCとか使うと高そう。

なのでそれをどう安く公開できるのかを探りながら実装してみた。

そして、備忘録なので読みづらいですよ。
もくじを見ながら読むと読みやすいかも。

# 決定方針メモ
- deployするものはすでに作成済みのものを使う。
- AWSは使わない
    - すでにできているものを使うのは本質を理解できづらいし、何より高い
- さくらインターネットを使う
    - https://vps.sakura.ad.jp/
    - 安いし、メンターの人におすすめされたのでとりあえず
- 本番環境でdockerは使わない

# こんどやるメモ(今回はやらない)
- domain設定
- ロードバランサー設定
- CICD
- サーバー間通信
    - https://vps.sakura.ad.jp/feature/lnw.html
- applicationの日本語化
    - なんかmysqlに日本語かとうろくできない。
- サーバー起動時にすべてのサービスを起動する

# 構成
激クソシンプルマイクロサービス。
↓ シンプル図
![スクリーンショット 2023-01-02 15.28.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/5ea7134d-1ca9-ce7b-feb3-a8947da8ebf3.png)

# やってみた
## まずは
deployの概要を知りたいので、これをみました。

https://www.youtube.com/watch?v=HvrIPQ77xRY

なんとなくわかった。
たぶん以下がひつよう。

- VPC
- サブネットの設定
- Gatewayの設定
- サーバーの設置(DB, Client, Server用)
- サーバーの設定(アプリケーションサーバー、Webサーバーなど)

そして、docker-composeっていう概念をdeployするのって難しいのかなって思った。
dockerは「パソコン上に仮想のサーバーを作成するもの」っていう前提があるので、このままネット上に上げてしまうと、一つのサーバーの中に複数の仮想サーバーをつくつようになってしまう。

今回はそうじゃない、サービスひとつひとつごとにサーバーを準備して、サーバー間でやり取りをしたいのだ。

## さくらインターネットをとりあえず準備

https://vps.sakura.ad.jp/

こちらで申し込み。
ゾーンは一番安いので。
プランは毎月。
一番小さい512MBから。

![スクリーンショット 2022-12-10 11.21.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/b2dfec4b-aa20-6ad9-440c-ee16d50a0ff4.png)

ストレージも最小で。
購入台数は、DB, client, backの3つ分。
冗長性持たせるのはあとで。

![スクリーンショット 2022-12-10 11.22.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/35479643-4f8d-ba09-c4f2-375ecead3734.png)

適当に名前をつける
![スクリーンショット 2022-12-10 11.24.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/f19f32f6-38a6-4d1f-ffbc-e2ef8d65c53d.png)

OS設定、どうしよ。
CentOSはサポート終了しているっぽいからやめよう。
CentOSがサポート終了した裏には、コミュニティサービスじゃない(企業作成)からくる要因があるそうな、だからKUSANAGIもやめよう。
ubuntuは使ったことあるから今回はなしで。
AlmaLinuxの方が人気と勢いがありそうですが、Googleが推しているのとより企業感の薄いRockyLinuxにしようと思います。

![スクリーンショット 2022-12-10 11.46.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/ec5ebe67-794b-9fe2-161b-9f4910d403b1.png)

スタートアップスクリプトは利用しない。(自分でやりたい)

![スクリーンショット 2022-12-10 11.47.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/9c086b07-12fd-c361-d18d-133f55f71ecc.png)

パケットフィルターはよくわからんけどとりあえず利用。
SSHキーは登録する。
![スクリーンショット 2022-12-10 11.49.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/7dd8a847-9e9a-2d26-9e0a-2f549f304e63.png)

クレジットカードで決済したら、サーバーの準備は完了。

# デプロイ
## サーバーに入ってみる
そしたら、先ほど登録したサーバーにterminalから入ってみよう。

```bash:terminal
$ ssh root@ipアドレス
ipアドレス's password:
Permission denied, please try again.
```

あれ、入れない。
てかそもそもsshkeyを登録したはずだからpassword要求されるのもおかしい。
と思ったら、そもそもユーザー名が違うっぽい。
rocky linuxを使っていると、管理ユーザー名はrockyになるらしい。

https://manual.sakura.ad.jp/vps/support/info/administrative-userl-login.html

```bash:terminal
$ ssh rocky@ipアドレス

SAKURA internet [Virtual Private Server SERVICE]

Last login: Sat Dec 10 13:16:42 2022 from ***.**.**.***
[rocky@host_name ~]$ ls -a
.  ..  .bash_logout  .bash_profile  .bashrc  .ssh
[rocky@host_name ~]$ 
```

おお、入れた。初期状態だからそりゃファイルはないわな。

## CD調査(本編と関係ない)
いまはやらないけれども、一通りサーバーに上げられたらCI・CDもやってみたい。
その時を見越した上でのデプロイをしたいので、一旦CDについて調査する。

調べてみたら、CircleCIやJenkinsなどがあったが、GithubActionsを想定してみようと思う。

https://knowledge.sakura.ad.jp/23478/

https://tiplib-web.com/tips/220214_deploy/

読んでみた(4割くらい)結果、結構簡単に実装できそうなことがわかった。
あと、本番サーバーに上げるのはやっぱりFTPで上げるっぽい。

ここまでわかれば一旦はおk

## デプロイ
開発環境ではdockerを用いていたので簡単に環境を作ることができたが、
本番環境はdockerを使わないことにしたので、調査をする必要がある。
予想としては、そんなに大変だとは思っていない。(dockerでやることを手でやるだけだと思っている)

### client
#### node導入
localで開発したdockerファイルを見てみると、nodeがinstallされていたので、rockylinuxにnodeを入れる。

https://www.server-world.info/query?os=Rocky_Linux_8&p=nodejs&f=3

```bash:terminal(remote)
[rocky@host_name ~]$ curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -

## Installing the NodeSource Node.js 16.x repo...

## Inspecting system...

+ rpm -q --whatprovides redhat-release || rpm -q --whatprovides centos-release || rpm -q --whatprovides cloudlinux-release || rpm -q --whatprovides sl-release || rpm -q --whatprovides fedora-release
+ uname -m
・
・
・

[rocky@host_name ~]$ sudo yum install -y nodejs
Node.js Packages for Enterprise Linux 9 - x86_64                                                                                                                            125 kB/s | 188 kB     00:01
Dependencies resolved.
=================================================================================================
 Package                                     Architecture                                Version 
・
・
・
Installed:
  nodejs-2:16.18.1-1nodesource.x86_64

Complete!
```

yumで入れたが、やべ、間違えた。
バージョン16.15.0が良いんだが。。
```bash:terminal(remote)
[root@host_name ~]# yum remove nodejs
[root@host_name ~]# yum install nodejs-16.15.0
Last metadata expiration check: 0:04:05 ago on Sat 10 Dec 2022 03:19:36 PM JST.
Dependencies resolved.
=================================================================================================
 Package                                     Architecture                                Version 
・
・
・
Installed:
  nodejs-2:16.15.0-1nodesource.x86_64

Complete!
[root@host_name ~]# node -v
v16.15.0
```
おけ。

#### アプリケーションを本番環境に配置する
フォルダ構成はFSSTNDだそうなので、ソースコードは`/usr/local/src/`に配置する。

```bash:terminal(local)
$ scp app.zip rocky@ipアドレス:/usr/local/src
scp: /usr/local/src/app.zip: Permission denied
```

へ？原因を調べたら、権限付与されてないっぽい。
入ってみて、権限調べたら、

```bash:terminal(remote)
[rocky@host_name ~]$ cd /usr/local
[rocky@host_name local]$ ll
total 40
drwxr-xr-x. 2 root root 4096 May 16  2022 bin
drwxr-xr-x. 2 root root 4096 May 16  2022 etc
drwxr-xr-x. 2 root root 4096 May 16  2022 games
drwxr-xr-x. 2 root root 4096 May 16  2022 include
drwxr-xr-x. 2 root root 4096 May 16  2022 lib
drwxr-xr-x. 3 root root 4096 Jul 19 16:14 lib64
drwxr-xr-x. 2 root root 4096 May 16  2022 libexec
drwxr-xr-x. 2 root root 4096 May 16  2022 sbin
drwxr-xr-x. 5 root root 4096 Jul 19 16:14 share
drwxr-xr-x. 2 root root 4096 May 16  2022 src
```

書き込み権限と所有者がrootになってる...？
あれ、CentOSでいうrootがRockyでいうrockyかと思っていたがどうやら違うっぽい。
んで、調べてみたら、どうやら初期状態はrootユーザーはロックされているけど、passwordを設定すればログインできるようになるっぽい。

https://manual.sakura.ad.jp/vps/os-packages/rockylinux-8.html#id3

ということでpasswordを変更する。
```bash:terminal(remote)
[rocky@host_name ~]$ sudo passwd root
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
```
これでrootでtcpしてみよう。
```bash:terminal(local)
$ scp app.zip root@ipアドレス:/usr/local/src
root@ipアドレス's password:
Permission denied, please try again.
```
...そもそもログインできない
調べてみたら、rootログインするのにパスワードだけじゃなくて、configの設定がいるそうな。

https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/422sshokroot.html

だけど、そもそもセキュリティ的に大丈夫なんか？と思ってきた。rootでログインするのはやめます。
rockyの権限を/usr/local/srcも触れるようにしましょ。
所有ユーザーをrootから変えるのは忍びないので、所有グループをrockyにする。

```bash:terminal(remote)
# rockyからrootでログイン
[rocky@host_name ~]# su -
Password:
Last login: Sat Dec 10 16:28:51 JST 2022 on pts/0
Last failed login: Sat Dec 10 16:29:40 JST 2022 from ***.**.**.*** on ssh:notty
There were 3 failed login attempts since the last successful login.
[root@host_name ~]# cd /usr/local
[root@host_name local]# chown root:rocky src/
[root@host_name local]# ll
total 40
drwxr-xr-x. 2 root root  4096 May 16  2022 bin
drwxr-xr-x. 2 root root  4096 May 16  2022 etc
drwxr-xr-x. 2 root root  4096 May 16  2022 games
drwxr-xr-x. 2 root root  4096 May 16  2022 include
drwxr-xr-x. 2 root root  4096 May 16  2022 lib
drwxr-xr-x. 3 root root  4096 Jul 19 16:14 lib64
drwxr-xr-x. 2 root root  4096 May 16  2022 libexec
drwxr-xr-x. 2 root root  4096 May 16  2022 sbin
drwxr-xr-x. 5 root root  4096 Jul 19 16:14 share
drwxr-xr-x. 2 root rocky 4096 Dec 10 16:32 src
[root@host_name local]# chmod 775 src/
[root@host_name local]# ll
total 40
drwxr-xr-x. 2 root root  4096 May 16  2022 bin
drwxr-xr-x. 2 root root  4096 May 16  2022 etc
drwxr-xr-x. 2 root root  4096 May 16  2022 games
drwxr-xr-x. 2 root root  4096 May 16  2022 include
drwxr-xr-x. 2 root root  4096 May 16  2022 lib
drwxr-xr-x. 3 root root  4096 Jul 19 16:14 lib64
drwxr-xr-x. 2 root root  4096 May 16  2022 libexec
drwxr-xr-x. 2 root root  4096 May 16  2022 sbin
drwxr-xr-x. 5 root root  4096 Jul 19 16:14 share
drwxrwxr-x. 2 root rocky 4096 Dec 10 16:32 src
```
これで所有グループを変更して、所有グループに書き込み権限を割り当てることができた。
3度目の正直！rockyから、scpしてみる。
```bash:terminal(local)
＄ sudo scp -r app rocky@ipアドレス:/usr/local/src
rocky@ipアドレス's password:
README.md                                                    100% 2117    75.3KB/s   00:00
favicon.ico                                                  100% 3870   141.1KB/s   00:00
index.html                                                   100% 1721    61.8KB/s   00:00
logo512.png                                                  100% 9664   340.9KB/s   00:00
manifest.json                                                100%  492    17.9KB/s   00:00
・
・
・
```

いけたーー！
そしたら、`npm install`しましょ！

```bash:terminal(remote)
[rocky@host_name ~]$ cd /usr/local/src/app
npm WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
npm WARN deprecated w3c-hr-time@1.0.2: Use your platform's native performance.now() and performance.timeOrigin.
npm WARN deprecated svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x.

added 1513 packages, and audited 1514 packages in 1m

244 packages are looking for funding
  run `npm fund` for details

6 high severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.
npm notice
npm notice New major version of npm available! 8.5.5 -> 9.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.2.0
npm notice Run npm install -g npm@9.2.0 to update!
npm notice
```
なんかいろいろ言われてるけど、一回スルー
え、このままアプリみれるんじゃね？

```bash:terminal(remote)
[rocky@host_name app]$ npm start

> app@0.1.0 start
> react-scripts start

Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
 - options.allowedHosts[0] should be a non-empty string.
```

そう甘くはないね。
いろいろ調べてみたら、「そのまま公開できるわけねぇだろ！！」って言われた。
Webサーバーとかが必要で、そこから公開するっぽいね。

ちなみに上のエラーはpackage.jsonに記述していた、proxyの設定を消したら直りました。

```json:package.json
// この1行削除
  "proxy": "http://server:8080",
```

#### Webサーバー(nginx)の準備
ふーーん、nginx使おうかな。

https://manuon.com/webserver-share-ranking/

そして、調べてたら、すごい参考になりそうなサイトがあったので、これを参考にNginx✖️Reactの環境を整える。

https://tomato-develop.com/how-to-deproy-react-ubuntu20-04-node-nginx/

https://www.yoheim.net/blog.php?q=20180407

```bash:terminal(remote)
$ sudo yum install nginx
Last metadata expiration check: 2:24:57 ago on Sat 10 Dec 2022 03:19:36 PM JST.
Dependencies resolved.
=========================================================================================================
 Package                                               Architecture                               Version
・
・
・
Installed:
  nginx-1:1.20.1-13.el9.x86_64                nginx-core-1:1.20.1-13.el9.x86_64                nginx-filesystem-1:1.20.1-13.el9.noarch                rocky-logos-httpd-90.13-1.el9.noarch

Complete!
[rocky@host_name ~]$ nginx -v
nginx version: nginx/1.20.1
```

あとなんか、buildしたファイルを使うっぽいからbuild。
```bash:terminal(remote)
[rocky@host_name ~]$ cd /urs/local/src/app
[rocky@host_name ~]$ npm run build

> app@0.1.0 build
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  127.49 kB  build/static/js/main.31aa3e48.js
  264 B      build/static/css/main.e6c13ad2.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build

Find out more about deployment here:

  https://cra.link/deployment
```

いま作ったbuildフォルダを参照するようにnginxで設定する。

```bash:terminal(remote)
[rocky@host_name ~]$ su -
Password: 
Last login: Sun Dec 11 14:07:41 JST 2022 on pts/0
[root@host_name ~]# cd /etc/nginx/conf.d/
[root@host_name conf.d]# vi ipアドレス.conf
# 以下を記述
# server {
#   listen       80;
#   server_name  nabelog-client;
#   charset      utf-8;
# 
#   # ドキュメントルートを指定.
#   root /usr/local/src/app/build;
#   index index.html;
# 
#   # リクエストされたリソースがなければ、index.htmlを返却.
#   location / {
#     try_files $uri /index.html;
#   }
# }
```

さいごにnginxを起動して、自動起動機能もオンにしておく。
```bash:terminal(remote)
[root@host_name conf.d]# systemctl start nginx
[root@host_name conf.d]# systemctl enable nginx
```

しかし、Webでアクセスしても表示されない。
文法がなんかおかしいのか？

```bash:terminal(remote)
[root@host_name conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

大丈夫そう。
そして、いろいろ調べみたら、VPSのパケットフィルターっていうやつでアクセスできないようにしていたっぽい。。知らんがな！
ということで、Webでアクセスできるように設定変更
![スクリーンショット 2022-12-11 15.26.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/14f18f36-1494-2e35-d91b-41855ca2236f.png)

さぁアクセス！
![スクリーンショット 2022-12-11 15.30.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/fa7c8bc6-b402-56c6-7f43-9a1bb1823ba4.png)
えぐ！w 表示できた笑
nginxってこんなに簡単に設定できるんだ。。

### server
じゃあ次はサーバーをデプロイしましょう。
なお以下はこれを参考にしました。

https://qiita.com/yamauchi_k/items/47eb73bc0f69b2f9070f

#### buildしてバイナリファイル作成
環境の違いを考慮しないといけないらしいけど、とりあえず無視してやってみる。

```bash:terminal(local)
$ go build main.go
```
そしたら、mainファイルができた。

#### scpで本番環境に送る
scpで本番環境に送るためには事前設定が必要だった。それをする。
```bash:terminal(remote)
# コマンドだけ、実行結果は表示しない
$ sudo passwd root
$ su -
$ sudo passwd root
$ cd /usr/local
$ chown root:rocky bin/
$ chown root:rocky src/
$ chmod 775 bin/
$ chmod 775 src/
$ ll
```

scpでmainファイルを送信

```bash:terminal(local)
$ scp services/server/src/main rocky@ipアドレス:/usr/local/bin/
main                                100%   14MB   8.1MB/s   00:01 
```

送信できた。

#### バイナリファイルを実行
じゃあ、早速。
```bash:terminal(remote)
[rocky@host_name ~]$ cd /usr/local/bin/
[rocky@host_name bin]$ ./main
-bash: ./main: cannot execute binary file: Exec format error
```

ん、このバイナリは実行できないって言われた。
あ、、、、[buildした時に無視した](#buildしてバイナリファイル作成)あれかw
> 環境の違いを考慮しないといけないらしいけど、とりあえず無視してやってみる。

はい、考慮するか。

#### 本番環境を意識したbulid、そして実行
localの環境をまず確認。
```bash:terminal(local)
$ go env GOOS
linux
$ go env GOARCH
arm64
```
たぶん、arm64なのがいけない気がする。僕はM1macなので、ここを修正してbuildする。

```bash:terminal(local)
$ rm main
$ env GOARCH=amd64 go build main.go
```

これでできたmainファイルを再度送信、実行する。

```bash:terminal(remote)
[rocky@host_name bin]$ ./main
:@tcp(db:3306)/?charset=utf8&parseTime=true&loc=Asia%2FTokyo
........................
```

を実行できてる！
この表示はあってて、必死にDBに接続しようとしているだけだね。
じゃあ、DBに接続しようとするのをやめて、mockのjsonデータを返すだけのAPIに編集。
やったことを簡単にまとめると、
- GORMで呼び出すところを呼び出さないように
- ただのjsonテキストを返すだけにした

編集後、buildして、またscpで本番環境に送信。
実行！

```bash:terminal(remote)
[rocky@host_name bin]$ ./main&
[1] 59434
[rocky@host_name bin]$ [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] Loaded HTML Templates (2): 
        - index.html
        - 

[GIN-debug] GET    /                         --> main.main.func1 (4 handlers)
[GIN-debug] GET    /hello                    --> main.main.func2 (4 handlers)
[GIN-debug] GET    /shops                    --> main.main.func3 (4 handlers)
[GIN-debug] POST   /shops                    --> main.main.func4 (4 handlers)
[GIN-debug] GET    /shops/:id                --> main.main.func5 (4 handlers)
[GIN-debug] PATCH  /shops/:id                --> main.main.func6 (4 handlers)
[GIN-debug] DELETE /shops/:id                --> main.main.func7 (4 handlers)
[GIN-debug] GET    /influencers              --> main.main.func8 (4 handlers)
[GIN-debug] POST   /influencers              --> main.main.func9 (4 handlers)
[GIN-debug] GET    /influencers/:id          --> main.main.func10 (4 handlers)
[GIN-debug] PATCH  /influencers/:id          --> main.main.func11 (4 handlers)
[GIN-debug] DELETE /influencers/:id          --> main.main.func12 (4 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
```

おお、動いてる！
そしたら、さくらVPSのパケットフィルタで、8080ポートを解放。
![スクリーンショット 2022-12-17 10.19.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/c13a8f91-836b-03fa-485d-90ba3de94cdd.png)

サイトからアクセスしてみる。
`http://ipアドレス:8080/shops`
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3433373335322f64643261613461342d303963312d663064372d646531372d3734323765613966393134612e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/58ed7b86-0fb1-7b38-2000-d977a19363c4.png)

みれた！最高。
そしたら、フロントエンドからここにAPI呼び出しをするようにする。

#### フロントエンドからバックエンドに呼び出し。
特に書くことはない。なぜなら、フロント側の呼び出し先アドレスをlocalhostから本番serverのアドレスに変えるだけです。
あえて書くとすれば、envファイルを用いて自動的に本番環境と開発環境で切り替えできるようにしたくらい。
参考は以下

https://ralacode.com/blog/post/use-env-variables-in-react/

https://qiita.com/yakimeron/items/8da088ca09249ae4cbf7

これができたら、deploy環境にappする
表示できた。

![ipアドレス_shops.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/cffb5146-9a21-d1bf-6f94-e3117ed99a61.png)

### DB
serverのAPIはいまmockで作成していたのですが、dbとの連携をしてできるようにしましょ。
だけど、DBサーバーってどうやって作るんだろ。
#### 調査

いろいろ調べてみた。

https://www.sakura-vps.net/centos6-setting-list/mysql-settings-for-sakura-vps/

https://qiita.com/d0ne1s/items/5894bbe80ce499c9e7bf

https://arkgame.com/2022/10/29/post-314334/

なんとなく方針が立ったので、進めてみる。

#### mysqlをinstall
まずはサーバーを開いて、rootユーザーの設定を行った。

```bash:terminal(remote)
[rocky@host_name ~]$ sudo passwd root
Changing password for user root.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.
[rocky@host_name ~]$ su -
Password: 
[root@host_name ~]# passwd root
Changing password for user root.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.
```

次に、mysqlのinstallを行った。
(そしてここら辺から気づいたんですが、dnfとyumって全く()一緒らしいですね。)
(参考： [yum と dnf 使う上では全く違いがない話](https://blog.apar.jp/linux/16100/))
```bash:terminal(remote)
[root@host_name ~]# sudo dnf install mysql mysql-server
・
・
・
Complete!
[root@host_name ~]# mysql --version
mysql  Ver 8.0.30 for Linux on x86_64 (Source distribution)
```

#### mysqlの起動
systemctlでmysqlのサービスを起動してみる。
```bash:terminal(remote)
[root@host_name ~]# systemctl start mysqld.service
Job for mysqld.service failed.
See "systemctl status mysqld.service" and "journalctl -xeu mysqld.service" for details.
[root@host_name ~]# systemctl list-units -t service
  UNIT                               LOAD   ACTIVE       SUB       JOB   DESCRIPTION                                            
  mysqld.service                     loaded deactivating stop-post start MySQL 8.0 database server

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.
JOB    = Pending job for the unit.

32 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
```

次はmysqlのパスワードを確認したいのだが、`/var/log/mysql/mysqld.log`には初期パスワードが書かれていなかったので、新規で作成の方法をさぐった。以下参考。

https://beyondjapan.com/blog/2020/07/mysql-password/

- `/etc/my.cnf.d/mysql-service.cnf`に「skig-prant-tables」と追記
    - どのユーザーでもパスワードなしで接続できて、すべての権限が付与される
- mysqlを再起動`systemctl restart mysqld`
- mysqlに入れるか試してみる`mysql -u root` -> 入れない

以下のエラーが出たのだが、どうやらmysql.sockファイルがないことが原因っぽい。
`touch /tmp/mysql.sock`で作成。権限も変える。

```bash:terminal(remote)
$ sudo touch /var/lib/mysql/mysql.sock
$ sudo chown mysql:mysql /var/lib/mysql/mysql.sock
```

結局これでもだめだった。

ってか、そもそもmysqlのサービスが動いていなくね？？
> [root@host_name ~]# systemctl start mysqld.service
Job for mysqld.service failed.
See "systemctl status mysqld.service" and "journalctl -xeu mysqld.service" for details.

ここに書いてある、「これやってみて！！」っていうコマンドを実行してみると、

```bash:terminal(remote)
[root@host_name mysql]# journalctl -xeu mysqld.service

░░ Support: https://access.redhat.com/support
░░ 
░░ A process of unit @UNIT has been killed by the Linux kernel out-of-memory (OOM)
░░ killer logic. This usually indicates that the system is low on memory and that
░░ memory needed to be freed. A process associated with mysqld.service has been determined
░░ as the best process to terminate and has been forcibly terminated by the
░░ kernel.
░░ 
░░ Note that the memory pressure might or might not have been caused by mysqld.service.
```

OOMキラーと言っていて、おそらく容量がない...？
mysqlの容量を調べてみたら、どうやら最低でも**1GB**必要らしい。

https://server-domain.info/report/need-memory-mysql.html

うちのVPSは500MBなので到底足りない。
いろいろ調べてみたが、1GBまではいかないものの、残り200MBないうちのサーバーの容量だときびしそう。。
ということで容量を拡張しましょう。
![スクリーンショット 2022-12-31 22.53.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/7cb7082f-992a-0cf8-81c9-768b2a23b30a.png)
![スクリーンショット 2022-12-31 22.55.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/ab83ba74-0890-14a1-033d-ed2a8caa420c.png)

うーーーーん、、、勉強代、、。
こういうのがちょっと痛い。

まぁそしたらmysqlは問題なく起動しますた。

```bash:terminal(remote)
[root@host_name ~]# systemctl start mysqld.service
[root@host_name ~]# systemctl enable mysqld.service
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.
```

#### mysqlの設定
諸々の設定を以下していきます。

```bash:terminal(remote)
[root@host_name ~]# cat /var/log/mysql/mysqld.log | grep password
2022-12-31T14:14:16.536829Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
# パスワードなさげ？
[root@host_name ~]# mysql_secure_installation
・
・
# 質問に答えてパスワードを設定。基本的にy
All done! 
[root@host_name ~]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.30 Source distribution

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like "chara%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8mb3                    |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql> exit
Bye
```
文字コードがutf8mb4なのだ。(4バイト以上の保存ができる)
どうやら、utf8では保存できない、絵文字なども保存できるみたい。
じゃあ変える必要ないな。

次はタイムゾーン設定

```bash:terminal(mysql)
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | JST    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)
```

このtime_zoneのSYSTEMをAsia/Tokyoに変えるらしい。

```bash:terminal(remote)
[root@host_name ~]# mysql_tzinfo_to_sql /usr/share/zoneinfo
[root@host_name ~]# mysql -u root -p -Dmysql < ~/timezone.sql
[root@host_name ~]# vi /etc/my.cnf.d/mysql-server.cnf
# 末尾に以下を追記
# [mysqld]
# default-time-zone = 'Asia/Tokyo'
[root@host_name ~]# systemctl restart mysqld.service
```

```bash:terminal(mysql)
mysql > show variables like '%time_zone%';
+------------------+------------+
| Variable_name    | Value      |
+------------------+------------+
| system_time_zone | JST        |
| time_zone        | Asia/Tokyo |
+------------------+------------+
2 rows in set (0.00 sec)
```

設定完了ーー！

#### バックエンドサーバーとの繋ぎこみ

さぁ、ほぼほぼ最終章。バックエンドサーバーとの繋ぎこみです。
さっきの設定で、localhostからしかアクセスできないようにしたんだけど平気かなぁ。。

とりあえず順序きめよ

- DB名決定&DB作成
- 参考サイト調査

よし。

##### DB名決定&DB作成
DB名は`nabelog_pro`にするか。
じゃあ、それを作りましょ。

```bash:terminal(mysql)
mysql> CREATE DATABASE nabelog_pro DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
Query OK, 1 row affected (0.01 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| nabelog_pro        |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
```
簡単ダァ。次。

##### 参考サイト調査

調査する。

https://qiita.com/otsuno/items/51e89d87ab85cb89539c

→ 3306ポートを解放しないといけないっぽい

https://nymemo.com/mysql/1539/

→ 外部からアクセスできるようにするには、それ専用のユーザーを設定した方がいいっぽい。

https://vps.sakura.ad.jp/feature/lnw.html

→ ローカルネットワークっていう機能を使ってサーバー間通信するのもいいな。本来こっちやりたいけども、まだ先のお話かな。まずはネットを介そう。


なんで、とりあえず外部からアクセスできるようにいろいろしてみよう。

##### 3306番ポート公開

![スクリーンショット 2023-01-02 11.36.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/29e51eb5-4ab4-944b-e12b-ff5b68dd7d7d.png)

##### 公開したポートからアクセスができるか確認

3306番ポートが開かれていることを確認したいので、hostを"%"にしてどこからでもアクセスできるようなユーザーを作りましょ。
あと適当なテーブルも。

```bash:terminal(remote)
mysql> CREATE USER 'exuser'@'%' IDENTIFIED BY '***********';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT host, user from mysql.user;
+-----------+------------------+
| host      | user             |
+-----------+------------------+
| %         | exuser           |
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
+-----------+------------------+
5 rows in set (0.00 sec)

mysql> create table test(  
    ->     id int NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'Primary Key',
    ->     create_time DATETIME COMMENT 'Create Time',
    ->     name VARCHAR(255)
    -> ) COMMENT '';
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
+-----------------------+
| Tables_in_nabelog_pro |
+-----------------------+
| test                  |
+-----------------------+
1 row in set (0.00 sec)
```

でけたから、これをlocalのターミナルから覗けるか確認。

```bash:terminal(local)
$ mysql -h ipアドレス -u exuser -P 3306 -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 21
Server version: 8.0.30 Source distribution

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use nabelog_pro;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------------+
| Tables_in_nabelog_pro |
+-----------------------+
| test                  |
+-----------------------+
1 row in set (0.03 sec)

```
いけたーー！みれたーー。

公開できていることがわかったので、いま設定したユーザーの権限を絞っとこう。
```bash:terminal(mysql)
mysql> grant usage on *.* to exuser;
Query OK, 0 rows affected (0.00 sec)

mysql> grant all on nabelog_pro.* to exuser;
Query OK, 0 rows affected (0.01 sec)
```

##### server用のユーザーも準備
serverと接続するためのユーザーも準備しましょ。
```bash:terminal(mysql)
mysql> create user 'server'@'ipアドレス' identified by '*********';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all on nabelog_pro.* to server@ipアドレス;
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for server@ipアドレス \G
*************************** 1. row ***************************
Grants for server@ipアドレス: GRANT USAGE ON *.* TO `server`@`ipアドレス`
*************************** 2. row ***************************
Grants for server@ipアドレス: GRANT ALL PRIVILEGES ON `nabelog_pro`.* TO `server`@`ipアドレス`
2 rows in set (0.00 sec)
```

##### serverのコードをGORMでdbサーバーを呼び出すように変更
mock用に作ったserverのコードを前のコード(dbと連携するコード)に直す。
そして、envファイルに本番環境のmysqlの設定を書く。

完了したら、buildして、mainファイルをremoteにscpで上げる。
そして実行。

![スクリーンショット 2023-01-02 15.16.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/c117b5b4-b896-31bf-8908-05a23333eab4.png)
![スクリーンショット 2023-01-02 15.16.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/a06afa69-6008-afa8-7fee-dbc12f89a4a9.png)

いけたぁぁぁぁ！！！
DBとの接続も完璧。
申し分なし。

これにて終わり！！！！！