【Docker】https-portalでSSL化しWordPressとDjangoを立ち上げてみる!

※ 当サイトではアフィリエイト広告を利用しています。リンクは広告リンクも含みます。

この記事は約13分で読めます。
広告

https-portalイメージを使うとNginxとLet’s EncryptによるSSL化ができるようです。
それを使ってWordPressとDjangoを別々のドメインでローカール環境で動かしてみました。
confファイルの設定がなくymlで全部できました。
Windows11、DockerDesktopでしか動作確認していません。VPSではやっていません。
私の誤解や間違いもあると思いますのでご了承ください。

お名前ドットコムでVPSではなくレンタルサーバー借りてるんですが、
その場合、ドメインの設定画面でSSL化できます。
VPSでは、それができないのか分かりませんが、もし同じように設定できるのであれば、
https-portalでやるSSL化と被るかもしれません。

参考:NginxをSSL付きで運用する時にhttps-portal (Docker+Let’s encrypt)がサイコーに気に入りました
私はhttps-portalではなくこちら↓の方法にしました。

広告

ネットワーク構築

https-portalといいう名前のネットワークを作る。

docker network create --driver bridge https-portal

WordPress追加

ローカール環境で任意のドメインを127.0.0.1(ローカルループバックアドレス)に設定するにはhostsファイルの編集が必要です。
こちらを参考にしてください。

