Androidはワンツーパンチ 三歩進んで二歩下がる

プログラミングやどうでもいい話

【6】DNSテスト用に無料の独自ドメインを取得してGoogle Cloud DNSでネームサーバの設定をする(GCE,freenom,http+独自ドメイン+ポート3000でアクセスする)

これはHerokuからGCP無料枠にRailsアプリを引越ししたときにやったことシリーズの【5】の続きです。
GCE に 作成した VM インスタンス上で Docker コンテナを起動して、http://IPアドレス:3000という形で実行することができましたが、今回はhttp://独自ドメイン:3000という形で起動するという形にしようと思います。そこのところのメモです。

1. 公式サイト

2. 何をやりたいのか

Heroku で本番運用していたWeb サイトGoogle Compute Engineに引越し作業中で、その作業手順をメモしています。
このシリーズの【5】までの工程で、GCE に 作成した VM インスタンスで Web サイトをhttp://IPアドレス:3000という形で表示出来るようになりました。

今後は独自ドメインで運用するようにしたいですが、使用するドメインが本番稼働中なので一時的にテスト用の無料ドメインを取得して DNS 設定をして表示テストをしたいと思います。

この記事ではhttp://独自ドメイン:3000という形で表示できれば OK とします。
別の記事で Nginx+Let's Encrypt を使って最終目標であるhttps://www.独自ドメインという形で表示できるようにします。

なお、ネームサーバーにGoogle Cloud DNSを使用していますが、私がちょっと試してみたかったので使っていますがこれでないと出来ないわけではありません。
現に本番ではドメインを取得したお名前.com のネームサーバーを使用しております。
freenom が提供するネームサーバを使えば無料で設定出来るようなので、こちらを試すのが良さそうです。

3. 目標

  • freenom で独自ドメインを取得する
  • Google Cloud DNS でネームサーバーの設定をする
  • http://独自ドメイン:3000という形でウェブサイトが表示できることを確認する

4. 注意点

  • Google Cloud DNSは使用料金がかかりますのでご注意ください。
  • DNSテスト成功後すぐにネームサーバーの設定を削除しましたが 2 円請求されました。

5. 参考サイト様

本当に参考になりました。ありがとうございます!

6. freenom で独自ドメインを取得する

参考サイト様の記事を参考に取得します。

記事がとてもよくまとまっているので、ここでは取得の説明を割愛させていただきます。

1 点、登録時に「Forward this domain to」という欄に適当な URL を入力したのですが、あとでネームサーバーを入力したところ「URL Forwarding」から自動で削除されていました。(ので自分で消さなくてよい)

自分はdousa-kensho.tkというドメインを取得しました。
すごく気軽に無料で取得できてありがたいサービスだと思います。
情報を提供してくださってる方々にも感謝しております。

↓これはdousa-kensho.tkに登録後、転送先サイトが表示された時のスクリーンショットです。 f:id:sakura_bird1:20190310171823p:plain:w600

7. Google Cloud DNS でネームサーバーの設定をする

dousa-kensho.tkというドメインを GCE の VM インスタンスが持っている外部 IP アドレスに向けるため、ネームサーバーで紐づけを行います。

7.1. Cloud DNS のゾーンを作成

GCP メニューよりネットワークサービス > Cloud DNS を選択します。

f:id:sakura_bird1:20190310174508p:plain:w300

ゾーンを作成します
ゾーンとは、ネームサーバがドメインを管理する範囲のことです。

f:id:sakura_bird1:20190310174556p:plain:w300

次の項目を設定します。

設定項目 設定内容
ゾーン名 任意の名前
DNS 使用するドメインを記入
DNSSEC わからなければオフのままで OK

f:id:sakura_bird1:20190310175025p:plain:w500

DNSSECという言葉が出てきましたが、Google によるとこのような意味のようです。

DNS Security(DNSSEC) | Cloud DNS | Google Cloud

