今回はフロントがVue.js、バックエンドがフレームワークなしのPHP、のローカル開発環境を構築します。
Vueはvue-cliを使用してプロジェクトを作成します。
Contents
ファイル構成
spa-projectディレクトリを本番サーバに転送する想定です。
spaの起点となるindex.htmlは、project/front-web/index.htmlになります。
vueプロジェクトをビルドするとdist ディレクトリ(/vue-project/dist)以下にビルドファイルが置かれるので、/vue-project/dist ↔︎ spa-project/project/front-web が同期されるようにdockerで設定していきます。
spa-project/
├── project //デプロイ時、サーバに置くディレクトリ
│ ├── front-web // vueのビルドファイルが置かれる
│ │ (└── index.html)
│ ├── apiとか色々
│ └──....
│
├── spa-dev //docker環境構築ディレクトリ
│ ├── app // PHPコンテナ
│ │ ├── Dockerfile
│ │ └── php.ini
│ ├── db // MySQLコンテナ
│ │ ├── Dockerfile
│ │ └── my.conf
│ ├── nginx // nginxコンテナ
│ │ ├── Dockerfile
│ │ └── default.conf
│ └── node // Nodeコンテナ
│ └── Dockerfile
└── docker-compose.yml // 全コンテナの管理
│
├── vue-project //vueのプロジェクトを置くディレクトリ
docker-compose.yml
services:
app:
build:
context: .
dockerfile: ./docker/app/Dockerfile
volumes:
- ../project/:{本番環境サーバのプロジェクトを置くパス}
node:
build:
context: .
dockerfile: ./docker/node/Dockerfile
ports:
- 8081:8081
depends_on:
- app
stdin_open: true
tty: true
volumes:
- ../vue-project:/vue-project #vue-cliで作成するプロジェクト名
- ../project/front-web/:/vue-project/dist
- node_modules_volume:/vue-project/node_modules
nginx:
build:
context: .
dockerfile: ./docker/nginx/Dockerfile
ports:
- 8080:80
depends_on:
- app
volumes:
- ../project/:{本番環境サーバのプロジェクトを置くパス}
db:
build:
context: .
dockerfile: ./docker/db/Dockerfile
ports:
- 3306:3306
environment:
MYSQL_DATABASE: ****
MYSQL_USER: ****
MYSQL_PASSWORD: ****
MYSQL_ROOT_PASSWORD: ******
TZ: "Asia/Tokyo"
volumes:
- mysql-volume:/var/lib/mysql
- ./docker/db/init_dump:/docker-entrypoint-initdb.d/
volumes:
mysql-volume:
node_modules_volume:
ポート(ブラウザを介しての接続)
nginxで8080ポートを解放し、PHPアプリケーションに接続できるようにします。APIやビルド後のvueの確認はこちらを使っていきます。(本番環境を模した感じです)
vueの開発はnpm run serve
で開発サーバを立てると思いますので、nodeで8081ポートを開けました。
vueは変更毎にいちいちビルドするのは面倒です。開発サーバだとホットリロードのような感じで変更を検知して自動的に反映してくれます。
Vue開発時は、ブラウザで8081にアクセスしてvueを表示し、vue内でAPIに接続するときは8080ポートに向かって通信しにいく感じになっています。
nodeコンテナのVolume
nodeコンテナのVueプロジェクトがローカルの/vue-projectディレクトリにマウントされます。ただし、/vue-project/distと/vue-project/node_modulesは除外されます。
/vue-project/dist
nodeコンテナの/vue-project/dist内は、Vueファイルをビルドしたファイルが置かれます。(つまり本番用ファイル) なのでnginxコンテナで表示できるようにマウント場所をproject/front-web/(SPA起点)にし、nginxで表示可能できるようにします。
/vue-project/node_modules
dockerはマウントするファイルが多いと動作がかなり重くなります。
node_modulesやcomposerのvendorなどはローカルのファイルをマウントするのではなく、dockerのコンテナ内でinstallする形にしましょう。
ttyとstdin_open
Dockerのコンテナは、実行中のプロセスが終了するまで停止せず、プロセスがアクティブである限りコンテナもアクティブです。逆にプロセスが終了した場合は停止してしまいます。
nginxなどはフォアグラウンドでプロセスを実行するようになっているのでプロセスが終了しないのですが、nodeやgoのコンテナ等は持続的にプロセスを実行するものがデフォルトでないので正常終了してしまいます。
このようなコンテナはttyを設定し、標準入出力をするものを用意してあげるとコンテナが継続されます。またstdin_openでその標準入出力とエラー出力をローカル側のdocker専用の標準入出力に接続させることができます。
参考:
https://zenn.dev/hohner/articles/43a0da20181d34
各コンテナのDockerfile
今回は各コンテナで特別な処理はしてないですが、参考までに載せておきます。
PHP Dockerfile
FROM php:7.4.27-fpm
ENV TZ Asia/Tokyo
RUN apt-get update && \
apt-get install -y git unzip libzip-dev libicu-dev libonig-dev && \
docker-php-ext-install intl pdo_mysql mysqli mbstring zip bcmath
COPY ./app/php.ini /usr/local/etc/php.ini
COPY --from=composer /usr/bin/composer /usr/bin/composer
WORKDIR {プロジェクトルート}
Mysql Dockerfile
FROM mysql:8.0.27
COPY ./db/my.conf /etc/my.conf
Nginx Dockerfile
FROM nginx:1.20.2-alpine
WORKDIR /
ENV TZ Asia/Tokyo
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
default.conf
server {
listen 80;
root {本番環境サーバのプロジェクトを置くパス};
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.html?$query_string;
}
location = /favicon.ico {
access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /404.html;
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location /api {
root {本番環境サーバのプロジェクトを置くパス}/api;
}
}
Vueプロジェクト(ビルド後)
http://localhost:8080/front-web/~
API
http://localhost:8080/api/~
Node Dockerfile
FROM node:18-alpine
WORKDIR /vue
RUN npm install -g @vue/cli
EXPOSE 81