【環境構築】Laravel × Docker × Apache かつローカルでSSL通信する

もくじ

環境

Mac
Laravel
Docker
Apache

最終的なディレクトリ構成

Test
├── LaravelApp  // 自動生成(A)
├── docker
│   ├── apache
│   │   ├── Dockerfile
│   │   ├── config
│   │   │   └── 000-default.conf
│   │   └── php.ini
│   └── ssl
│       ├── san.txt
│       ├── server.key  // 自動生成(B)
│       ├── server.csr  // 自動生成(C)
│       ├── server.crt  // 自動生成(D)
│       └── server.key.org  // 自動生成(E)
└── docker-compose.yml

Laravelをインストール(A)

  • アプリ名:LaravelApp
  • バージョン:9.x
$ composer create-project "laravel/laravel=9.*" LaravelApp

最新をインストールするなら

$ laravel new LaravelApp

ファイル作成

# PHPバージョン指定
FROM php:8.1-apache-bullseye

# composerバージョン指定
COPY --from=composer:2.4.1 /usr/bin/composer /usr/bin/composer

# apt install iputils-ping net-tools で ping を導入
RUN apt-get update \
  && apt-get install -y zlib1g-dev libzip-dev unzip vim iputils-ping net-tools sudo\
  && docker-php-ext-install zip

# node と npm をインストール
RUN apt-get install -y gnupg
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash -\
  && apt-get install -y nodejs\
  && npm install npm@8.12.1 --global

# a2emod rewrite をして apache に rewrite モジュールを追加
# これをしないと Laravel でルート以外にアクセスできない
RUN a2enmod rewrite


ADD docker/apache/php.ini /usr/local/etc/php/

# Apache の conf は seites-available に作成し
# a2ensite コマンドでシンボリックリンクを sites-enabled に作成する
ADD docker/apache/config/000-default.conf /etc/apache2/sites-available/
RUN a2ensite 000-default

WORKDIR /var/www/html

COPY ./LaravelApp /var/www/html

RUN chown www-data storage/ -R \
  && composer install\
  && npm install

# サーバ証明書ファイル・秘密鍵ファイルをコンテナ内に配置(ローカルSSL通信用)
COPY docker/ssl/server.crt /etc/ssl/certs/
COPY docker/ssl/server.key /etc/ssl/private/
RUN sed -i 's!/var/www/html!/var/www/html/public!g' /etc/apache2/sites-available/default-ssl.conf \
    && sed -i 's!/etc/ssl/certs/ssl-cert-snakeoil.pem!/etc/ssl/certs/server.crt!g' /etc/apache2/sites-available/default-ssl.conf \
    && sed -i 's!/etc/ssl/private/ssl-cert-snakeoil.key!/etc/ssl/private/server.key!g' /etc/apache2/sites-available/default-ssl.conf
RUN a2enmod ssl \
  && a2ensite default-ssl.conf
ServerName localhost:443

<VirtualHost _default_:443>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html/public
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
  ServerName localhost:443
  ServerAlias *.localhost:443
  SSLEngine on
  SSLCertificateFile "/etc/ssl/certs/server.crt"
  SSLCertificateKeyFile "/etc/ssl/private/server.key"
</VirtualHost>
[Date]
date.timezone = "Asia/Tokyo"

[mbstring]
mbstring.language = "Japanese"
subjectAltName = DNS:localhost
version: '3'

services:
  apache:
    container_name: apache
    build:
      context: .
      dockerfile: ./docker/apache/Dockerfile
    ports:
      - 443:443
    environment:
      - TZ=Asia/Tokyo
      - APACHE_DOCUMENT_ROOT=/var/www/html/public
      - APP_DOMAIN=localhost
    volumes:
      - ./LaravelApp:/var/www/html
      - ./docker/apache/php.ini:/usr/local/etc/php/php.ini
      - ./docker/ssl/server.crt:/etc/ssl/certs/server.crt
    networks:
      - net1
networks:
  net1:

自己署名証明書を準備

ローカルでSSL通信するために、ローカルであっても証明書を作成する必要があります。

パスワードは任意でok

1. server.key(秘密鍵)の作成(B)

sslディレクトリに移動しておく

$ cd docker/ssl/
$ openssl genrsa -aes128 2048 > server.key

2. server.csr(公開鍵+認証局での署名に必要な情報)の作成(C)

$ openssl req -new -key server.key > server.csr
  • Country NameJP
  • Common Name:任意(localhost など)
  • 他はブランクでOK

3. server.crt(サーバ証明書)の作成(D)

$ openssl x509 -in server.csr -days 365 -req -signkey server.key > server.crt -extfile san.txt

4. パスフレーズを削除(E)

$ mv server.key server.key.org
$ openssl rsa -in server.key.org > server.key

5. 証明書を「常に信頼する」

  1. server.crtをダブルクリックで開く(キーチェーンアクセス.app)
  2. システム > 証明書 > 作成した証明書の行をダブルクリック
  3. 信頼を開いて「常に信頼する」を選択

6. Chrome 再起動

Docker

ビルドして起動

$ docker-compose up -d --build

https://localhost/ にアクセスしてちゃんと鍵マークになってれば完了!

うまくいかないときは停止して再構築

$ docker-compose down --rmi all --volumes --remove-orphans
$ docker-compose up -d --build

ログを確認してデバッグもしてみてください。

$ docker ps -a
$ docker logs コンテナID

さいごに

Laravel × Docker × nginx は結構記事を見つけたんですが、Apacheを使った参考が少なかったのでまとめてみました。 自分も時間かかった身なので、誰かの助けになれば幸いです。

参考URL

Docker + Apache + Laravel で Web アプリケーションつくる - kita127のブログ

Laravel開発環境をDockerを使ってサクッと構築する【最小限のコード】|Webエンジニア研究室

【Apache】ローカルに立てたDockerコンテナでHTTPS通信する方法|Webエンジニア研究室

SAN(Subject Alternative Name) のオレオレ証明書 - Qiita

Docker php-apacheを自己証明書でSSL対応(自分メモ) - Qiita

Docker × Laravel ローカル環境でHTTPS(SSL)通信する - Qiita