MENU
  • VPS(レンタルサーバ)比較
  • ITエンジニアの転職
  • IT技術入門(Engineers.LOG)
カテゴリー
  • IT関連 (623)
    • Bootstrap (2)
    • クラウド (4)
    • サーバー技術 (185)
    • ストレージ (7)
      • NetApp (7)
    • ネットワーク技術 (91)
      • Cisco (36)
      • Juniper (18)
      • 負荷分散装置 (17)
    • パソコン関連 (92)
      • MAC (25)
      • Windows (54)
    • プログラミング (154)
      • Ansible (11)
      • C言語 (23)
      • Python (111)
        • Django (20)
    • 仮想化 (88)
      • Docker (63)
      • VMware (23)
  • VPS (200)
    • ABLENET VPS (16)
    • Amazon Lightsail(VPS) (2)
    • ConoHaVPS (37)
    • mixhostVPS (4)
    • WebARENAIndigo (16)
    • XServerVPS (34)
    • お名前.com VPS (12)
    • さくらのVPS (24)
    • カゴヤクラウドVPS (13)
    • シンVPS (7)
  • レンタルサーバー (56)
    • エックスサーバー (38)
  • 光回線 (8)
  • 技術スキルアップ開発・学習 (7)
    • Envader (2)
    • RareTECH (2)
    • Udemy (3)
もう現役20年超えましたー。経験値ならだれにも負けないエンジニア技術ブログ
インフラエンジニアの技術LOG
  • VPS(レンタルサーバ)比較
  • ITエンジニアの転職
  • IT技術入門(Engineers.LOG)
インフラエンジニアの技術LOG
  • VPS(レンタルサーバ)比較
  • ITエンジニアの転職
  • IT技術入門(Engineers.LOG)
  1. ホーム
  2. IT関連
  3. 仮想化
  4. Docker
  5. 【Docker】Webサイトを無料でSSL(HTTPS)化する方法

【Docker】Webサイトを無料でSSL(HTTPS)化する方法

2021 11/12
Docker
2020年5月9日2021年11月12日

DockerコンテナでWebサイトを構築し、SSL(HTTPS)化する手順をまとめました。
Dockerで構築したWebサイトの構成は以下となります。

CentOS8環境(ConoHaVPS)

  • Nginx(https-portal)
  • Django
  • PostgreSQL

https-portalは、dockerで構築したWebサイトを自動でSSL化(https)にするコンテナで、Nginxと無料のSSL(Let’s Encrypt)が内包されています。

Docker上でNginx+Django+PostgreSQLの構築については以下ページを参考にしてください。

あわせて読みたい
【docker-compose】Django+PostgreSQL+Nginxを連携した構築手順(CentOS8+VPS環境) VPS+CentOS8環境下で、docker-composeを利用し、Djangoの環境構築をしましたのでまとめます。 今回の構築では「docker-compose」でDjango+PostgreSQL+Nginxを連携した設...

設計手順は以下となります。

目次
安くて高速!高性能VPSで快適開発!
最速5分でサーバー構築
>>>こちらをチェック

エンジニア必見! 技術力を伸ばすVPS徹底比較
>>>VPS比較

「Docker-compose」でNginx+Django+PostgreSQLのWebサイトを無料でSSL化する手順

今回構築するプロジェクトの構造は以下となります。

$ tree
.
|-- Dockerfile
|-- db-data
|-- docker-compose.yml
|-- manage.py
|-- mysite
|   |-- __init__.py
|   |-- __pycache__
|   |   |-- __init__.cpython-38.pyc
|   |   |-- settings.cpython-38.pyc
|   |   |-- urls.cpython-38.pyc
|   |   `-- wsgi.cpython-38.pyc
|   |-- asgi.py
|   |-- settings.py
|   |-- urls.py
|   `-- wsgi.py
|-- requirements.txt
`-- ssl_certs
    |-- account.key
    |-- dhparam.pem
    `-- engineers-life.com
        `-- production
            |-- chained.crt -> /var/lib/https-portal/example.com/production/signed.crt
            |-- domain.csr
            |-- domain.key
            `-- signed.crt

事前に必要となるファイルやディレクトリは以下となります。

  • Dockerfile
  • requirements.txt
  • docker-compose.yml

