Contents
Dockerで始めるセキュアな開発環境:HTTPS/SSL設定
Docker環境でのSSL接続設定について詳しく解説します。
HTTPSとSSL/TLSの関係って?
- HTTPS(Hypertext Transfer Protocol Secure)は、Webブラウザとサーバー間の通信を安全に行うためのプロトコルです。
- SSL/TLSは、HTTPSの中で使われている暗号化技術です(SSLは古い呼び方で、現在はTLSが主流です)。
Dockerを使用した開発環境でも、SSL接続を適切に設定することで、より本番環境に近い安全な環境を構築できます。
➡️ 本番環境との一貫性
まずはdocker-compose.ymlで設定
まずdocker-compose.ymlでポート443のマッピングを設定
services:
app:
ports:
- "0.0.0.0:8080:80"
- "443:443"
SSL証明書設定
SSL証明書設定には主に3つの選択肢
自己署名証明書を使用する場合
https://localhostとしてブラウザで確認すると警告がでます
警告ページで「詳細」や「続行」などのオプションを探します。 リスクを理解した上で、「Webサイトへ進む」などのオプションを選択します。 ブラウザは警告を表示しつつも、ページの表示を許可します。
注意点:この方法は開発環境でのみ推奨されます。
この設定により、ホストマシンのポート443がDockerコンテナ内のポート443にマッピングされます。これにより、外部からのHTTPS接続(ポート443)をコンテナ内のApacheサーバーで受け付けることができます。
Dockerfileでの設定
次に、Dockerfileで以下のようなSSL関連の設定を行います:
1)SSLモジュールの有効化:
RUN a2enmod ssl
2)デフォルトのSSLサイト設定の有効化:
RUN a2ensite default-ssl
3)自己署名SSL証明書の生成:
RUN echo '#!/bin/bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/apache-selfsigned.key \
-out /etc/ssl/certs/apache-selfsigned.crt \
-subj "/CN=localhost"
sed -i "s|SSLCertificateFile.*|SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt|" /etc/apache2/sites-available/default-ssl.conf
sed -i "s|SSLCertificateKeyFile.*|SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key|" /etc/apache2/sites-available/default-ssl.conf' > /usr/local/bin/generate_ssl_cert.sh
RUN chmod +x /usr/local/bin/generate_ssl_cert.sh && /usr/local/bin/generate_ssl_cert.sh
DockerfileのRUN
コマンドがデフォルトでroot権限で実行されるため、追加の権限設定なしでopenssl
コマンドを実行できます。複雑な権限設定なしで、システムレベルの操作を容易に行えます。
openssl
コマンドを使用して自己署名証明書を生成しています。-x509
:自己署名証明書を生成することを指定します。-nodes
:秘密鍵をパスワードで保護しないことを指定します。-days 365
:証明書の有効期間を1年に設定します。-newkey rsa:2048
:2048ビットのRSA鍵を新しく生成します。-keyout
と-out
:鍵と証明書の出力先を指定します。-subj "/CN=localhost"
:証明書のサブジェクト(ここではCommon Name)を設定します。…証明書が保護するドメイン名または IP アドレスを指定します
- sed は “stream editor” の略で、テキストの変換や置換に使用
- 置換パターン:
s|旧パターン|新パターン|
の形式で、|
はデリミタ(区切り文字)として機能
- 置換パターン:
4)ポート443の公開:
EXPOSE 80 443
Let’s Encryptは開発環境では難しい

Let’s Encryptが開発環境で難しい主な理由は:
- ドメイン名が必要
- localhostでは使えない
- IPアドレスでも使えない
- 外部からのアクセスが必要
- 証明書発行時に外部からの認証が必要
- ローカル環境では実現が難しい
- 更新の手間
- 90日ごとに更新が必要
- 開発環境では更新管理が面倒
ローカルDocker開発環境では難しい、、、?
mkcertを使用したSSL接続の設定
mkcertを使用することで、自己署名証明書の警告なしに安全な開発環境を構築できます。
Chocolateyがインストールされていない場合は、まずChocolateyをインストール
Chocolateyは、Windowsのためのパッケージマネージャーです。
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))