DNSSEC は、ドメインネーム ルックアップに対するレスポンスを認証するドメインネーム システムの機能です。これらのルックアップに対するプライバシー保護は行いませんが、攻撃者が DNS リクエストに対するレスポンスを改ざんまたは汚染できないようにします。

「作成」ボタンをクリックするとこのような画面が表示されます。
DNS サーバーを、レジストラドメインを取得した業者)のネームサーバーに指定する必要があります。
この作業は後ほど行います。
「レコードセットを追加」をクリックして A レコードの追加を行います。

f:id:sakura_bird1:20190310175838p:plain:w500

7.2. A レコードを追加する

A レコードを設定することで、DNS サーバーで IP アドレスとドメイン名を紐付けします。
ここではレコードセット 2 件(www 有りと無し)を登録します。

レコードセットの追加で次の項目を設定します。

設定項目 設定内容
DNS サブドメインがあれば入力(ここではサブドメイン無しと www の 2 件)
リソースレコードのタイプ A
IPv4 アドレス IP アドレスを入力(ここでは GCE の VM インスタンスの外部 IP アドレス)

1 件目
f:id:sakura_bird1:20190310182531p:plain:w300

2 件目
f:id:sakura_bird1:20190310182604p:plain:w300

ゾーンにAレコードが2件追加されたのを確認できると思います。
NS レコードの 4 件のアドレスを freenom で登録する必要があります。

f:id:sakura_bird1:20190310183607p:plain:w500

7.3. freenom 側にネームサーバーを登録する

freenom にアクセスしてサインインします。
http://www.freenom.com/ja/index.html?lang=ja Freenom - 誰でも利用できる名前

「Services」 > 「My Domains」
をクリックします。
編集対象のドメインの「Manage Domain」をクリックします。

「Management Tools」 > 「Nameservers」
をクリックします。

f:id:sakura_bird1:20190310184421p:plain:w400

「Use custom nameservers」という項目にチェックを入れてから
Google Cloud DNS で取得した 4 つのレコード情報を入力し、「Change Nameservers」ボタンをクリックします。

f:id:sakura_bird1:20190310184951p:plain:w400

これでネームサーバーの設定は終わりです。

8. http://独自ドメイン:3000という形でウェブサイトが表示できることを確認する

ここまでの作業でdousa-kensho.tkというドメインとサーバーの IP アドレスが紐付いたのでブラウザでアクセスして確認します。
前回までのテスト時と同じくポート 3000 番で外部に公開しているので、確認するアドレスはこのようになります。

http://dousa-kensho.tk:3000
http://www.dousa-kensho.tk:3000

このように表示できました。
f:id:sakura_bird1:20190310185655p:plain:w400

今回はこれで終わりです。
次回はhttps+ドメインでアクセスできるようにします。
Google Cloud DNS は有料なのでアクセスが確認出来たら、ゾーンの設定は早めに削除しておきます。

9. 関連リンク

【5】GCP(GCE)でRailsアプリを外部IPアドレス+3000番ポートで動かしてみる(環境変数COMPOSE_FILE、GCE+Docker+Rails+Puma+PostgreSQL)

これはHerokuからGCP無料枠にRailsアプリを引越ししたときにやったことシリーズの【4】の続きです。
GCE に 作成した VM インスタンス上で Rails アプリを動かしてみるところのメモです。
http://localhost:3000/ でテストしていたものをそのまま GCE に持っていって動かすようなことをします。

1. 公式サイト

2. 目標

  • 環境変数 COMPOSE_FILE を GCE に設定して複数ある環境用の docker-compose.yml を読み込めるようにする
  • 3000 番ポートを開ける
  • Docker Compose コマンドを実行して Rails アプリが動くのを確認する

