ということで、DockerでNginxのコンテナをつくり、Webページ(サービス)を公開する手順をまとめる。
今回つかう環境は以下のとおり。
- CentOS 7.2(ホストOS)
- Docker 1.12.3
- Nginx 1.11.5
ホストOSの準備
ホストOSは、さくらのクラウドの1コア/1GBプランのCentOS 7.2を使うことにした。
イベントやたまーにWeb上で2万円クーポンを配布しているので、ありがたく使わせてもらう。
CentOSの初期設定などは、以下の記事を参考にしていただければ、スクリプト一発で完了する。
サーバを作成したら、SSHで接続、ログインする。
Dockerのインストール
公式ドキュメントに従い、ホストOSにDockerをインストールする。
※今回はrootでログインしているのでsudoは使っていない。もし前述のセットアップスクリプトを使って一般ユーザでログインした場合は、適宜各コマンドの先頭にsudoがつくと読み替えてほしい。
# update
$ yum update -y
# yum repositoryにdockerを追加
$ tee /etc/yum.repos.d/docker.repo <<-'__EOF__'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
__EOF__
$ yum install docker-engine -y
$ systemctl enable docker.service
$ systemctl start docker
設定ファイルやHTMLファイル等の準備
今回は以下のようなディレクトリ構成でファイル等を準備する。
Dockerfileは、Dockerでイメージを作るときの定義ファイル。docker buildコマンドを実行すると、書かれた処理を上から順に実行され、Dockerイメージが作成される。
app.confは、Nginxの設定ファイル。アクセスされたときにどのディレクトリのHTMLファイルを参照するかなどを記述する。
keys配下は、HTTPS接続するためのオレオレ証明書(自己証明)が入っている。
(本来は認証局で発行してもらったサーバ証明書を使う)
www/index.htmlが、今回表示したいHTMLファイル。
. ├── Dockerfile // <-- Dockerイメージの設計書 ├── app.conf // <-- Nginxの設定ファイル ├── keys │ ├── server.crt // <-- サーバ証明書 │ ├── server.csr // <-- 証明書署名要求ファイル │ └── server.key // <-- 秘密鍵 └── www └── index.html // <-- 今回参照するファイル
Nginxの設定ファイルの作成
server {
listen 80;
server_name localhost;
return 301 https://$host$request_uri;
}
server {
server_tokens off;
access_log /root/logs/access.log;
error_log /root/logs/error.log;
listen 443;
server_name localhost;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
location / {
alias /root/www/;
}
}
今回は、HTTPS対応するためにSSLの設定をしている。
80番ポート(http)でアクセスされた場合は、httpsにリダイレクトする。
location /で https://ipaddressでアクセスしたときに表示するパスを指定している。
デフォルトでindex.htmlやindexというファイルを自動で参照してくれるが、index.htmやその他のファイル名(index.phpなど)を使う場合は、index index.htm index.phpと指定する必要がある。
オレオレ証明書(自己証明書)の作成
本来なら認証局が発行した証明書を使うべきなのだが、実験用なのでオレオレ証明書で代用する。(Let's Encryptなら無料で発行することも可能)
証明書を作成するためにはopensslコマンドを使うので、以下の手順でmod_sslをインストールする。
# yum install mod_ssl -y
以下の手順は、./keysに移動して実行しているものとする。
秘密鍵の作成
秘密鍵を暗号化してしまうと、コンテナ起動時(Nginx起動時)に「Enter PEM pass phrase」とパスワードが求められ起動できないので注意。
暗号化しないので、後述するがパーミッションを400などに変更しておく必要がある。
# openssl genrsa 2048 > server.key
Generating RSA private key, 2048 bit long modulus
............................................+++
.........................+++
e is 65537 (0x10001)
証明書署名要求の作成
# openssl req -new -key server.key > server.csr
Enter pass phrase for server.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP // <-- 国名
State or Province Name (full name) []:Tokyo // <-- 都道府県
Locality Name (eg, city) [Default City]:Ota-ku // <-- 市区町村
Organization Name (eg, company) [Default Company Ltd]:Black Everyday Company // <-- 会社名or組織名
Organizational Unit Name (eg, section) []:Blog // <-- 部署名
Common Name (eg, your name or your server's hostname) []:example.com // <-- 認証を受けるホスト名
Email Address []:hoge@example.com // <-- メールアドレス
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: // <-- パスワードは空白でOK
An optional company name []: // <-- オプションの会社名も空白でOK
ここで指定した国名、会社名が証明書の詳細情報となる。(ブラウザで確認できる)
サーバ証明書を作ったら、このファイルは不要なので削除しても良い。
サーバ証明書の作成
今回は実験用なので30日間有効なサーバ証明書を作成している。有効期間を伸ばしたい場合は、「-days <日数>」を好きな期間に変更してほしい。
# openssl x509 -in server.csr -days 30 -req -signkey server.key > server.crt
Signature ok
subject=/C=JP/ST=Tokyo/L=Ota-ku/O=Black Everyday Company/OU=Blog/CN=example.com/emailAddress=hoge@example.com
Getting Private key
Enter pass phrase for server.key:
Dockerfileの作成
FROM nginx
MAINTAINER BcRikko
ADD ./www /root/www
ADD ./app.conf /etc/nginx/conf.d/app.conf
ADD ./keys/server.crt /etc/nginx/server.crt
ADD ./keys/server.key /etc/nginx/server.key
RUN mkdir /root/logs
RUN chmod 755 -R /root
RUN chmod 400 /etc/nginx/server.key
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
1行目: FROM nginxでNginxの最新のイメージを取得する。
どんなイメージがあるかはDocker Hubで検索できる。
5行目: ホストOSの./wwwにあるファイルを、コンテナ内の/root/wwwに追加(コピー)する。
6行目: ホストOSの./app.confを、コンテナ内の/etc/nginx/conf.d/app.confに追加する。
nginxは /etc/nginc/conf.d配下の[*.conf]というファイルを読み込むので、app.confでなくともsettings.confとかでもOK。
7行目: ホストOSにあるデジタル証明書(./keys/server.crt)を、コンテナ内の/etc/nginx/server.crtに追加する。
8行目: ホストOSにある秘密鍵(./keys/server.key)を、コンテナ内の/etc/nginx/server.keyに追加する。
11行目: コンテナ内の/root配下のパーミッションを755(所有者はフル権限、それ以外は読み込みと実行権限のみ)に変更する。
これをしないとWebサーバにアクセスしたときに、「403 Forbidden」になってしまうので注意。
12行目: サーバの秘密鍵にパスフレーズをつけていないので、所有者(root)以外は読書不可にする。所有者も読み込み権限しかない。
14行目: ポート443を開放する。
15行目: Nginxを起動するコマンド。ただし、Nginxをそのまま実行するとバックグラウンドで動いてしまいDockerがすぐ止まってしまう。そのため「-g daemon off;」というオプションを付けて、フォアグラウンドで実行するようにしている。
イメージの作成とコンテナ起動
# Dockerfileからイメージを作成
$ docker build -t webapp .
# 作成されたイメージの確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
webapp latest c4c1cfa648ef 22 seconds ago 181.4 MB
nginx latest e43d811ce2f4 12 days ago 181.4 MB
# コンテナの起動
$ docker run -d -p 443:443 -p 80:80 webapp
# コンテナの起動状況の確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
944913c6e58a webapp "nginx -g 'daemon off" 3 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp lonely_visvesvaraya
これで「https://IPアドレス」でアクセスすると以下のような警告ページが表示される。
自己証明の場合は、SSL/TLSによる暗号化通信はできるものの中間者攻撃の危険性があるため、このような警告ページが表示されるようになっている。
「詳細情報を表示する」→「IPアドレスにアクセスする(安全ではありません)」をクリックすると、/root/www/index.htmlの内容が表示される。
コンテナが立ち上がらなかった場合は、以下のコマンドで立ち上がらなかった理由を調べる。
# コンテナ一覧(停止中含む)を表示
$docker ps -a
# ログを確認
docker logs <container id>
もしDockerfileやapp.confなどの修正が必要になったら、docker buildでイメージを再作成する。
単純にコンテナを停止、再度起動したいだけなら、以下のコマンドを実行する
# コンテナの停止
$ docker stop <container id>
# コンテナの再起動
$ docker start <container id>
また起動しているコンテナに入りたい場合は、docker execコマンドを利用する。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
944913c6e58a webapp "nginx -g 'daemon off" 3 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp lonely_visvesvaraya
# 起動しているコンテナに入る
$ docker exec -it lonely_visvesvaraya /bin/bash
参考サイト
Dockerについて
- Dockerfile のベストプラクティス — Docker-docs-ja 1.9.0b ドキュメント
- 効率的に安全な Dockerfile を作るには - Qiita
- よく使うDockerコマンド - Qiita
Nginxについて
以上
written by @bc_rikko
0 件のコメント :
コメントを投稿