各ファイルで内のデータは以下で説明します。

Dockerfile

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir ./code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
RUN pip install django-sslserver
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
COPY . /code/

Dockerfileはpythonの最新版Dockerイメージをインストールし、requirements.txt内のイメージをコンテナ上でインストールします。

requirements.txt

Django
psycopg2
gunicorn

requirements.txtでコンテナ上でインストールするイメージとなります。

  • Django:Webフレームワーク
  • psycopg2:PythonからPostgreSQLサーバにアクセスするために必要となるイメージ
  • gunicorn:NginxでPython製WebフレームワークでできたWebアプリケーションを起動

docker-compose.yml

docker-compose.ymlで設定する内容は以下となります。

version: '3'
 
services:
  db:
    image: postgres
    ports:
            - 5432:5432
    environment:
            - POSTGRES_PASSWORD=postgres
    volumes:
            - ./db-data:/var/lib/postgresql/data
    container_name: postgres

  web:
    restart: always
    build: .
    command: bash -c "python manage.py runserver 0.0.0.0:8000 && python manage.py migrate"
    volumes:
            - .:/code
    ports:
            - 8000:8000
    depends_on:
            - db
    container_name: django

  https-portal:
    image: steveltn/https-portal:1
    ports:
            - 80:80
            - 443:443
    links:
            - web
    restart: always
    environment:
      DOMAINS: 'example.com -> http://web:8000'
      STAGE: 'production' # Don't use production until staging works
      #FORCE_RENEW: 'true'
    container_name: https-portal
    volumes:
            - ./ssl_certs:/var/lib/https-portal

volumes:
    db-data:
    ssl_certs:

上記設定はあくまで検証環境となります。
グローバルに公開する際はポート「8000番」閉じて公開するようお願いします。

service「db」

PostgreSQLのコンテナを構築します。
ポート番号は5432にアクセスします。データベースは永続化するために「db-data」へ共有します。
コンテナ名は「postgres」になります。

service「web」

DjangoWebアプリを起動します。
ポートは8000番でアクセスします。
コンテナはdbコンテナが立ち上がったことを確認した後、コンテナを起動するようにします。
コンテナ名は「django」となります。

service「https-portal」

Nginxを起動し、無料SSL(Let’s Encrypt)を自動で設定します。
80番ポートでアクセスするとリダイレクトで443へアクセスします。
80もしくは443でアクセスした場合、django(web)8000番へリダイレクトします。

「STAGE」では以下の設定をします。
インターネット上では以下の動作をします。

  • local:オレオレ証明書 アクセスできない
  • staging:オレオレ証明書 アクセスできる
  • production:証明書発行 アクセスできる

「#FORCE_RENEW: ‘true’」ここで無効化をしています。
docker-compose up/downを繰り返しているとrenewが実行され、リミットエラーが発生してしまいます。
月に5回ほどこれをしてしまうと、1週間証明書が発行できなくなり、SSL化できなくなってしまいます。

Webサイト構築後に「#」を外すようにしましょう。
これにより、定期的に証明書の更新を自動で実施してくれます。

「ssl_certs」ではコンテナボリュームの証明書と共有化してくれます。
ボリューム名は「ssl_certs」とします。

「docker-compose」でDjangoプロジェクト作成

ファイルの作成が完了したら、次に対象のフォルダ直下で以下コマンドでDjangoプロジェクトを作成します。

$ docker-compose run web django-admin startproject mysite .

※docker-composeコマンドが使えない場合はパッケージがインストールされていないので事前にインストールしておきましょう。

正常に実行されると以下のようにフォルダとファイルが作成されます。

-rw-r--r--  1 root             root  247 May  7 13:45 Dockerfile
drwx------ 19 systemd-coredump root 4096 May  8 17:18 db-data
-rw-r--r--  1 root             root  951 May  8 17:12 docker-compose.yml
-rwxr-xr-x  1 root             root  626 May  5 00:48 manage.py
drwxr-xr-x  3 root             root 4096 May  5 01:05 mysite
-rw-r--r--  1 root             root   25 May  5 00:39 requirements.txt
drwxr-xr-x  3 root             root 4096 May  8 17:16 ssl_certs

DjangoをPostgreSQLデータベースに接続