3. 注意点

  • Docker は勉強中ですので、Dockerfile や docker-compose.yml などはとりあえず動くことを確認するもの程度に考えていただければと思います。

  • 作業対象である Rails アプリ「ポケット糖質量」のデータは csv ファイルから投入すれば出来上がり、しかも ReadOnly なデータです。
    ほとんどソースコードの一部のようなものなので、DB をコンテナの外に設定していません。
    コンテナを消せば DB もすべて消えてしまいます。
    アプリの仕様によりこのような環境になっておりますので、参考にする時はご注意ください。

4. 参考サイト様

本当に参考になりました。ありがとうございます!

5. 環境変数 COMPOSE_FILE を GCE に設定して複数ある環境用の docker-compose.yml を読み込めるようにする

参考サイト様によると、 環境ごとに別名で作ってある docker-compose.yml を-fオプション無しで使う方法として環境変数 COMPOSE_FILE を設定すればよいということですので、設定してみたいと思います。
例として次の 2 つの環境用のファイルを用意します。

stage ファイル名
development docker-compose.development.yml
production docker-compose.production.yml

なお docker-compose.yml を用意しておいて共通の処理を書いておき、各環境用ファイルは差分を書いておくことで AND 合体されるというやり方もできるようです。

5.1. コマンドで環境変数 COMPOSE_FILE を設定する(一時的)

exportコマンドを使ってファイル名を COMPOSE_FILE 変数に入れます。
2 行目は COMPOSE_FILE 変数の中身を表示しています。

この方法はログアウトしてログインし直すと COMPOSE_FILE 変数自体消えてしまいます。

$export COMPOSE_FILE=docker-compose.development.yml
$env | grep COMPOSE_FILE

5.2. bashrc に環境変数 COMPOSE_FILE を設定する(永続的)

.bashrc を編集して環境変数 COMPOSE_FILE を設定します。
ログアウトしても COMPOSE_FILE 変数の設定はそのままです。

$nano ~/.bashrc

エディタを起動したら次の例のように書き加えます。

# docker-composeのデフォルトComposeファイルを本番用に設定
export COMPOSE_FILE=docker-compose.production.yml

保存後、次のように実行します。

$source ~/.bashrc

これでいつでも$env | grep COMPOSE_FILEを実行すると設定したファイル名が表示されると思います。

f:id:sakura_bird1:20190306155728p:plain:w400

6. 3000番ポートを開ける

GCE のインスタンスファイアウォールルールを設定して、Rails のデフォルトポート番号である 3000 番のポートを開ける処理を行います。

ポートを開ける処理はこのシリーズ記事の
【2】GCP(GCE)で無料の VM インスタンスを作る(Always Free 無料枠、外部 IP アドレス取得、SSH 接続、22 番ポート対応)
でも記述しております。

6.1. ファイアウォールルールの作成

ナビゲーションメニューから「ネットワーク詳細の表示」を選択します。

f:id:sakura_bird1:20190307015052p:plain:w400

ファイアウォールルール」→「ファイアウォールルールを作成」をクリックします。

f:id:sakura_bird1:20190307015159p:plain:w400

次の項目を設定します。

入力項目 内容
名前 デフォルトのルールにならって、 allow-3000 (3000 はポート番号)にするとよい
ターゲットタグ デフォルトのルールにならって、 allow3000-server にするとよい
ソース IP の範囲 0.0.0.0/0
プロトコルとポート 指定したプロトコルとポートをクリックし tcp のところに 3000 を入力する

f:id:sakura_bird1:20190307015409p:plain:w400

f:id:sakura_bird1:20190307015435p:plain:w400

入力し終えたら「保存」を押して追加されたのを確認します。 ここで入力したターゲットタグをインスタンスのネットワークタグに追加します。

VM インスタンスの詳細」→「編集」画面でターゲットタグを追加します。

f:id:sakura_bird1:20190307015532p:plain:w400

GCE 側の設定はこれでできました。

7. Docker Compose コマンドを実行して Rails アプリが動くのを確認する

