好了,到了這個階段,我們終於要進入 Docker 的世界了!前幾篇文章我們討論了系統規劃與需求,現在來到實作的部分,要為整個開發環境打好基礎。這篇文章將帶你一步步打造出一個基於 Docker 的開發環境,裡面包含了 Laravel(後端)、Nuxt(前端)、Nginx(伺服器),以及 MariaDB(資料庫)。這不僅能讓我們的開發流程更加順暢,也保證開發、測試和部署環境一致。
這次我們會用到以下目錄結構來組織專案:
→ .docker-env/
→→ api/
→→→ Dockerfile
→→ nginx/
→→→ api.conf
→→→ web.conf
→→ web/
→→→ Dockerfile
→ api/
→ web/
→ docker-compose.yml
是不是很乾脆?接下來,讓我們逐步拆解,看看如何用 Docker 來輕鬆管理這些服務!
因為觀看這篇文章的朋友們,手頭上的環境都不太相同,要列出mac、linux、windows 各Docker安裝步驟會太冗長,在麻煩自行安裝囉
首先,我們會在根目錄下建立 docker-compose.yml 檔案,這是 Docker Compose 的設定檔。它會管理我們的 Laravel、Nuxt、Nginx、MariaDB 四個服務,讓它們在同一個網路中彼此協作。以下是我們的 docker-compose.yml 設定檔:
version: '3.8'
services:
# Laravel (backend)
backend:
build:
dockerfile: ./.docker-env/api/Dockerfile
container_name: laravel-app
restart: on-failure
volumes:
- ./api:/var/www/html
environment:
- APP_ENV=local
- APP_DEBUG=true
- DB_CONNECTION=mysql
- DB_HOST=db
- DB_PORT=3306
- DB_DATABASE=finance
- DB_USERNAME=root
- DB_PASSWORD=root
command: bash -c "if [ ! -f composer.json ]; then composer create-project --prefer-dist laravel/laravel .; fi && composer install && php-fpm"
depends_on:
- db
networks:
- app-network
# Nuxt.js (frontend)
frontend:
build:
dockerfile: ./.docker-env/web/Dockerfile
container_name: nuxt-app
restart: unless-stopped
volumes:
- ./web:/app
ports:
- "3000:3000"
command: sh -c "if [ ! -f package.json ]; then npx nuxi init .; fi && npm install && npm run dev"
depends_on:
- backend
networks:
- app-network
# Nginx for serving Laravel and Nuxt
nginx:
image: nginx:alpine
container_name: nginx
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./.docker-env/nginx/api.conf:/etc/nginx/conf.d/api.conf
- ./.docker-env/nginx/web.conf:/etc/nginx/conf.d/web.conf
depends_on:
- backend
- frontend
networks:
- app-network
# MySQL (Database)
db:
image: mariadb:latest
container_name: mariadb
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: finance
MYSQL_USER: root
MYSQL_PASSWORD: root
volumes:
- "./.docker-env/.db_data/mysql:/var/lib/mysql"
networks:
- app-network
networks:
app-network:
driver: bridge
這個 docker-compose.yml 檔案會將所有的服務設定在一個橋接網路中,這樣每個服務都能輕鬆地互相通信。
現在來看看 Laravel 部分的 Dockerfile 設定。這個 Dockerfile 會幫我們設定一個 PHP 開發環境,並安裝 Laravel 所需的依賴。
# 使用 PHP 基礎映像檔
FROM php:8.2-fpm
# 安裝相關依賴套件
RUN apt-get update > /dev/null && apt-get install -y \
git \
unzip \
libjpeg-dev \
libxpm-dev \
libwebp-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
libzip-dev \
libpng-dev \
zlib1g-dev \
libicu-dev \
jpegoptim \
g++ \
libxrender1 \
libfontconfig
# 安裝 PHP zip 擴展
RUN docker-php-ext-install intl > /dev/null \
&& docker-php-ext-install zip > /dev/null \
&& docker-php-ext-install bcmath > /dev/null \
&& docker-php-ext-install pdo pdo_mysql mysqli > /dev/null
# 安裝 Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# 設置工作目錄
WORKDIR /var/www/html
# 複製專案檔案
COPY ../../api .
# 設置正確的權限
RUN chown -R www-data:www-data /var/www/html
# Expose port 9000 and start PHP-FPM server
EXPOSE 9000
CMD ["php-fpm"]
這個 Dockerfile 會幫我們把 PHP 8.2 環境以及需要的擴展安裝好,同時設定好 Composer,讓我們的 Laravel 專案可以在 Docker 裡面順利運行。
接下來是前端 Nuxt 的部分,我們會在 .docker-env/web/Dockerfile 中配置 Node.js 環境。這裡使用的是 Alpine 版本的 Node 20,它既輕量又高效,非常適合用來開發 Nuxt 應用。
# 使用 Node.js 20 映像
FROM node:20-alpine
# 設置工作目錄
WORKDIR /app
# 複製 package.json 和 package-lock.json
COPY package*.json ./
# 不在這裡安裝依賴,等待容器啟動時處理
# 複製源代碼
COPY ../../web .
# 暴露端口
EXPOSE 3000
# 開發環境會延遲到容器啟動時才執行
這個 Dockerfile 設定完後,當我們啟動容器時,它會在第一次運行時自動安裝 Nuxt 所需的依賴並啟動開發伺服器。
為了讓 Laravel 和 Nuxt 都能透過 Nginx 提供服務,我們需要設置兩個 Nginx 配置檔:api.conf 和 web.conf。這些檔案會告訴 Nginx 如何代理請求給後端 Laravel 和前端 Nuxt。
# Laravel API server
server {
listen 80;
server_name api.localhost;
index index.php index.html;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass laravel-app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
# 代理 Nuxt 請求
server {
listen 80;
server_name web.localhost;
root /usr/share/nginx/html;
index index.html;
location / {
proxy_pass http://nuxt-app:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
這樣配置完後,我們的 Nginx 會處理來自 api.localhost 和 web.localhost 的請求,並將它們分別代理到 Laravel 和 Nuxt 的容器。
現在,所有設定檔都完成了,接下來就是要讓它們跑起來!只需執行以下指令:
docker-compose up --build
當一切順利時,Laravel 和 Nuxt 都應該能透過 Nginx 正常運行。你可以透過 兩個設定好的Domain來訪問它們,後端會通過 api.localhost 提供 API,前端則會通過 web.localhost 提供頁面。
因為這兩組Domain是虛的!所以需要自行設定hosts,這樣才能看到相關的內容,並且要檢查每個服務是否能正確啟動!
到這裡,我們已經成功建立了一個基於 Docker 的開發環境,裡面包含了 Laravel、Nuxt、Nginx 和 MariaDB。這樣的架構讓我們能輕鬆管理多個服務,並保證開發環境與部署環境的一致性。接下來,讓我們進一步深入,了解 Nginx 如何作為反向代理,來協調前後端之間的溝通。
在下一篇文章《拆解 Docker 環境:快速理解 Nginx 反向代理 Nuxt 和 Laravel 的關係》中,我們將深入探討 Nginx 是如何在這個架構中,充當前端與後端的「守門員」,確保流量順暢進行。
你將會了解到: