こんにちは、無資格・無免許エンジニアの三木です。
前回こちらで
何もわからない状態から開発を始めて
「できあがりはこちらです」と3分クッキングのような記事を書かせて頂いたのですが
ここから順番に、どのように環境を用意していったかを記事にしたいと思います
本記事はdocker-composeの設定+Laravelのインストールののち、localhost接続でLaravelのページが表示されるまでを書かせて頂きます。
開発マシンの前提
WindowsでもMacでも良いのですが
Windowsの場合はWSL2+Ubuntuが起動する状態になっていて
Windows → ターミナルソフトなどでUbuntu上から、ルートディレクトリ以下の操作が出来る
Mac → ターミナルからルートディレクトリ以下の操作が出来る
という状態を前提として考えています。
Docker DesktopによるDockerコンテナの立ち上げ
Webのシステムを開発するにはweb(http)やdatabaseなどの複数のサーバーが必要になります
これらを物理的に1台づつ用意して…ということをやっているケースはもうあまりなく
DockerやVirtualBoxなどの仮想環境でPC上に構築することが多いです
必要なサーバーごとにDocker環境を一つづつ立ち上げるということも可能ですが
複数あったときにまとめて起動・停止が出来れば便利です
これを可能にするDocker-ComposeをWindows/Macのアプリケーションとして利用できるのがDocker Desktopとなります。
ポータルはDocker Desktopを利用してローカルホスト内に下記を作成し、そこで開発をおこなっています
- ネットワークブリッジ
- Webコンテナ
- DBコンテナ
- Redisコンテナ
まずはこのDockerコンテナの環境を作成していくのですが
Ubuntu/Macのターミナルで作業したい空のディレクトリに入り
下記のコマンドで何かしらバージョンが表示される状態になっていれば作成を開始できます
$ docker-compose -v
Docker Compose version v2.31.0-desktop.2
ここからコンテナ設定を作成し、起動させていきます。
設定ファイルの配置と作成
ファイルは下記のように配置しました
└── root/
├── docker/
│ ├── db/
│ │ └── my.cnf
│ └── web/
│ ├── apache-virtualhost.conf
│ ├── Dockerfile
│ └── server.sh
├── portal-app/
│ └── ※ここは空
└── docker-compose.yml
一旦1ファイルづつ説明していきます。
各ファイル・設定は表題のアプリを開発するにあたってこのように用意した…
という一例なので、利用したいコンテナなどによって全然違う構成になると思います。
docker-compose.yml
Docker-Composeの設定ファイルです。
ここに記載している内容を元にコンテナをビルド・起動・停止します。
下記のファイルではweb/db/redisのサーバーをローカルのネットワークブリッジに立ち上げるための設定です。
###########################
# ローカル開発環境
services:
###########################
# portal_web / webサーバー
# このブロック1つがサーバー(コンテナ)1つを表す
portal_web:
container_name: portal_web # コンテナ名、ブリッジ内で名前引きするので大事
build: docker/web # ビルド時にDockerfileを参照する場合に指定
environment:
- APP_TIMEOUT=60
- PHP_MEMORY_LIMIT=256M
- PHP_MAX_UPLOAD=20M
working_dir: /var/www/html/portal-app # コンテナにログインした際の初期ディレクトリ
ports:
- "9190:80" # localhost:9190への接続をこのサーバーの80ポートにフォワーディング
- "5173:5173" # localhost:5173への接続をこのサーバーの5173ポートにフォワーディング
networks:
- portal_local # 使用するネットワークブリッジ、設定は末尾
volumes:
- ./:/var/www/html # このディレクトリをコンテナ内/var/www/html以下にマッピングする
###########################
# portal_db : mysql 8.4.3
# DBサーバー
portal_db:
container_name: portal_db
image: mysql:8.4.3 # webと異なり、imageから直接作成
#ports:
# - 3306:3306 # もしブリッジ外からDBへ接続したいなら設定が必要
environment: # 立ち上がるDBのDB名やuser名、ローカルは適当で大丈夫
MYSQL_DATABASE: portal
MYSQL_USER: portal
MYSQL_PASSWORD: portal
MYSQL_ROOT_PASSWORD: portal
TZ: 'Asia/Tokyo'
networks:
- portal_local # 使用するネットワークブリッジ、設定は末尾
volumes:
- portal_db_volume:/var/lib/mysql # 永続化のため名前付きボリュームを利用、設定は末尾
- ./docker/db/conf.d:/etc/mysql/conf.d # 起動時の文字コード設定変更のため、参照confを変更
###########################
# portal__redis : Redis 7.4.1
# Redisサーバー
portal_redis:
container_name: portal_redis
image: redis:7.4.1 # webと異なり、imageから直接作成
#ports:
# - "6379:6379" # もしブリッジ外からRedisへ接続したいなら設定が必要
volumes:
- portal_redis_volume:/data # 永続化のため名前付きボリュームを利用、設定は末尾
networks:
- portal_local # 使用するネットワークブリッジ、設定は末尾
networks: # コンテナを立ち上げるネットワークブリッジの設定
portal_local:
name: portal_local
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: 192.168.200.0/24 # 一応クラスCのプライベート範囲を設定しています
volumes: # DBやRedisのデータ永続化のために利用する名前つきボリューム
portal_db_volume:
driver: local
portal_redis_volume:
driver: local
Dockerfile(docker/web/Dockerfile)
Webサーバー(portal_web)のビルド時に利用されるコンテナの設定ファイルです。
コンテナのビルド時にのみ、上から順にRUNやCOPYで指定したコマンドが実行されていきます。
# DBやRedisと同様に元となるコンテナイメージを指定
FROM php:8.4.2-apache-bookworm
# 使う予定のPHP拡張などをインストール
RUN apt-get update \
&& apt-get install -y libzip-dev unzip \
&& docker-php-ext-install zip pdo mysqli pdo_mysql \
&& docker-php-ext-install opcache \
&& yes '' | pecl install redis
# Laravel他のインストールなどを管理するcomposerをインストール
RUN curl https://getcomposer.org/download/2.8.4/composer.phar -o /usr/local/bin/composer -s \
&& chmod 755 /usr/local/bin/composer
# npmコマンドやnode.jsを利用するためnodeをインストール
RUN curl -sL https://deb.nodesource.com/setup_22.x | bash -\
&& apt-get install -y nodejs
# コンテナ上でgitコマンドを利用したいためgitをインストール
RUN apt-get update && \
apt-get install -y git
RUN git config --global --add safe.directory /var/www/html
# apacheの設定ファイルを上書きする
COPY apache-virtualhost.conf /etc/apache2/sites-enabled/000-default.conf
# apache起動のためのシェルをコピーし、実行できる権限にする
COPY server.sh /usr/local/bin/server.sh
RUN chmod 755 /usr/local/bin/server.sh
# 起動後にシェルを実行する
ENTRYPOINT ["/usr/local/bin/server.sh"]
server.sh(docker/web/server.sh)
Dockerfileの末尾で指定した起動後に実施するシェル
apacheの実行ユーザーを追加して、apacheを起動
(このため、コンテナが起動した後に、apacheでhttpの接続を待ち受ける状態になる)
#!/bin/sh
# get current user setting.
USER=`grep apache /etc/passwd`
# set user if user is not exist.
if [ -z "$USER" ] && [ ! -z "$APACHE_UID" ]; then
useradd -u $APACHE_UID apache
mkdir -m 755 /home/apache
chown apache /home/apache
export APACHE_RUN_USER=apache
fi
# start apache.
apache2-foreground
wait
apache-virtualhost.conf(docker/web/apache-virtualhost.conf)
Dockerfileの最後の方で上書きしているapacheの設定ファイル
この後Laravelをインストールした後に、80番ポートへの接続を/var/www/html/portal-app/public
へマッピングしたいために用意
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/portal-app/public
DirectoryIndex index.php
<Directory /var/www/html/portal-app>
Options FollowSymLinks
Options -Indexes
AllowOverride All
# set allow IP address.
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
my.cnf(docker/db/conf.d/my.cnf)
docker-compose.ymlの設定でビルド時にコピーを実施
そのままDBを起動してしまうと文字コード設定が一部latin1などになってしまうので設定
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[client]
default-character-set=utf8mb4
ポートマッピングについて
以上の設定ファイルでWeb/DB/Redisのサーバーを立ち上げることができます。
ただしそれだけでは、全てのコンテナが一つのネットワークブリッジ上に立ち上がるため
サーバー間の通信は可能ですが、ブリッジの外からWebサーバーへアクセスすることができず、開発中の画面を確認することができません。
このためdocker-compose.yml
のファイルに
ports:
- "9190:80" # localhost:9190への接続をこのサーバーの80ポートにフォワーディング
- "5173:5173" # localhost:5173への接続をこのサーバーの5173ポートにフォワーディング
の設定を追加して、開発中の環境にアクセスできるようにしています。
コンテナの起動と確認
コンテナのビルド方法
docker-compose.yml
のあるディレクトリで
$ docker compose build
でコンテナのイメージが作成されます。
もし途中Dockerfile
を編集した場合はimageの更新が必要なため、上記の再実行が必要です。
また、ビルドにはキャッシュが利用されるのですが
意図しないキャッシュ利用が発生している場合などは下記コマンドでキャッシュなしビルドが可能です。
$ docker compose build --no-cache
コンテナの起動方法
作成したコンテナイメージの起動は下記のコマンドで出来ます
$ docker compose up -d
また、立ち上がっているコンテナは下記のコマンドで確認可能です
$ docker-compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
portal_db mysql:8.4.3 "docker-entrypoint.s…" portal_db 45 minutes ago Up 45 minutes 3306/tcp, 33060/tcp
portal_redis redis:7.4.1 "docker-entrypoint.s…" portal_redis 45 minutes ago Up 45 minutes 6379/tcp
portal_web no02-portal_web "/usr/local/bin/serv…" portal_web 45 minutes ago Up 45 minutes 0.0.0.0:5173->5173/tcp, 0.0.0.0:9190->80/tcp
もしSTATUS
= UP
となっていない場合はどこかで失敗しています
-d
オプションを外すことで
各コンテナのログ出力から問題を特定することが出来るかもしれません
$ docker-compose up
[+] Running 4/4
✔ Network portal_local Created 0.1s
✔ Container portal_web Created 0.1s
✔ Container portal_db Created 0.1s
✔ Container portal_redis Created 0.1s
Attaching to portal_db, portal_redis, portal_web
portal_redis | 1:C 24 Dec 2024 07:53:02.717 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
portal_redis | 1:C 24 Dec 2024 07:53:02.717 * Redis version=7.4.1, bits=64, commit=00000000, modified=0, pid=1, just started
…
webサーバーコンテナへのシェルログイン
作成したWebコンテナへのログインは以下のコマンドで出来ます
ログイン先はdocker-compose.yml
で指定したcontainer_name
の値を指定します
$ docker exec -it portal_web bash
root@5121f2f7b75d:/var/www/html/portal-app# (以降の入力はwebコンテナのbashに)
コンテナから抜けるときは下記となります
root@5121f2f7b75d:/var/www/html/portal-app# exit
$ (元のターミナルに戻ってくる)
dbサーバーのシェルログイン
作成したDBコンテナのログインは以下のコマンドで出来ます
DBはenvironment
の設定によりビルド完了時にデータベースの作成まで完了しています。
試しにmysqlにログインし、database一覧を表示するなら下記のようになります
mysqlのユーザー名・パスワードやデータベース名などはdocker-compose.yml
で設定したenviroment
の値を利用します
$ docker exec -it portal_db bash
bash-5.1# mysql -uportal -pportal <---- 警告を嫌うなら[mysql -uportal -p]として後入力に
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.4.3 MySQL Community Server - GPL
Copyright (c) 2000, 2024, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
| portal | <---- environmentで指定したDBが出来上がっている
+--------------------+
3 rows in set (0.00 sec)
mysql> exit <---- mysqlから抜ける
Bye
bash-5.1# exit <---- DBコンテナから抜ける
exit
redisサーバーのシェルログイン
作成したReidsコンテナのログインは以下のコマンドで出来ます
redis-cli
を起動し、登録されているKeyを調べるなら以下のようになります。
$ docker exec -it portal_redis bash
root@36bde9c8d794:/data# redis-cli <--- redis-cliを起動
127.0.0.1:6379> KEYS * <--- キー一覧を表示、立上げ直後は何もない
(empty array)
コンテナの停止方法
docker-compose.yml
のあるディレクトリで下記のコマンドで停止できます
$ docker-compose down
[+] Running 4/4
✔ Container portal_web Removed
✔ Container portal_db Removed
✔ Container portal_redis Removed
✔ Network portal_local Removed
$
ここまで問題なく動作すれば
- 開発で利用するサーバーが自分のマシン内に用意出来ている
- 各マシンにログインして現在の状況を確認する手法が整っている
といえると思います。
Laravelのインストール
WebコンテナにログインしてComposer経由でLaravelをインストールします
$ docker exec -it portal_web bash
root@8930d5732a83:/var/www/html/portal-app# composer create-project laravel/laravel .
また、Redisへの接続にpredisを利用するためcomposerからpredisのインストールも実施
root@8930d5732a83:/var/www/html/portal-app# composer require --dev predis/predis
これでportal-appディレクトリ以下にLaravelフレームワークがインストールされます
余計なmigrationなども動作してしまいますが、一旦このままで
rootユーザーでコンテナに接続してしまっているので所有権限を変更し
本来はインストールや操作するユーザーを気を遣うところですが、ローカル環境…ということでログやキャッシュの出力先のアクセス権を緩くしておきます
root@8930d5732a83:/var/www/html/portal-app# chown -R 1000:1000 .
root@8930d5732a83:/var/www/html/portal-app# chmod 777 -R storage
portal-app
ディレクトリ直下に.env
という環境パラメータを設定するファイルが出来上がっているはずなので
以下を参考に立ち上げたコンテナのcontainer-name
などを設定します
※同一ブリッジ内のため、Webから見てcontainer-nameで通信が出来る状態になっています
APP_NAME=portal <-- 一応アプリ名に変更
APP_ENV=local
APP_KEY=base64:NTRRUl0n24WXDHmdyEnJ9bvEvoFToGDDlD1Ox3+C4fk=
APP_DEBUG=true
APP_TIMEZONE=Asia/Tokyo <-- JSTに変更
APP_URL=http://localhost:9190 <-- 9190にマッピングしたので変更
APP_LOCALE=ja <-- 言語を変更
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=ja_JP <-- Fakerの言語を変更
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
PHP_CLI_SERVER_WORKERS=4
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql <-- mysqlへ変更
DB_HOST=portal_db <-- DBコンテナへ変更
DB_PORT=3306
DB_DATABASE=portal <-- docker-compose.ymlで設定したユーザー名などに変更
DB_USERNAME=portal <-- 同上
DB_PASSWORD=portal <-- 同上
SESSION_DRIVER=redis <-- redisへ変更
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=redis
CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=predis <-- predisへ変更
REDIS_HOST=portal_redis <-- Redisコンテナ名へ変更
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=log
MAIL_SCHEME=null
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}"
記事作成時点のLaravel最新バージョンで上記作成していますが、見覚えのないパラメータも増えていました。
実行いただくタイミングによっては用意される.env
は上記と異なるものになると思います。
念のためここでmigrateを実行してみて、DBへの接続が問題ないか確認します
root@8930d5732a83:/var/www/html/portal-app# php artisan migrate
INFO Preparing database.
Creating migration table ...... 22.88ms DONE
INFO Running migrations.
0001_01_01_000000_create_users_table ...... 87.43ms DONE
0001_01_01_000001_create_cache_table ...... 35.44ms DONE
0001_01_01_000002_create_jobs_table ...... 65.95ms DONE
php artisan migrate
を実行した後に、DBコンテナで上記コマンドが作成したであろうテーブルが確認できれば問題ありません
今回はusers
などが相当します
$ docker exec -it portal_db bash
bash-5.1# mysql -uportal -p
(input password ...)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use portal;
Database changed
mysql> show tables;
+-----------------------+
| Tables_in_portal |
+-----------------------+
| cache |
| cache_locks |
| failed_jobs |
| job_batches |
| jobs |
| migrations |
| password_reset_tokens |
| sessions |
| users |
+-----------------------+
9 rows in set (0.01 sec)
接続確認
ここまで問題がなければ
PCからブラウザでhttp://localhost:9190/
へアクセスすると
上記のようにLaravelのインストール直後の画面が表示されると思います。
ここからLaravel上での開発を進めていける状態となります。
次はPHP実装やReact実装…ではなくterraformの記事を作成していこうと思います。
読んでいただきありがとうございました。