Djangoのデータベース接続をPostgreSQLに設定します。
プロジェクトディレクトリで、「mysite/settings.py」ファイルを編集します。

vi mysite/settings.py
#ALLOWED_HOSTS = []
ALLOWED_HOSTS = ["*"]
  
#DATABASES = {
#    'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
#}
  
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD' : 'postgres',
        'HOST' : 'db',
        'PORT' : 5432,
    }
}

ALLOWED_HOSTSはWebサイトへのアクセスを全て許可「*」とします。
DATABASESはPostgreSQLへのアクセスへ書き換えます。

データベース設定後、Djangoコンテナで以下コマンドで更新を実施します。

docker-compose run web python manage.py migrate

「docker-compose」でWebサイト起動とSSL自動取得・設定

docker-compose up

------中略------


django          | Django version 3.0.6, using settings 'mysite.settings'
django          | Starting development server at http://0.0.0.0:8000/
django          | Quit the server with CONTROL-C.

「docker-compose up」コマンド実行後、上記のように表示された後、少し経つとSSL証明書の発行と設定が自動で実施されます。

正常に動作すると以下のようにサービスが立ち上がり、SSL(https)でのアクセスが可能となります。

https-portal    | [services.d] starting services
https-portal    | [services.d] done.

ブラウザを立ち上げ、該当のWebサーバへアクセスすると以下のように証明書が有効となり、SSL化されていることが確認できます。

証明書も正常に設定されていることが確認できます。

「docker-compose up」後の状態

Dockerコンテナ起動後の状態は以下のようになります。

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
django_web              latest              cbfffd069c7b        47 hours ago        1.02GB
python                  3                   4f7cd4269fa9        10 days ago         934MB
postgres                latest              0f10374e5170        2 weeks ago         314MB
steveltn/https-portal   1                   fcf3e18b11ed        8 weeks ago         301MB
$ 
$ docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                                      NAMES
26a98361c225        steveltn/https-portal:1   "/init"                  17 minutes ago      Up 2 seconds        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   https-portal
42d4fc615990        django_web                "bash -c 'python man…"   17 minutes ago      Up 3 seconds        0.0.0.0:8000->8000/tcp                     django
8bb99b4ac06c        postgres                  "docker-entrypoint.s…"   17 minutes ago      Up 4 seconds        0.0.0.0:5432->5432/tcp                     postgres
$ 
$ docker volume ls
DRIVER              VOLUME NAME
local               django_db-data
local               django_ssl_certs
$ 

証明書実行時にエラーが発生した場合

上記でも簡単に説明はしましたが、今回dockerコンテナで起動した「https-portal」ですが、NginxとSSLを自動で立ち上げてくれますが、「FORCE_RENEW」を設定すると、何度か、「docker-compose」のUP/DOWNを繰り返すと、リミッターに抵触し、1週間ほど証明書が上手く設定できなくなってしまいます。

https-portal_1  | Response Code: 429
https-portal_1  | Response: {u'status': 429, u'type': u'urn:ietf:params:acme:error:rateLimited', u'detail': u'Error creating new order :: too many certificates already issued for exact set of domains: test.engineers-life.com: see https://letsencrypt.org/docs/rate-limits/'}
https-portal_1  | ================================================================================
https-portal_1  | Failed to sign test.engineers-life.com, is DNS set up properly?
https-portal_1  | ================================================================================
https-portal_1  | Failed to obtain certs for test.engineers-life.com

調べてみるとLet’s Encrypyでは証明書の更新は週5回までとなっており、それ以上更新することがNGとなっているので、ある程度構築が完了した後、「FORCE_RENEW」を設定し反映するようにしましょう。
もしくは、今回の無料SSLは3ヶ月更新のため、3ヶ月後の更新時に「FORCE_RENEW」を反映し、更新を実施します。

これ、私もハマってしまい、SSL化できなくなってしまいました。
リミットは1週間ほどで外れ、再度更新ができるようなので、ここは気をつけて運用するようにしましょう。

自動SSL化コンテナ「https-portal」の公式サイトは以下となります。
https://github.com/SteveLTN/https-portal#quick-starthttps://github.com/SteveLTN/https-portal#quick-start