このエントリの題名に「GCE+Docker+Rails+Puma+PostgreSQL」と書いてありますが、GCE と Docker 以外はローカルで Rails5 でrails newした時の構成とほとんど同じです。
DB が PostgreSQL になってるところぐらいが違うでしょうか。
http://localhost:3000/ でテストしていたものをそのまま GCE に持っていって動かすようなイメージで動作確認してみたいと思います。

前提としてアプリのソースコードが入ったプロジェクトディレクトリは VM 上にコピー済みとします。

環境変数 COMPOSE_FILEはdevelopmentをセットしておきます。

7.1. Dockerfile

Dockerfile は必死でググってこんな感じにしました。内容の説明は割愛させていただきます。

FROM ruby:2.5.3-alpine3.8
LABEL maintainer="My Name" Name=pocket_carbo Version=0.0.1

ENV LANG C.UTF-8

ENV APP_PATH /usr/src/app

WORKDIR $APP_PATH

COPY Gemfile $APP_PATH
COPY Gemfile.lock $APP_PATH

ENV RUNTIME_PACKAGES="libxml2-dev libxslt-dev libstdc++ bash tzdata postgresql-dev postgresql-client nodejs ca-certificates"\
  DEV_PACKAGES="build-base"

RUN set -x && \
  apk add --update --no-cache $RUNTIME_PACKAGES &&\
  apk add --update\
  --virtual build-dependencies\
  --no-cache\
  $DEV_PACKAGES &&\
  gem install bundler --no-document &&\
  bundle config build.nokogiri --use-system-libraries &&\
  bundle install &&\
  apk del build-dependencies && \
  cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
  rm -rf /var/cache/apk/*

COPY . APP_PATH

EXPOSE 3000

7.2. docker-compose.yml

この時点での docker-compose.development.yml ファイルはこんな感じです。

version: '3'
services:
  db:
    image: postgres:11.1-alpine
    ports:
      - '5432'
    volumes:
      - db-data:/var/lib/postgresql/data
  web:
    build: .
    command: bash -c "rm -f ./tmp/pids/server.pid; bundle exec rails s -p 3000 -b '0.0.0.0'"

    volumes:
      - .:/usr/src/app
      - bundle-data:/bundle
    environment:
      RAILS_ENV: development
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes:
  bundle-data:
  db-data:

7.3. /config/database.yml

この時点での/config/database.yml はこんな感じです。
staging は結局環境を作らなかったんですが、定義だけしてあります。
DB が外部ではないのでコンテナを削除するとデータも全てなくなります。

default: &default
adapter: postgresql
encoding: utf8
# For details on connection pooling, see rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: db
username: postgres
password:

development:
<<: *default
database: db/pocket_carbo_development

test:
<<: *default
database: db/pocket_carbo_test

staging:
<<: *default
database: db/pocket_carbo_staging

production:
<<: *default
database: db/pocket_carbo_production

7.4. docker-compose コマンドでビルド&起動

これらのコマンドを実行していきます。
自分が実行する時はスクリプトファイルを実行する形にしてますが、あまりイケてないですね。
私のアプリでは初期データ投入が必要なのでrails db:seedしています。

#!/usr/bin/env bash

docker-compose build

docker-compose run --rm web bin/rails db:create
docker-compose run --rm web bin/rails db:migrate
docker-compose run --rm web bin/rails assets:precompile
docker-compose run --rm web bin/rails db:seed

docker-compose up -d

うまくいけばhttp://[外部IPアドレス]:3000でアプリ画面が表示されます。

f:id:sakura_bird1:20190307043046p:plain:w500

今回は以上です。
このシリーズでは今後独自ドメインで表示、SSL対応をするのでdocker-compose.ymlは変わっていきます。
次回は今回動かしたアプリをhttps+独自ドメインでアクセス出来るようにするための下準備として、テスト用の独自ドメインを取得してDNSサーバーの設定をして動かしてみます。

8. 関連リンク

【4】GCP(GCE)のVMインスタンスにファイルを転送する(Cyberduck, scpコマンド)

これはHerokuからGCP無料枠にRailsアプリを引越ししたときにやったことシリーズの【3】の続きです。
GCE に 作成した VM インスタンスに Docker などのインストールをし、設定を行ったところです。
今回はソースコードや設定ファイルなどを転送する方法について書いてみたいと思います。

1. 公式サイト

2. 目標

3. 注意点

4. 参考サイト様

本当に参考になりました。ありがとうございます!

5. ファイル転送方法の種類

GCE のインスタンスにファイルを転送する方法としては次の項目が代表的なものとして挙げられます。
CIなどを使用しているケースはここでは扱いません。

私は Github からソースコードを pull しています。
.gitignore に入っているような.envmaster.keyファイルなどは Cyberduck を使って転送しています。
今の所これで事足りています。

当エントリでは Cyberduck と scp コマンドを使う方法について触れてみたいと思います。

6. Cyberduck(Mac)を使う

前提としてCyberduck 公式サイトからダウンロードしてインストールされているとします。
私の PC が Macbook なので Mac 前提で説明いたします。

起動後、左上の「新規作成」ボタンをクリックします。

f:id:sakura_bird1:20190308004327p:plain:w400

ダイアログの転送方法のリストから、
「SFTP(SSH による暗号化 FTP)」を選択します。

以下の項目を入力し、「接続」ボタンをクリックします。

項目 入力内容
サーバ GCE のインスタンスの外部 IP アドレス
ポート 22 番を塞いだ代わりに開けたポート番号※このシリーズ【2】参照
ユーザー名 SSH 接続する時のユーザー名
SSH Private Key ~/.ssh/[SSH ログインの時に使う認証鍵の名前]

f:id:sakura_bird1:20190308005834p:plain:w400

接続できるとユーザーのディレクトリが表示されます。

f:id:sakura_bird1:20190308021409p:plain:w400

デフォルトだと隠しファイルは表示されないので、
「表示」→「不可視ファイルを表示」と
「環境設定」→「ブラウザ」→「'.'で始まるファイルを表示」にチェックしておくとよいです。

これでファイル転送したり、ディレクトリを作ったり出来るようになりました。
ファイルを転送する場合、画面の上の方の「アクション」ボタンを押して
「アップロード」を選択するとできます。

7. Linux の scp コマンドを使う

ローカルのファイルをリモートにコピーする時はこのような書式になります。

scp ファイル名 接続先:パス名

次の例のように実行できます。
ここで使っているオプションは次の通りです。
・ -i は秘密鍵ファイル
・ -P はポート番号
・ -r はディレクトリ内のデータを再帰的にコピーする

$scp -i ~/.ssh/google_compute_engine -P 40022 test.txt sakura@[GCEの外部IPアドレス]:./

カレントディレクトリのtest.txtを sakura ユーザーのディレクトリの直下にコピーしています。

$scp -i ~/.ssh/google_compute_engine -P 40022 -r test sakura@[GCEの外部IPアドレス]:./

カレントディレクトリのtestディレクトリと配下のデータを sakura ユーザーのディレクトリの直下にコピーしています。

8. ファイル転送のパーミッション

Cyberduck でも scp コマンドでも、何もしないとファイルを転送する時は SSH 接続したユーザーのディレクトリ配下にしか転送出来ません。
他のディレクトリに転送しようとするとパーミッションエラー(Permission denied)になるからです。

自分一人でサーバーを使っている分にはディレクトリのパーミッションを 777 に変更してしまうのが手っ取り早いやり方だと思います。

$sudo chmod -R 777 /home/test

複数の人が使っている場合は(絶対に運用ルールを決めるべきですが)
777 にするよりは、一時的に root 権限でログインし、ファイルをユーザーディレクトリ → コピー先にコピーする
という方法のほうがいいかなあという気がします。

今回はこれで終わりです。
次回はサーバー上でDockerコンテナを動かしてみたいと思います。

9. 関連リンク