GCEにて、Webサイトを構築するうえで、SSLを利用したhttp通信をしたく、いろいろと試行錯誤して実現できたので、備忘録として記事にします。
#目的
dockerコンテナをGCEに立て、ブラウザにてWebサイトにアクセスする際に、IPアドレスを直打ちして表示するのではなく、ドメイン・SSLを利用したhttpsアクセスを実現する。
#環境等
・GCE:Ubuntu 18.04 LTS
n1-standard-1(vCPU x 1、メモリ 3.75 GB)
・ドメイン:お名前.comにて取得
・SSL証明書:Let's Encrypt
#ドメインの取得
まずは、ドメインの取得をします。
今回は「お名前.com」を利用しました。
ドメインによって金額は異なりますが、安いので「.work」が1円とか、「.site」で25円とかありましたので、こだわりが無ければ安いので問題ないかと思います。
私は「.com」で1000円のドメインを契約しました。
ドメインの取得が完了したら、次のステップです。
#GCEにVMインスタンスを立てる
GCEに下記の内容でインスタンスを立てます。
マシンタイプは「n1-standard-1(vCPU x 1、メモリ 3.75 GB)」がよさそうです。
OSは使い慣れた「Ubuntu 18.04 LTS」を使用しています。
下部の「HTTPトラフィックを許可する」「HTTPSトラフィックを許可する」にチェックを入れ、作成します。
既にコンテナイメージをDockerHubに上げている場合は、「このVMインスタンスにコンテナイメージをデプロイする」にチェックを入れ、イメージを指定しても問題ないはず。
今回は、新しいUbuntu環境にdocker等を入れていきます。
#静的IPアドレスの設定
VPCネットワーク > 外部IPアドレスを選択し、静的アドレスを予約します。
名前はなんでも大丈夫です。
リージョンには、GCEと同じオレゴンを選んでいます。
予約ボタンを押し、VMインスタンスとの設定を入力します。
VMインスタンスの詳細画面から、編集を選択し、「ネットワーク インターフェース」を設定します。
外部IPのセレクトボックスから、先ほど登録した静的IPアドレスを選択します。
これで、VMインスタンスのIPアドレスの固定が完了しました。
#Cloud DNSの設定
次に、Cloud DNSを設定します。
ネットワークサービス > Cloud DNSからゾーンを作成します。
ゾーン名は任意で、DNS名は「お名前.com」で取得したドメインを入力します。
ゾーンを作成したら次は、今作成したゾーンの詳細画面を開き、レコードセットを作成します。
DNS名はそのまま何も入力せずに、IPv4アドレスに予約した静的IPアドレスを入力して作成します。
登録後、ゾーンの詳細画面に戻り、お名前.comとの設定をします。
#お名前.comの設定
お名前.comとCloud DNSの連携は、ゾーンの詳細画面のNSに書かれたデータという項目のxxxxx.googledomains.com.と書かれた4つをお名前.comのネームサーバに指定する必要があります。
上記の赤枠の値を下記のお名前.comのネームサーバに設定します。
この際に、もともと入力されていたネームサーバ情報はすべて消してください。
これで、お名前.com・GCPの設定は完了です。
#VMインスタンスの設定
作成したVMインスタンスにSSH接続します。
作成したVMインスタンスの詳細画面からSSH接続できます。
接続出来たら、下記のコマンドを上から順番に実行してdocker関連をインストールします。
※ 「このVMインスタンスにコンテナイメージをデプロイする」にチェックを入れた場合は、「SSLの設定」まで飛ばして下さい。
# インストール可能なパッケージの「一覧」を更新
$ sudo apt update
# HTTPS経由でrepositoryをやりとり出来るようにするためのパッケージをインストール
$ sudo apt install -y \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
# Dockerの公式GPG keyを追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# repository( stable ) を追加
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 再度 apt パッケージのアップデート
$ sudo apt update
# docker をインストール
$ sudo apt install -y docker-ce
# dockerの起動確認
$ sudo systemctl status docker
次に指定の一般ユーザでも sudo 無しでdockerを使えるようにします。
※ 下記のuserNameは環境のユーザ名に合わせて修正して下さい。
# 自分のユーザー名を表示
$ whoami
userName
# userNameをDockerグループに追加
$ sudo gpasswd -a userName docker
# dockerグループの確認
$ cat /etc/group | grep docker
docker:x:999:userName
# dockerが使用するソケットを一般ユーザでも読み込み出来るようにする
$ sudo chmod 666 /var/run/docker.sock
docker-composeをインストールします
# バイナリからdocker-composeをインストール
# インストールするバージョンを設定
$ export compose='1.24.0'
※ バージョンは都度確認が必要です。
2019/6/10時点で最新:1.24.0
# docker-composeをダウンロード
$ sudo curl -L https://github.com/docker/compose/releases/download/${compose}/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# 実行権限の付与
$ sudo chmod 0755 /usr/local/bin/docker-compose
#バージョン確認
$ docker-compose -v
ここまででVMインスタンスの設定は完了です。
Dockerイメージを取得
デプロイするDockerイメージをDocker Hubからpullします。
pullした後に、docker runコマンドによって、コンテナーを作成・起動します。
# docker hubから任意のDockerイメージを取得する
$ docker pull Dockerイメージ名
# docker runコマンドより、コンテナを作成・起動します。
$ docker run --name web -d Dockerイメージ名
コンテナの起動を確認したら、コンテナに入り、hostnameを確認します。
# 立ち上がっているコンテナに入る
$ docker exec -it web sh
# コンテナのIPアドレスを確認する
$ hostname -i
コンテナのIPアドレスを確認したら、どこかに控えておきましょう。
私の場合は「172.17.0.3」でした。
#SSLの設定
やっとSSLの設定に入ります。
ここまでが事前準備といったところでしょうか・・・長い・・・
今回、SSL証明書は「Let’s Encrypt」を使用します。
既に、Webサーバにnginx, 証明書にlet’s encryptベースのリバースプロキシとして動作する. 自動で証明書の更新もしてくれるDockerイメージの「https-portal」がありますので、こちらをpullします。
# steveltn/https-portalをpull
$ docker pull steveltn/https-portal
イメージをpullできたら、次はdocker runコマンドでコンテナの作成・起動します。
※ webコンテナは私の場合ポート8080で起動するようにあらかじめ設定していますので、環境に合わせて変更してください。
docker run --name reverse-proxy -p 80:80 -p 443:443 -e STAGE='production' -e DOMAINS='ドメイン名 -> http://webコンテナのIPアドレス:8080' steveltn/https-portal -d
上記で大事なのは「-e DOMAINS='ドメイン名 -> http://webコンテナのIPアドレス:8080'」ですね。今回の環境でいうと「-e DOMAINS='ssl-site.com -> http://172.17.0.3:8080'」となります。
ドメイン名の紐づけに、VMインスタンスのIPアドレスではなく、先に作成したWebコンテナのIPアドレスを入力しないと、動いてくれません。
ここまでくると、あとはブラウザにてドメインをhttpsで接続するだけです。
お名前.comの反映に時間がかかる場合がありますので、接続がうまくいかなくても2日程度待てば、つながることもあります。
これで、GCEのDocker環境でSSL証明書を利用したデプロイが完了しました。
let’s encryptの証明書には90日の期限がありますが、steveltn/https-portalを利用すると、自動的に更新してくれるみたいです。素晴らしい。