以上がNginx+Django+PostgreSQL構成のWebサイトをSSL化する手順となります。

エンジニアスキルをアップする勉強法

ITエンジニアの開発・検証・学習としてインターネット上で専用のサーバ(VPS)を利用しましょう!
実務経験はVPSで学べます。

あわせて読みたい
現役エンジニアがおすすめするVPSレンタルサーバ比較(高速SSD限定) 格安VPS比較(2025年最新版)

Docker
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (6件)

  • surface0 より:
    2021年11月11日 6:35 PM

    webのコンテナに対して8000番のポートフォワードを設定する必要はないのではないでしょうか?
    せっかくリバースプロキシでHTTPS化してるのにセキュリティホールを作ってしまっているようなものだと思いますが。
    (ついでに言えば、dbも直接外部公開するのはあまり良くないと思いますが…)

    返信
    • げんき☆ひろき より:
      2021年11月11日 6:56 PM

      surface0さん
      コメント有難うございます。
      おっしゃる通りですね。

      こちらのページの設定はあくまで、当時のDjango検証用で構築したサイトのデモとなるので、参考としてお願いします。
      DBに関してもWebアプリを構築するうえで、簡易的な設定となります。

      実際商用で使用する際は、セキュリティも考慮したうえでの設計をお願いします。

      返信
      • surface0 より:
        2021年11月12日 12:50 PM

        返信ありがとうございます。

        ローカル環境で試しに、というのであれば許容するところのなのですが、
        VPSという一般公開される環境において、しかも入門記事といえど特にHTTPS導入というセキュリティ向上がテーマでの記事ですから、個人・商用問わず最低限のセキュリティには気を配った説明をお願いしたいと存じます。

        発展記事ならば尚のことで「8000番を開けておくのはもう不要です。危険なので閉じましょう」というのが入っていれば説得力があって良いかと思いました。

        このような丁寧な説明の記事ほど鵜呑みにしてしまう初学者は多いので、書いてない事についての意図が伝わりづらく難しいところだとは思いますが、なるべくご配慮いただけると幸いです。

        返信
        • げんき☆ひろき より:
          2021年11月12日 1:27 PM

          surface0さん
          ご返信ありがとうございます。

          こちら記事に追記いたしました。
          ご指摘ありがとうございます。

          今後ともよろしくお願いします。

          返信
  • k より:
    2021年11月16日 2:50 PM

    django-sslserverは本番環境には非推奨みたいですね・・・

    返信
    • げんき☆ひろき より:
      2021年11月16日 2:58 PM

      kさん
      コメントありがとうございます。

      私は一時期商用として公開していましたよー
      ただし、FWなどのセキュリティ対策はしていました。

      公式が非推奨と言っているのかは確認できませんでしたが、個人で運用するのがめんどくさいので結果的にWordpressで運用してます。

      返信

コメントする コメントをキャンセル

email confirm*

post date*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)



検索
カテゴリー
新着記事
  • XServerVPS アニメ風 男の子 プログラミングをしている VPSを利用している 楽しそうにしている
    XServerVPSで証明書(SSL)を取得する方法
    2025年3月24日
    XServerVPS
  • レンタルサーバ アニメ風 女の子 楽しんでパソコンをしている 目がキラキラ
    WordPressがレンタルサーバよりVPSで利用する方がおすすめの理由
    2025年3月19日
    VPS
  • VPS レンタルサーバー アニメ風 女の子 プログラミングをしている VPSを利用している 楽しそうにしている
    VPSとクラウドの違いとは?初心者向けにわかりやすく解説
    2025年3月5日
    VPS
  • シンVPS アニメ風 女の子 パソコン プログラミングをしている VPSを利用している 楽しそうにしている
    シンVPSはWindows serverを利用できない。その理由と利用できるOSは?
    2025年3月4日
    シンVPS
  • シンVPS アニメ風 女の子 パソコン プログラミングをしている VPSを利用している 楽しそうにしている
    シンVPSでゲームを利用する環境はあるのか
    2025年3月4日
    シンVPS
  • シンVPS アニメ風 女の子 パソコン プログラミングをしている VPSを利用している 楽しそうにしている
    シンVPSのサイトの表示速度は他社に比べて早いのか?
    2025年3月4日
    シンVPS
目次
目次