WordPressの部分はクィックスタート: Compose と WordPressのWordPressのymlを使いました。
それに以下処理を追加します。
上で作ったネットワークhttps-portalに80(httpのデフォルトポート)、443(httpsのデフォルトポート)をexposeでさらします。
VIRTUAL_HOST: site-a1.com,www.site-a1.comにドメインを書きます。
しかしネットワーク上の飛ばし先は、wordpress(http://wordpress)でした。

要確認
docker container ls -aで確認するとnameはwordpress1-wordpress-1になっている
ymlでservices:でwordpress:(多分、サービス名というのかも)としているからhttp://wordpressとして動いているが、
この辺の指定の仕方はクリアにした方がいいと思った。今回使ってないけどcontainer_name:との関係とか。

wordpressディレクトリを作って
wordpress/docker-compose.yml

version: '3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     expose:
      - 80
      - 443
     restart: always
     environment:
       VIRTUAL_HOST: site-a1.com,www.site-a1.com
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:
networks:
  default:
      name: https-portal
      external: true
docker-compose up -d
でWordPressのコンテナを作ります。

次にhttps-portalのymlを書きます。
Domainsのところにドメインの行き先を書きます。
Domainsのところに>-というのがありますが
参考にさせていただいたサイトでそうなっていたので、そうしました。
参考:NginxをSSL付きで運用する時にhttps-portal (Docker+Let’s encrypt)がサイコーに気に入りました
https-portalディレクトリを作って
https-portal/docker-compose.yml

version: '3'

services:
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - '80:80'
      - '443:443'
    environment:
      DOMAINS: >-
        site-a1.com -> http://wordpress
        ,www.site-a1.com -> http://wordpress
      STAGE: 'local' # Don't use production until staging works
    volumes:
      - https-portal-data:/var/lib/https-portal
    restart: always

networks:
  default:
      name: https-portal
      external: true
volumes:
    https-portal-data: # Recommended, to avoid re-signing when upgrading HTTPS-PORTAL
docker-compose up -d
https://site-a1.com/にアクセスすると
「接続がプライベートではありません」になります。
STAGE: 'local'にしているためです。
参考:【Docker】https-portalを使ってHTTPS化 & Let’s encryptの自動化

そのまま詳細設定→site-a1.com に進む (安全ではありません)をクリックすると
WordPressが表示されます。
目次へ

Django追加

DjangoのDockerはこちらを参考にしてください。
こちらではNginxを間にいれましたが今回はなしでもできました。

Dckerfile、requiments.textに関しては上の記事を参照してください。
composeexampleフォルダなども記事の中でdjangoプロジェクトを作ったときにできたものです。


docker-compose.ymlはWordPressの時と同じように
ネットワークhttps-portalに8000ポートをさらします。
VIRTUAL_HOST: site-b.com,www.site-b.comにドメインを書きます。

version: "3.9"
services:
  web:
    build: .
    command: gunicorn composeexample.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - .:/code
    expose:
      - 8000
    environment:
      VIRTUAL_HOST: site-b.com,www.site-b.com
networks:
  default:
      name: https-portal
      external: true

DMEINSに,site-b.com -> http://web:8000 ,www.site-b.com -> http://web:8000を追加します。
https-portal/docker-compose.yml

version: '3'

services:
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - '80:80'
      - '443:443'
    environment:
      DOMAINS: >-
        site-a1.com -> http://wordpress
        ,www.site-a1.com -> http://wordpress
        ,site-b.com -> http://web:8000
        ,www.site-b.com -> http://web:8000
      STAGE: 'local' # Don't use production until staging works
    volumes:
      - https-portal-data:/var/lib/https-portal
    restart: always

networks:
  default:
      name: https-portal
      external: true
volumes:
    https-portal-data: # Recommended, to avoid re-signing when upgrading HTTPS-PORTAL
https://site-b.com/にアクセス
「接続がプライベートではありません」と出ます。
詳細設定→site-b.com に進む (安全ではありません)をクリックするとDjangoが表示されます。

STAGE:’production’でやってみた。変わらなかったし、https-portalコンテナが止まる。
ドメインがDNSに登録されていないとlet’s encryptが証明書を発行しないみたい。
独自ドメインでも何でもないただの文字列なので当然ダメでした。

Djangoのstatic

プロジェクトしか作っていなかったが、この状態からアプリを作るには
コンテナの中に入って

コンテナの中に入るにはCONTAINER IDを確認し
docker container exec -it CONTAINER ID bash

python manage.py startapp アプリ名
で作っていく。下の記事を参考にしてください。

静的ファイルの配信はwhitenoiseを使えば一応できます。
ただDjangoでは静的ファイルの出力は苦手(遅くなる)なようで、
普通、静的ファイルの配信は手前のNginxに任せるようです。

https-portalのNginxから静的ファイルの配信

ということで手前のNginxで無理やり出力してみました。
参考:https://tomato-develop.com/docker-dockercompose-python-django-postgresql-gunicorn-nginx-how-to-build-development-and-production-environment/

Djangoのsettings.pyで追加
STATIC_ROOT = os.path.join(BASE_DIR, "static")
注意、STATIC_ROOTをstaticではなくstaticfilesに集めるサンプルもよく見ますので、
staticfilesの場合は、staticの部分をstaticfilesに変えましょう。

static_volumeというvolumeを作り/code/staticとリンクさせる。
version: "3.9"
services:
  web:
    build: .
    command: gunicorn composeexample.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - .:/code
      - static_volume:/code/static
    expose:
      - 8000
    environment:
      VIRTUAL_HOST: site-b.com,www.site-b.com
networks:
  default:
      name: https-portal
      external: true
volumes:
  static_volume:
docker-compose up -d
したあと/code/staticにstaticに静的ファイルを集める。
そうするとリンクされているvolumeのstatic_volumeにも静的ファイルが入る。
docker-compose exec web python manage.py collectstatic
DockerDesktopでstatic_volumesに静的ファイルが入ってるか確認してみてください。

https-portalコンテナのcode/static/にstatic_volumeをマウントすれば静的ファイルがコピーされる。
ここでハマったんですが、volumeの名前がstatic_volumeではなくdjango1_static_volumeに変わっていました。
volumeの名前は以下で確認できます。
docker volume ls

ymlは以下になります。external: trueをつけないと別のvolumeが作られてしまうので注意です。
version: '3'

services:
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - '80:80'
      - '443:443'
    environment:
      DOMAINS: >-
        site-a1.com -> http://wordpress
        ,www.site-a1.com -> http://wordpress
        ,site-b.com -> http://web:8000
        ,www.site-b.com -> http://web:8000
      STAGE: 'local' # Don't use production until staging works
    volumes:
      - https-portal-data:/var/lib/https-portal
      - django1_static_volume:/code/static
    restart: always

networks:
  default:
      name: https-portal
      external: true
volumes:
    https-portal-data: # Recommended, to avoid re-signing when upgrading HTTPS-PORTAL
    django1_static_volume:
     external: true
docker-compose up -d
コンテナが動いた状態で
Docker Desktopでhttps-portalコンテナの/etc/nginx/conf.d/site-b.com.ssl.confとwww.site-a1.com.ssl.confの中身に以下追加します。
これによりsite-b.com/static/は、https-portalコンテナの/code/static/から配信されます。
    location /static/ {
        alias /code/static/;
    }
追加してsaveしたら
docker exec https-portal-https-portal-1 nginx -s reload
を実行すると更新されます。
コンテナを止めると追加したところが消えるので、またやる必要があります。

もっとすっきりした形にしないと実用的ではないですが、
どこがどういう役目か分かるヒントになると思います。

あとアプリを作るときstaticの下にアプリ名などを付けたディレクトリを作って、
その下に静的ファイルを置かないと、
Nginxで配信するときにみんな同じ階層に入ってしまいファイル名が同じだとバグの原因になる。
まずは2週間無料でお試し♪さくらのVPS

まとめ

使うDockerのイメージによりだいぶ設定することが変わってくる。というか省略できる。
confを全くつくらないでymlだけで完成してしまう。
しかしイメージ頼みすぎると何かあったときに対応できなくなる怖さはある。
目次へ

この記事を書いたイチゲを応援する(質問でもokです)
Vプリカでのお支払いがおすすめです。

MENTAやってます(ichige)

コメント

タイトルとURLをコピーしました