コンテナ化されたNode.jsアプリケーションをNginx、Let’sEncrypt、DockerComposeで保護する方法
序章
Node.jsアプリケーションの柔軟性とセキュリティを強化する方法は複数あります。 Nginx のようなリバースプロキシを使用すると、リクエストの負荷分散、静的コンテンツのキャッシュ、トランスポート層セキュリティ(TLS)の実装が可能になります。 サーバーで暗号化されたHTTPSを有効にすると、アプリケーションとの間の通信が安全に保たれます。
コンテナにTLS/SSLを使用してリバースプロキシを実装するには、ホストオペレーティングシステムで直接作業する場合とは異なる一連の手順が必要です。 たとえば、サーバーで実行されているアプリケーションの Let’s Encrypt から証明書を取得する場合は、必要なソフトウェアをホストに直接インストールします。 コンテナを使用すると、別のアプローチを取ることができます。 Docker Compose を使用すると、アプリケーション、Webサーバー、およびCertbotクライアントのコンテナーを作成して証明書を取得できます。 これらの手順に従うことで、コンテナ化されたワークフローのモジュール性と移植性を活用できます。
このチュートリアルでは、Docker Composeを使用して、Nginxリバースプロキシを使用してNode.jsアプリケーションをデプロイします。 アプリケーションに関連付けられているドメインのTLS/SSL証明書を取得し、 SSLLabsから高いセキュリティ評価を受けていることを確認します。 最後に、 cron ジョブを設定して証明書を更新し、ドメインのセキュリティを維持します。
前提条件
このチュートリアルに従うには、次のものが必要です。
-
An Ubuntu 18.04 server, a non-root user with
sudo
特権、およびアクティブなファイアウォール。 For guidance on how to set these up, please read this Initial Server Setup guide. -
サーバーにインストールされているDockerとDockerCompose。 For guidance on installing Docker, follow Steps 1 and 2 of How To Install and Use Docker on Ubuntu 18.04. For guidance on installing Compose, follow Step 1 of How To Install Docker Compose on Ubuntu 18.04.
-
登録されたドメイン名。 This tutorial will use your_domain throughout. Freenom で無料で入手するか、選択したドメインレジストラを使用できます。
-
次の両方のDNSレコードがサーバー用に設定されています。 DigitalOceanアカウントに追加する方法の詳細については、このDigitalOcean DNSの概要をフォローしてください(使用している場合)。
- とのAレコード
your_domain
サーバーのパブリックIPアドレスを指します。 - とのAレコード
www.your_domain
サーバーのパブリックIPアドレスを指します。
- とのAレコード
Once you have everything set up, you’re ready to begin the first step.
ステップ1—ノードアプリケーションのクローン作成とテスト
As a first step, you’ll clone the repository with the Node application code, which includes the Dockerfile to build your application image with Compose. Then you’ll test the application by building and running it with the docker run command, without a reverse proxy or SSL.
In your non-root user’s home directory, clone the nodejs-image-demo repository from the DigitalOcean Community GitHub account. This repository includes the code from the setup described in How To Build a Node.js Application with Docker.
Clone the repository into a directory. This example uses node_project
as the directory name. Feel free to name this directory to your liking:
- git clone https://github.com/do-community/nodejs-image-demo.git node_project
Change into the node_project
ディレクトリ:
- cd node_project
このディレクトリには、 Docker node:10imageと現在のプロジェクトディレクトリの内容を使用してノードアプリケーションを構築するための手順を含むDockerfileがあります。 You can preview the contents of the Dockerfile with the following:
- cat Dockerfile
OutputFROM node:10-alpine
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY package*.json ./
USER node
RUN npm install
COPY --chown=node:node . .
EXPOSE 8080
CMD [ "node", "app.js" ]
これらの手順では、プロジェクトコードを現在のディレクトリからコンテナにコピーし、依存関係をインストールしてノードイメージを構築します。 npm install
. また、Dockerのキャッシングとイメージレイヤーを利用して、 package.json
と package-lock.json
、残りのアプリケーションコードのコピーから、プロジェクトのリストされた依存関係を含みます。 Finally, the instructions specify that the container will be run as the non-root node user with the appropriate permissions set on the application code and node_modules
ディレクトリ。
For more information about this Dockerfile and Node image best practices, please explore the complete discussion in Step 3 of How To Build a Node.js Application with Docker.
SSLを使用せずにアプリケーションをテストするには、 dockerbuildと -t
国旗。 This example names the image node-demo
、ただし、他の名前を付けることもできます。
- docker build -t node-demo .
ビルドプロセスが完了すると、 dockerimagesを使用してイメージを一覧表示できます。
- docker images
The following output confirms the application image build:
OutputREPOSITORY TAG IMAGE ID CREATED SIZE
node-demo latest 23961524051d 7 seconds ago 73MB
node 10-alpine 8a752d5af4ce 3 weeks ago 70.7MB
次に、でコンテナを作成します docker run
. Three flags are included with this command:
-p
: This publishes the port on the container and maps it to a port on your host. You will use port80
on the host in this example, but feel free to modify this as necessary if you have another process running on that port. For more information about how this works, review this discussion in the Docker documentation on port binding.-d
:これは、コンテナをバックグラウンドで実行します。--name
: This allows you to give the container a memorable name.
次のコマンドを実行して、コンテナーを作成します。
- docker run --name node-demo -p 80:8080 -d node-demo
dockerpsを使用して実行中のコンテナーを検査します。
- docker ps
The following output confirms that your application container is running:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4133b72391da node-demo "node app.js" 17 seconds ago Up 16 seconds 0.0.0.0:80->8080/tcp node-demo
これで、ドメインにアクセスしてセットアップをテストできます。 http://your_domain
. 交換することを忘れないでください your_domain
あなた自身のドメイン名で。 アプリケーションは次のランディングページを表示します。
アプリケーションのテストが完了したので、コンテナーを停止してイメージを削除できます。 使用する docker ps
to get your CONTAINER ID
:
- docker ps
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4133b72391da node-demo "node app.js" 17 seconds ago Up 16 seconds 0.0.0.0:80->8080/tcp node-demo
dockerstopでコンテナを停止します。 必ず交換してください CONTAINER ID
独自のアプリケーションとともにここにリストされています CONTAINER ID
:
- docker stop 4133b72391da
docker system pruneと -a
国旗:
- docker system prune -a
Press y
停止したコンテナとイメージを削除することを確認するために出力でプロンプトが表示されたら。 これにより、ビルドキャッシュも削除されることに注意してください。
アプリケーションイメージをテストしたら、DockerComposeを使用して残りのセットアップの構築に進むことができます。
ステップ2—Webサーバー構成の定義
With our application Dockerfile in place, you’ll create a configuration file to run your Nginx container. You can start with a minimal configuration that will include your domain name, document root, proxy information, and a location block to direct Certbot’s requests to the .well-known
directory, where it will place a temporary file to validate that the DNS for your domain resolves to your server.
First, create a directory in the current project directory, node_project
, for the configuration file:
- mkdir nginx-conf
Create and open the file with nano
またはお気に入りの編集者:
- nano nginx-conf/nginx.conf
次のサーバーブロックを追加して、ユーザーリクエストをノードアプリケーションコンテナにプロキシし、Certbotのリクエストを .well-known
ディレクトリ。 必ず交換してください your_domain
あなた自身のドメイン名で:
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain www.your_domain;
location / {
proxy_pass http://nodejs:8080;
}
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
}
This server block will allow you to start the Nginx container as a reverse proxy, which will pass requests to your Node application container. It will also allow you to use Certbot’s webroot plugin to obtain certificates for your domain. このプラグインは、 HTTP-01検証メソッドに依存しています。このメソッドは、HTTPリクエストを使用して、Certbotが特定のドメイン名に応答するサーバーからリソースにアクセスできることを証明します。
編集が終了したら、ファイルを保存して閉じます。 If you used nano
, you can do this by pressing CTRL + X
, then Y
, and ENTER
. To learn more about Nginx server and location block algorithms, please refer to this article on Understanding Nginx Server and Location Block Selection Algorithms.
With the web server configuration details in place, you can move on to creating your docker-compose.yml
file, which will allow you to create your application services and the Certbot container you will use to obtain your certificates.
ステップ3—Docker作成ファイルの作成
The docker-compose.yml
file will define your services, including the Node application and web server. 名前付きボリュームなどの詳細を指定します。これは、コンテナー間でSSLクレデンシャルを共有するために重要であり、ネットワークおよびポート情報も指定します。 It will also allow you to specify commands to run when your containers are created. This file is the central resource that will define how your services will work together.
Create and open the file in your current directory:
- nano docker-compose.yml
まず、アプリケーションサービスを定義します。
version: '3'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
restart: unless-stopped
The nodejs
サービス定義には次のものが含まれます。
build
:これは、以下を含む構成オプションを定義します。context
とdockerfile
、これは、Composeがアプリケーションイメージをビルドするときに適用されます。 Docker Hub などのレジストリの既存のイメージを使用する場合は、代わりに image命令を使用して、ユーザー名、リポジトリ、イメージタグに関する情報を使用できます。context
:これは、アプリケーションイメージビルドのビルドコンテキストを定義します。 In this case, it’s the current project directory which is represented with the.
.dockerfile
: This specifies the Dockerfile that Compose will use for the build — the Dockerfile reviewed at in Step 1.image
,container_name
:これらは画像とコンテナに名前を適用します。restart
:これは再起動ポリシーを定義します。 デフォルトはno
, but in this example, the container is set to restart unless it is stopped.
Note that you are not including bind mounts with this service, since your setup is focused on deployment rather than development. For more information, please read the Docker documentation on bind mounts and volumes.
To enable communication between the application and web server containers, add a bridge network called app-network
after the restart definition:
services:
nodejs:
...
networks:
- app-network
このようなユーザー定義のブリッジネットワークにより、同じDockerデーモンホスト上のコンテナー間の通信が可能になります。 これにより、アプリケーション内のトラフィックと通信が合理化されます。これは、同じブリッジネットワーク上のコンテナ間のすべてのポートを開き、ポートを外部に公開しないためです。 したがって、フロントエンドサービスを公開するために必要なポートのみを開くことを選択できます。
次に、を定義します webserver
サービス:
...
webserver:
image: nginx:mainline-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- web-root:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
depends_on:
- nodejs
networks:
- app-network
Some of the settings defined here for the nodejs
service remain the same, but some of the following changes were made:
image
:これは、DockerHubから最新のAlpineベースNginxイメージをプルするようにComposeに指示します。 詳細についてはalpine
images, please read Step 3 of How To Build a Node.js Application with Docker.ports
:これはポートを公開します80
to enable the configuration options you’ve defined in your Nginx configuration.
The following named volumes and bind mounts are also specified:
web-root:/var/www/html
: This will add your site’s static assets, copied to a volume calledweb-root
、に/var/www/html
コンテナのディレクトリ。./nginx-conf:/etc/nginx/conf.d
: This will bind mount the Nginx configuration directory on the host to the relevant directory on the container, ensuring that any changes you make to files on the host will be reflected in the container.certbot-etc:/etc/letsencrypt
: This will mount the relevant Let’s Encrypt certificates and keys for your domain to the appropriate directory on the container.certbot-var:/var/lib/letsencrypt
:これにより、Let’sEncryptのデフォルトの作業ディレクトリがコンテナの適切なディレクトリにマウントされます。
次に、の構成オプションを追加します certbot
容器。 ドメインと電子メール情報を自分のドメイン名と連絡先電子メールに必ず置き換えてください。
...
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- web-root:/var/www/html
depends_on:
- webserver
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
この定義は、DockerHubからcertbot / certbotimageをプルするようにComposeに指示します。 また、名前付きボリュームを使用して、ドメイン証明書やキー入力などのリソースをNginxコンテナと共有します certbot-etc
、Let’sEncryptの作業ディレクトリ certbot-var
、およびのアプリケーションコード web-root
.
Again, you’ve used depends_on
そのことを指定するには certbot
コンテナは一度開始する必要があります webserver
サービスが実行されています。
The command
option specifies the command to run when the container is started. それは含まれています certonly
次のオプションを使用したサブコマンド:
--webroot
:これは、認証のためにwebrootプラグインを使用してファイルをwebrootフォルダーに配置するようにCertbotに指示します。--webroot-path
:これは、webrootディレクトリのパスを指定します。--email
:登録と復旧のためのご希望のメールアドレス。--agree-tos
:これは、ACMEのサブスクライバー契約に同意することを指定します。--no-eff-email
:これは、電子メールを Electronic Frontier Foundation (EFF)と共有したくないことをCertbotに通知します。 必要に応じて、これを省略してください。--staging
:これは、Let’sEncryptのステージング環境を使用してテスト証明書を取得することをCertbotに通知します。 このオプションを使用すると、構成オプションをテストして、ドメイン要求の制限を回避できます。 For more information about these limits, please read Let’s Encrypt’s rate limits documentation.-d
:これにより、リクエストに適用するドメイン名を指定できます。 In this case, you’ve includedyour_domain
とwww.your_domain
. Be sure to replace these with your own domains.
最後のステップとして、ボリュームとネットワークの定義を追加します。 Be sure to replace the username here with your own non-root user:
...
volumes:
certbot-etc:
certbot-var:
web-root:
driver: local
driver_opts:
type: none
device: /home/sammy/node_project/views/
o: bind
networks:
app-network:
driver: bridge
Your named volumes include your Certbot certificate and working directory volumes, and the volume for your site’s static assets, web-root
. ほとんどの場合、Dockerボリュームのデフォルトドライバーは local
Linuxではmountコマンドと同様のオプションを受け入れるドライバー。 Thanks to this, you are able to specify a list of driver options with driver_opts
マウントします views
directory on the host, which contains your application’s static assets, to the volume at runtime. その後、ディレクトリの内容をコンテナ間で共有できます。 内容の詳細については views
directory, please read Step 2 of How To Build a Node.js Application with Docker.
The following is the complete docker-compose.yml
file:
version: '3'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
restart: unless-stopped
networks:
- app-network
webserver:
image: nginx:mainline-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- web-root:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
depends_on:
- nodejs
networks:
- app-network
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- web-root:/var/www/html
depends_on:
- webserver
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
volumes:
certbot-etc:
certbot-var:
web-root:
driver: local
driver_opts:
type: none
device: /home/sammy/node_project/views/
o: bind
networks:
app-network:
driver: bridge
サービス定義が整ったら、コンテナを起動して証明書要求をテストする準備が整います。
ステップ4—SSL証明書とクレデンシャルを取得する
You can start the containers with docker-compose up. This will create and run your containers and services in the order you have specified. Once your domain requests succeed, your certificates will be mounted to the /etc/letsencrypt/live
上のフォルダ webserver
容器。
でサービスを作成する docker-compose up
with the -d
フラグを実行します nodejs
と webserver
バックグラウンドのコンテナ:
- docker-compose up -d
Your output will confirm that your services have been created:
OutputCreating nodejs ... done
Creating webserver ... done
Creating certbot ... done
Use docker-compose ps to check the status of your services:
- docker-compose ps
すべてが成功した場合、あなたの nodejs
と webserver
services will be Up
そしてその certbot
コンテナは 0
status message:
Output Name Command State Ports
------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
nodejs node app.js Up 8080/tcp
webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp
If you notice anything other than Up
の中に State
の列 nodejs
と webserver
サービス、または以外の終了ステータス 0
のために certbot
container, be sure to check the service logs with the docker-compose logs command. For example, if you wanted to check the Certbot log, you would run:
- docker-compose logs certbot
これで、資格情報がにマウントされていることを確認できます webserver
docker-compose exec を含むコンテナー:
- docker-compose exec webserver ls -la /etc/letsencrypt/live
Once your request succeeds, your output will reveal the following:
Outputtotal 16
drwx------ 3 root root 4096 Dec 23 16:48 .
drwxr-xr-x 9 root root 4096 Dec 23 16:48 ..
-rw-r--r-- 1 root root 740 Dec 23 16:48 README
drwxr-xr-x 2 root root 4096 Dec 23 16:48 your_domain
リクエストが成功することがわかったので、編集できます certbot
削除するサービス定義 --staging
国旗。
Open the docker-compose.yml
file:
- nano docker-compose.yml
でファイルのセクションを検索します certbot
サービス定義、および置換 --staging
のフラグ command
オプションと --force-renewal
国旗。 This will tell Certbot that you want to request a new certificate with the same domains as an existing certificate. The certbot
service definition should have the following definitions:
...
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- web-root:/var/www/html
depends_on:
- webserver
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...
When you’re done editing, save and exit the file. これで実行できます docker-compose up
を再現するには certbot
コンテナとその関連ボリューム。 By including the --no-deps
option, you’re telling Compose that it can skip starting the webserver
サービス、すでに実行されているため:
- docker-compose up --force-recreate --no-deps certbot
The following output indicates that your certificate request was successful:
OutputRecreating certbot ... done
Attaching to certbot
certbot | Account registered.
certbot | Renewing an existing certificate for your_domain and www.your_domain
certbot |
certbot | Successfully received certificate.
certbot | Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
certbot | Key is saved at: /etc/letsencrypt/live/your_domain phd.com/privkey.pem
certbot | This certificate expires on 2022-11-03.
certbot | These files will be updated when the certificate renews.
certbot | NEXT STEPS:
certbot | - The certificate will need to be renewed before it expires. Cert bot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setu p for instructions.
certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot |
certbot | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
certbot | If you like Certbot, please consider supporting our work by:
certbot | * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/do nate
certbot | * Donating to EFF: https://eff.org/donate-le
certbot | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
certbot exited with code 0
証明書を配置したら、Nginx構成を変更してSSLを含めることができます。
手順5—Webサーバーの構成とサービス定義を変更する
Enabling SSL in your Nginx configuration will involve adding an HTTP redirect to HTTPS and specifying your SSL certificate and key locations. It will also involve specifying the Diffie-Hellman group, which you will use for Perfect Forward Secrecy.
あなたが再作成しようとしているので webserver
これらの追加を含めるサービスは、今すぐ停止できます。
- docker-compose stop webserver
Next, create a directory in your current project directory for the Diffie-Hellman key:
- mkdir dhparam
opensslコマンドを使用してキーを生成します。
- sudo openssl dhparam -out /home/sammy/node_project/dhparam/dhparam-2048.pem 2048
キーの生成には少し時間がかかります。
関連するDiffie-HellmanおよびSSL情報をNginx構成に追加するには、最初に、前に作成したNginx構成ファイルを削除します。
- rm nginx-conf/nginx.conf
ファイルの別のバージョンを開きます。
- nano nginx-conf/nginx.conf
次のコードをファイルに追加して、HTTPをHTTPSにリダイレクトし、SSLクレデンシャル、プロトコル、およびセキュリティヘッダーを追加します。 交換することを忘れないでください your_domain
あなた自身のドメインで:
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain www.your_domain;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location / {
try_files $uri @nodejs;
}
location @nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
#add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
}
HTTPサーバーブロックは、Certbot更新要求のWebルートを指定します。 .well-known/acme-challenge
ディレクトリ。 また、ルートディレクトリへのHTTPリクエストをHTTPSに転送するrewriteディレクティブも含まれています。
HTTPSサーバーブロックは ssl
と http2
. To read more about how HTTP/2 iterates on HTTP protocols and the benefits it can have for website performance, please read the introduction to How To Set Up Nginx with HTTP/2 Support on Ubuntu 18.04. このブロックには、最新のSSLプロトコルと暗号を使用し、OSCPステープリングがオンになっていることを確認するための一連のオプションも含まれています。 OSCPステープリングを使用すると、最初の TLSハンドシェイク中に、認証局からタイムスタンプ付きの応答を提供できます。これにより、認証プロセスを高速化できます。
このブロックは、SSLとDiffie-Hellmanの資格情報とキーの場所も指定します。
Finally, you’ve moved the proxy pass information to this block, including a location block with a try_files directive, pointing requests to your aliased Node.js application container, and a location block for that alias, which includes security headers that will enable you to get A ratings on things like the SSL Labs and Security Headers server test sites. これらのヘッダーには、 X-Frame-Options 、 X-Content-Type-Options 、 Referrer Policy 、 Content-Security-Policy 、およびX-XSS-Protection。 HTTP Strict Transport Security (HSTS)ヘッダーはコメント化されています。これは、影響を理解し、「プリロード」機能を評価した場合にのみ有効にしてください。
編集が終了したら、ファイルを保存して閉じます。
再作成する前に webserver
service, you need to add a few things to the service definition in your docker-compose.yml
HTTPSおよびDiffie-Hellmanボリューム定義に関連するポート情報を含むファイル。
ファイルを開きます。
- nano docker-compose.yml
の中に webserver
サービス定義、次のポートマッピングと dhparam
名前付きボリューム:
...
webserver:
image: nginx:latest
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- web-root:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- dhparam:/etc/ssl/certs
depends_on:
- nodejs
networks:
- app-network
次に、 dhparam
あなたへのボリューム volumes
definitions. Remember to replace the sammy
と node_project
directories to match yours:
...
volumes:
...
webroot:
...
dhparam:
driver: local
driver_opts:
type: none
device: /home/sammy/node_project/dhparam/
o: bind
と同様に web-root
ボリューム、 dhparam
ボリュームは、ホストに保存されているDiffie-Hellmanキーをマウントします。 webserver
容器。
編集が終了したら、ファイルを保存して閉じます。
を再作成します webserver
サービス:
- docker-compose up -d --force-recreate --no-deps webserver
であなたのサービスをチェックしてください docker-compose ps
:
- docker-compose ps
The following output indicates that your nodejs
と webserver
サービスが実行されています:
Output Name Command State Ports
----------------------------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
nodejs node app.js Up 8080/tcp
webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
最後に、ドメインにアクセスして、すべてが期待どおりに機能していることを確認できます。 ブラウザを次の場所に移動します https://your_domain
、必ず代用してください your_domain
あなた自身のドメイン名で:
A lock icon should appear in your browser’s security indicator. If you would like to, you can navigate to the SSL Labs Server Test landing page or the Security Headers server test landing page. The configuration options included should earn your site an A rating on the SSL Labs Server Test. In order to get an A rating on the Security Headers server test, you would have to uncomment the Strict Transport Security (HSTS) header in your nginx-conf/nginx.conf
file:
…
location @nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
…
Again, enable this option only if you understand the implications and have assessed its “preload” functionality.
ステップ6—証明書の更新
Let’s Encrypt certificates are valid for 90 days. You can set up an automated renewal process to ensure that they do not lapse. これを行う1つの方法は、 cron
スケジューリングユーティリティ。 You can schedule a cron
job using a script that will renew your certificates and reload your Nginx configuration.
と呼ばれるスクリプトを開きます ssl_renew.sh
プロジェクトディレクトリ内:
- nano ssl_renew.sh
次のコードをスクリプトに追加して、証明書を更新し、Webサーバー構成を再ロードします。
#!/bin/bash
COMPOSE="/usr/local/bin/docker-compose --ansi never"
DOCKER="/usr/bin/docker"
cd /home/sammy/node_project/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af
このスクリプトは最初に docker-compose
と呼ばれる変数のバイナリ COMPOSE
、およびを指定します --no-ansi
実行されるオプション docker-compose
ANSI制御文字のないコマンド。 次に、同じことを行います docker
バイナリ。 最後に、それはに変わります ~/node_project
ディレクトリと次を実行します docker-compose
コマンド:
docker-compose run
:これは開始しますcertbot
コンテナとオーバーライドcommand
provided in thecertbot
サービス定義。 を使用する代わりにcertonly
subcommand use therenew
subcommand, which will renew certificates that are close to expiring. Also included is the--dry-run
option to test the script.- docker-compose kill :これによりSIGHUPシグナルが
webserver
container to reload the Nginx configuration.
次に、 docker system prune を実行して、未使用のコンテナーとイメージをすべて削除します。
Close the file when you are finished editing, then make it executable:
- chmod +x ssl_renew.sh
次に、ルートを開きます crontab
指定された間隔で更新スクリプトを実行するファイル:
sudo crontab -e
このファイルを初めて編集する場合は、エディターを選択するように求められます。
no crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/ed
2. /bin/nano <---- easiest
3. /usr/bin/vim.basic
4. /usr/bin/vim.tiny
Choose 1-4 [2]:
...
At the end of the file, add the following line:
...
*/5 * * * * /home/sammy/node_project/ssl_renew.sh >> /var/log/cron.log 2>&1
This will set the job interval to every five minutes, so you can test whether your renewal request has worked as intended. You have also created a log file, cron.log
、ジョブからの関連する出力を記録します。
5分後、確認してください cron.log
to confirm whether the renewal request has succeeded:
- tail -f /var/log/cron.log
After a few moments, the following output signals a successful renewal:
Output- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates below have not been saved.)
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Killing webserver ... done
Output…
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Killing webserver ...
Killing webserver ... done
Deleted Containers:
00cad94050985261e5b377de43e314b30ad0a6a724189753a9a23ec76488fd78
Total reclaimed space: 824.5kB
Exit out by entering CTRL + C
in your terminal.
これで、 crontab
毎日の間隔を設定するファイル。 To run the script every day at noon, for example, you could modify the last line of the file like the following:
...
0 12 * * * /home/sammy/node_project/ssl_renew.sh >> /var/log/cron.log 2>&1
You can also remove the --dry-run
あなたからのオプション ssl_renew.sh
脚本:
#!/bin/bash
COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"
cd /home/sammy/node_project/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af
君の cron
ジョブは、Let’s Encrypt証明書が適格なときに更新することで、証明書が失効しないようにします。 Logrotateユーティリティを使用してログローテーションを設定し、ログファイルをローテーションおよび圧縮することもできます。
結論
コンテナを使用して、Nginxリバースプロキシを使用してNodeアプリケーションをセットアップして実行しました。 また、アプリケーションのドメインのSSL証明書を保護し、 cron
必要に応じてこれらの証明書を更新するジョブ。
If you are interested in learning more about Let’s Encrypt plugins, please review our articles on using the Nginx plugin or the standalone plugin.
You can also learn more about Docker Compose with the following resources:
- Ubuntu18.04にDockerComposeをインストールする方法。
- Ubuntu16.04でDockerおよびDockerComposeを使用して継続的インテグレーションテスト環境を構成する方法。
- Docker Composeを使用してLaravel、Nginx、およびMySQLをセットアップする方法。
構成ドキュメントは、マルチコンテナアプリケーションについてさらに学ぶための優れたリソースでもあります。