Chocolatey現在のインストール状態を確認してみましょう
cd ~
PS C:\Users\ida-t> choco --version
choco : 用語 'choco' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。
名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいこと
を確認してから、再試行してください。
// chocoコマンドは認識されない(PATHが通っていない)
\Users\name\AppData\Local> ls
..
d----- 2024/09/13 9:48 mkcert
..
// AppData\Localにmkcertフォルダがある
// chocolateyフォルダは見当たらない
管理者権限が必要
事前準備
chocolatey(チョコレーティー)の状態:
C:\Windows配下に複数のchocolateyInstall.ps1が残存(2019年と2024年のタイムスタンプ)
本来のインストール場所(C:\ProgramData\chocolateyまたはAppData\Local\chocolatey)にはない
コマンド(choco)は認識されない
→ 完全にインストールされていない、かつ古い痕跡が残っている状態
mkcert(エムケイサート)の状態:
C:\Users\[ユーザー名]\AppData\Local\mkcertフォルダが存在
コマンド(mkcert)は認識されない可能性が高い
→ 不完全なインストール状態
パスが通るとは
AppDataフォルダとは
ユーザーごとの設定を保存する隠しフォルダ
C:\Users\名前\AppData\Localにある
一般権限でインストールすると、ここに入ってしまう
既存の不完全なmkcertのアンインストール
場所:C:\Users[ユーザー名]\AppData\Local\mkcertの削除
依頼タイトル:
開発環境のHTTPS化に必要なツール(Chocolatey、mkcert)の管理者権限インストール依頼
依頼理由:
ローカル開発環境でのHTTPS通信テストが必要
現状、HTTPSの証明書管理ツール(mkcert)が中途半端にインストールされている状態
必要な作業:
パッケージマネージャー(Chocolatey)の管理者権限でのインストール
インストール先:C:\ProgramData\chocolatey
理由:システム環境変数の設定が必要なため
mkcertの管理者権限でのインストール
コマンド:choco install mkcert
理由:ローカル認証局の設定に管理者権限が必要なため
期待される結果:
開発環境でのHTTPS通信のテストが可能になる
証明書の警告なしでローカル開発が行える
一般権限でパスを通す場合もしくはパスを通さずにしようすると、、(非推奨?)
mkcertの場合は残念ながら管理者権限が必須です。理由は:
- 証明書の信頼設定にシステムレベルのアクセスが必要
- ブラウザに信頼させるには管理者権限が必要
- ローカル認証局の作成に管理者権限が必要
そのため、パスを通すだけや、フルパスでの実行だけでは目的を達成できません。HTTPSの警告なし開発環境を作るには、管理者権限でのインストールが必要になります。
Chocolateyは一般権限でも一部機能は使える
しかし、mkcertのような管理者権限が必要なツールはインストールできても正常に動作しない
mkcert「エムケイサート」のインストールと使用
Windows PowerShell”を右クリックし、“管理者として実行”を選択します。
mkcertをインストール:
choco install mkcert
インストールの確認
mkcert --version
ローカル認証局のインストール
mkcert -install
インストールの確認
mkcert -CAROOT
証明書の生成
プロジェクトディレクトリに移動し、以下のコマンドを実行:
mkdir certs
cd certs
mkcert localhost 127.0.0.1 ::1
→ファイル生成
・証明書ファイル: [最初のドメイン名]+[追加エントリ数].pem
(公開鍵を含む)
・秘密鍵ファイル: [最初のドメイン名]+[追加エントリ数]-key.pem
各ファイルを編集
鍵ファイルを作成したら下記を実施します
- Apache設定ファイルでは、SSLエンジンを有効にし、証明書と秘密鍵のパスを正しく指定しています。
- Dockerfileでは、Apacheの SSL モジュールを有効化しています。
- docker-compose.ymlでは、443ポートをホストにマッピングし、必要なボリュームをマウントしています。
project_root/
│
├── local-mysite/
│ ├── certs/
│ │ ├── localhost+2.pem
│ │ └── localhost+2-key.pem
│ ├── env_vars/
│ │ └── localhost
│ ├── sites-available/
│ │ └── 000-default.conf
│ ├── .htaccess
│ ├── docker-compose.yml
│ ├── Dockerfile
│ ├── php.ini
│ └── ssl_cert_gen.sh
│
└── mysite/
└── (PHPアプリケーションファイル)
▼docker-compose.yml
version: "3.4"
services:
app:
# Dockerfileからイメージをビルド
build:
context: .
dockerfile: Dockerfile
# ボリュームマウントの設定
volumes:
# 環境変数ファイルをマウント
- ./env_vars:/var/www/env_vars
# PHPアプリケーションのソースコードをマウント
- ../0824_mysite:/var/www/html
# SSL証明書をマウント(読み取り専用)
- ./certs/localhost+2.pem:/etc/ssl/certs/localhost+2.pem:ro
# SSL秘密鍵をマウント(読み取り専用)
- ./certs/localhost+2-key.pem:/etc/ssl/private/localhost+2-key.pem:ro
# Apache設定ファイルをマウント
- ./sites-available:/etc/apache2/sites-available
# ポートマッピングの設定
ports:
# HTTP: ホストの8082ポートをコンテナの80ポートにマッピング
- "0.0.0.0:8082:80"
# HTTPS: ホストの443ポートをコンテナの443ポートにマッピング
- "443:443"
# 環境変数の設定(必要に応じて追加)
environment:
- APACHE_DOCUMENT_ROOT=/var/www/html
▼Dockerfile
# SSL対応PHP開発環境のDockerfile
# PHP 8.1とApacheをベースとした公式イメージを使用
FROM php:8.1-apache
# カスタムApache設定ファイルをコンテナ内の指定された場所にコピー
COPY ./sites-available/000-default.conf /etc/apache2/sites-available/000-default.conf
# PDO_MySQL拡張をインストールし、Apacheのrewrite、proxy、proxy_httpモジュールを有効化
RUN docker-php-ext-install pdo_mysql && a2enmod rewrite proxy proxy_http
# SSLモジュールを有効化
RUN a2enmod ssl
# デフォルトのSSLサイト設定を有効化
RUN a2ensite default-ssl
# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y \
curl \
gnupg \
git \
unzip \
openssl \
# Node.jsのセットアップスクリプトを取得して実行
&& curl -sL https://deb.nodesource.com/setup_18.x | bash - \
# Node.jsをインストール
&& apt-get install -y nodejs \
# パッケージリストを削除してイメージサイズを削減
&& rm -rf /var/lib/apt/lists/*
# Composerをコンテナ内にコピー
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# コンテナ内の作業ディレクトリを設定
WORKDIR /var/www/html
# Composerの設定
ENV COMPOSER_HOME /var/www/.composer
RUN mkdir -p $COMPOSER_HOME && chown -R www-data:www-data $COMPOSER_HOME
# Apache実行ユーザーの設定
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
# Apacheの設定を変更し、.htaccessが機能するようにAllowOverrideをAllに設定
RUN sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
# コンテナのポート80(HTTP)と443(HTTPS)を公開
EXPOSE 80 443
# .htaccessファイルをコンテナ内にコピー
COPY .htaccess /var/www/html/.htaccess
# .htaccessファイルの所有権と権限を設定
RUN chown www-data:www-data /var/www/html/.htaccess && chmod 644 /var/www/html/.htaccess
# カスタムphp.iniをコンテナ内にコピー
COPY ./php.ini /usr/local/etc/php/php.ini
# PHPエラーログファイルを作成し、適切な権限を設定
RUN touch /var/log/php_errors.log && chmod 666 /var/log/php_errors.log
# mkcertで生成した証明書をコンテナ内にコピー
COPY ./certs/localhost+2.pem /etc/ssl/certs/localhost.crt
COPY ./certs/localhost+2-key.pem /etc/ssl/private/localhost.key
# 証明書のパーミッションを適切に設定
RUN chmod 644 /etc/ssl/certs/localhost.crt && \
chmod 600 /etc/ssl/private/localhost.key
# Apacheをフォアグラウンドで実行
CMD ["apache2-foreground"]
▼000-default.conf
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html
Redirect permanent / https://localhost/
# HTTPのアクセスログとエラーログ(必要に応じてコメントを外す)
# ErrorLog ${APACHE_LOG_DIR}/error.log
# CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
<VirtualHost *:443>
ServerName localhost
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/ssl/certs/localhost+2.pem
SSLCertificateKeyFile /etc/ssl/private/localhost+2-key.pem
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```
この設定は、HTTPからHTTPSへのリダイレクトと、SSL/TLS接続の基本的な設定を提供します。
mkcertとopenssl、Let’s Encryptを使用したSSL設定の比較
mkcertとopenssl、Let’s Encryptを使用したSSL設定の主な違いは、使いやすさと生成される証明書の性質にあります。
mkcertは開発環境に特化しており、簡単な操作で信頼されたSSL証明書を生成できます。一方、opensslはより汎用的で、詳細な設定が可能ですが、使用にはより深い知識が必要です。
開発環境では、mkcertの使用が推奨されます:
- セットアップが簡単で、チーム全体で一貫した環境を構築しやすい。
- ブラウザ警告がなく、よりスムーズなテストが可能。
- 開発者が証明書の詳細な管理に時間を割く必要がない。
一方、以下の場合はopensslの使用が適切です:
- 本番環境用の証明書生成。
- カスタムな証明書要件がある場合。
- 証明書生成プロセスの詳細な制御が必要な場合。
重要なポイントは、開発環境と本番環境で異なるアプローチを取ることが多いということです。開発ではmkcertの簡便性を活かし、本番ではopensslやLet’s Encryptなどを使用して、より厳格なセキュリティを確保することが一般的です。
セキュリティの考慮事項
開発環境でのmkcert使用
利点:
- 簡単にローカルでHTTPS環境を構築できる
- 開発者の生産性向上
- 本番環境に近い条件でのテストが可能
制限:
- ローカルマシンでのみ信頼される証明書
- 公的に認証された証明書ではない
mkcertはローカル環境に最適化されているため、本番環境特有の問題を見逃す可能性がある
一般的な本番環境要件:
- 信頼された認証局(CA)による証明書の使用
- 強力な暗号化アルゴリズムの採用
- 定期的な証明書の更新
- 適切なサーバー設定(TLSバージョン、暗号スイートなど)