GCE x Ubuntu x Docker環境構築をコマンドで

# 環境

```
MacOS X 10.15.5 (Catalina)
Homebrew 2.4.9
Google Cloud SDK 304.0.0
```

# GCP アカウント登録

[【画像で説明】Google Cloud Platform (GCP)の無料トライアルでアカウント登録](https://qiita.com/komiya_____/items/14bd06d0866f182ae912)

# Google Cloud SDK のインストール

[Google Cloud SDK のインストール ~ 初期化](https://qiita.com/komiya_____/items/5af0dcc8639fad9fee29)

# プロジェクト作成

[Google Cloud SDK でプロジェクトを作成する](https://qiita.com/komiya_____/items/fb02f38e1886db280d52)

# インスタンスの作成

## インスタンス名を決める

変数に入れておきます。

```sh
$ INSTANCE='anata_no_instance_name'
```

## 公開 VM イメージを確認

インスタンスを作成する際に`PROJECT`と`FAMILY`を参照します。

```sh
$ gcloud compute images list

NAME               PROJECT      FAMILY   DEPRECATED STATUS
centos-6-v20200714 centos-cloud centos-6            READY
centos-7-v20200714 centos-cloud centos-7            READY
...
ubuntu-1804-bionic-v20200807 ubuntu-os-cloud ubuntu-1804-lts READY
```

## インスタンスの作成

今回は ubuntu-1804-lts を利用

```sh
$ gcloud compute instances create $INSTANCE \
--image-family ubuntu-1804-lts \
--image-project ubuntu-os-cloud \
--zone asia-northeast1-a \
--machine-type f1-micro \
--boot-disk-size 30GB
```

GCPには12か月間、＄300分のクレジットがもらえる無料トライアルと、規定範囲内であればクレジットとは関係なく各サービスを無料でつかえるAlwaysFreeという仕組みがあります。
無料トライアル期間中でも Always Free の規定内であればクレジットは消費されないようです。

* リージョン: us-xxxx1のいずれか
* マシーンタイプ: f1-micro x1
* 永続ストレージ: 30GB以下


> 無料トライアルの期間中に Always Free の対象となるリソースをご利用になる場合、そのリソースが無料トライアルのクレジット分から差し引かれることはありません。

※ 規定が変わる可能性もあるため、こちらをご確認ください。
https://cloud.google.com/free/docs/gcp-free-tier#always-free

## インスタンスの詳細確認

作成されたインスタンスを確認してみる。

```sh
$ gcloud compute instances describe $INSTANCE
```

# SSH 接続

インスタンスに SSH 接続するための設定をしていきます。

## キーペアの作成

```sh
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -C 'example@gmail.com'
...
Enter passphrase (empty for no passphrase): # 秘密鍵にアクセスするためのパスフレーズを登録
Enter same passphrase again: # 確認のためもう一度
...
```

-t rsa（RSA 方式）
-b 鍵長 4096 ビット方式
-C コメント。GCP に鍵登録する場合は、ここで指定したものを自動でユーザー追加してくれる。

### おまけ

gcloud コマンドでも可能

```sh
$ gcloud compute ssh $INSTANCE
```

## 秘密鍵の権限変更

セキュリティの観点からファイル権限を 400 に変更しておきます。
※ 所有者のみが読み取りのみ可能な権限

```sh
$ chmod 400 ~/.ssh/id_rsa
```

## 公開鍵をコピー

```sh
$ cat ~/.ssh/id_rsa.pub | pbcopy
```

## 公開鍵の登録

こちらは GUI で操作する必要があるようです。

GCP コンソールから
https://console.cloud.google.com/

### プロジェクト全体で登録する場合

![スクリーンショット 2020-08-12 16 11 25](https://user-images.githubusercontent.com/63569663/90090456-085a7900-dd5f-11ea-9f8f-9165e2c0e299.png)

![スクリーンショット 2020-08-12 16 12 05](https://user-images.githubusercontent.com/63569663/90090455-07c1e280-dd5f-11ea-8c27-a488289e3450.png)

![スクリーンショット 2020-08-12 16 12 23](https://user-images.githubusercontent.com/63569663/90090451-055f8880-dd5f-11ea-86e2-a17ec9021fce.png)

### インスタンス毎に登録する場合

![スクリーンショット 2020-08-13 14 35 51](https://user-images.githubusercontent.com/63569663/90098104-73fa1180-dd72-11ea-9bfc-6c6c3acf499c.png)

## 接続

ssh コマンドで接続します。

```sh
$ ssh ユーザーネーム@外部IP -i ~/.ssh/id_rsa
...
Are you sure you want to continue connecting (yes/no/[fingerprint])? # <- yesと入力
Enter passphrase for key '/Users/anata_no_home_dir/.ssh/id_rsa': # <- パスフレーズを入力(キーペア作成時に登録したもの)
...
```

**ユーザーネーム**
>デフォルトでは、SSH セッションのユーザー名は、アカウントにログインしているメールアドレスから、ドメイン情報を省略して、生成されます。たとえば、メールアドレスが user@gmail.com の場合、対応するユーザー名は user になります。

**外部IP**
Webコンソールの メニュー > Compute Engine > VMインスタンス 
or
$ gcloud compute instances describe インスタンス名
...
natIP: xx.xxx.xxx.xx
...

から調べられます。
### おまけ

`Are you sure you want to ~`　は初回接続時に聞かれる。(接続先のフィンガープリントが変わったときも)
yes と回答することで~/.ssh/known_hosts ファイルに追加され、次回以降は聞かれなくなります。

-oStrictHostKeyChecking=no オプションをつけることでスキップ可能。
回答をスキップし known_hosts に登録されるがセキュリティ的にはよろしくないので問題ないと判断できる場合のみ。

```sh
$ ssh ユーザーネーム@外部IP -i ~/.ssh/id_rsa -oStrictHostKeyChecking=no
```

## config ファイルに登録

~/.ssh/config ファイルを編集します。

```/Users/anata_no_home_dir/.ssh/config
Host webserver <- 任意のホスト名
    User anata_no_user_name
    HostName 192.0.2.1
    Port 22
    IdentityFile ~/.ssh/id_rsa
```

### おまけ

config ファイルに`StrictHostKeyChecking no`を追記することで、-oStrictHostKeyChecking=no と同じことが可能。

```/Users/anata_no_home_dir/.ssh/config
Host webserver
    User anata_no_user_name
    HostName 192.0.2.1
    Port 22
    IdentityFile ~/.ssh/id_rsa
    StrictHostKeyChecking no <- これ
    UserKnownHostsFile=/dev/null  <- これ
```

UserKnownHostsFile=/dev/null はホストを known_hosts ファイルに追記しないようにするもの。

## 接続

config ファイルに登録したホスト名でログイン確認

```sh
$ ssh webserver
```

# ポートの変更

ポート番号は 0 ～ 65535 までありますが、基本的に 49513 ～ 65535 までの番号を使うのが安心なようです。

https://27bit.com/question-number.html

## sshd_config ファイルのポート番号を変更

サーバ内操作になります。

/etc/ssh/sshd_config ファイルを編集。
`#Port ~` と記載のある行のコメントアウトをはずし、↑ で変更したポート番号に変更

ここを
<変更前>

```text:/etc/ssh/sshd_config
...
#Port 22
...
```

↓
こうする
<変更後>

```text:/etc/ssh/sshd_config
...
Port 12022
...
```

コマンドで

```sh
$ sudo sed -i -e "s/#Port 22/Port 12022/g" /etc/ssh/sshd_config
```

**-i**
ファイルを読み込んで、結果をそのファイルに上書きする。

**-e**
-e オプションがない場合はオプション以外の最初の引数が処理内容とみなされるので、たいていは -e を省略できる。処理内容を指示する引数に拡張正規表現を使いたい場合は、-E または -r を付ける。

https://hydrocul.github.io/wiki/commands/sed.html

sshd のサービスを再起動

```sh
$ sudo systemctl restart sshd
```


## ファイアウォールルールを変更

VPC ネットワークでいくつかのファイアウォールルールというものがデフォルトで設定されています。
ここでは SSH の設定である`default-allow-ssh`のデフォルトのポート番号を`22` -> `12022`へ変更します。

```sh
$ gcloud compute firewall-rules update default-allow-ssh \
--allow tcp:12022
```

## config ファイルのポート番号を変更

```/Users/anata_no_home_dir/.ssh/config
Host webserver
    User anata_no_user_name
    HostName 192.0.2.1
    Port 12022 <- ここ
    IdentityFile ~/.ssh/id_rsa
```


## 確認

ログインしてみる

```sh
$ ssh webserver
```

or

```sh
$ ssh ユーザーネーム@外部IP -p 12022 -i ~/.ssh/id_rsa 
```


# サーバの設定

サーバ内操作になります。

## Ubuntu の時刻同期設定

<サーバ内>

どの時刻サーバと同期させるかの設定。

### `/etc/systemd/timesyncd.conf`を編集

ここを

```/etc/systemd/timesyncd.conf
...
[Time]
#NTP=
#FallbackNTP=ntp.ubuntu.com
...
```

↓

こう

```/etc/systemd/timesyncd.conf
...
[Time]
NTP=ntp.nict.jp
FallbackNTP=ntp1.jst.mfeed.ad.jp ntp2.jst.mfeed.ad.jp ntp3.jst.mfeed.ad.jp
...
```
コマンドでやるならこう

```sh
$ sudo sed -i -e 's/#NTP=/NTP=ntp.nict.jp/g' /etc/systemd/timesyncd.conf 

$ sudo sed -i -e 's/#FallbackNTP=ntp.ubuntu.com/FallbackNTP=ntp1.jst.mfeed.ad.jp ntp2.jst.mfeed.ad.jp ntp3.jst.mfeed.ad.jp/g' /etc/systemd/timesyncd.conf 
```

再起動

```sh
$ sudo systemctl restart systemd-timesyncd.service
```

## タイムゾーンの設定

### 現在時刻の確認

```
$ date

Thu Aug 09 00:06:18 UTC 2020
```

### タイムゾーンの確認

```sh
$ timedatectl

                      Local time: Thu 2020-08-09 00:08:23 UTC
                  Universal time: Thu 2020-08-09 00:08:23 UTC
                        RTC time: Thu 2020-08-09 00:08:24
                       Time zone: Etc/UTC (UTC, +0000)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no
```

### タイムゾーンの設定

```sh
$ sudo timedatectl set-timezone Asia/Tokyo
```

### タイムゾーンの変更を確認

```sh
$ timedatectl

                      Local time: Thu 2020-08-09 09:16:35 JST
                  Universal time: Thu 2020-08-09 00:16:35 UTC
                        RTC time: Thu 2020-08-09 00:16:36
                       Time zone: Asia/Tokyo (JST, +0900)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no
```

# docker のインストール

サーバ内操作になります。

## シェルスクリプトでインストール

```sh
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
```
**-f**
エラー時に出力を一切しない

**-s**
プログレスメーターやエラーメッセージを表示しない。

**-S**
`-s`と一緒に使用することで、エラーメッセージだけは出力するようにする。

**-L**
ページが移動しリダイレクト先がある場合にリダイレクトを有効にする。

## ユーザーグループの追加

```sh
$ sudo usermod -aG docker anata_no_user_name
```
ユーザーネームはコマンドラインに表示されている@の前の文字列
GCPの場合デフォルトはgmailの@の前

## 権限変更

docker が使用するソケットを一般ユーザでも読み込み出来るようにする

```sh
$ sudo chmod 666 /var/run/docker.sock
```

## 実行確認

```sh
$ docker -v
```

# docker-compose のインストール

## GitHub リポジトリのバイナリからインストール

```sh
# インストール
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```

**-L**
ページが移動しリダイレクト先がある場合にリダイレクトを有効にする。

**uname -s** の確認

```sh
$ uname -s
Linux
```

**uname -m** の確認

```sh
$ uname -m
x86_64
```

## 権限変更

```sh
$ sudo chmod +x /usr/local/bin/docker-compose
```
**+x**
すべてのユーザーに実行権限を付与

## 実行確認

```sh
$ docker-compose -v
```

### おまけ

- docker を d
- docker-compose を dc

で実行できるようにエイリアスを設定します。

```sh
$ sudo sh -c "echo \"\nalias d='docker'\" >> ~/.bashrc"
$ sudo sh -c "echo \"\nalias dc='docker-compose'\" >> ~/.bashrc"

$ source ~/.bashrc
```

※ sudo echo "alias d='docker'" >> ~/.bashrc だとエラー

#### 確認

以下のコマンドがとおれば OK

```sh
d -v

Docker version 19.03.12, build 48a66213fe
```

```sh
dc -v

docker-compose version 1.26.2, build eefe0d31
```

## おしまい

最後まで読んでいただきありがとうございました。