D5 - 拆解 Docker 環境:快速理解Nginx 反向代理 Nuxt 和 Laravel 的關係

閱讀時間約 15 分鐘

好了,到了這一步,我們已經有了一個基於 Docker 的開發環境,但你可能會想:「這麼多配置,到底是怎麼運作的?」別擔心,今天我們要一起拆解這個 Docker 環境,深入了解 Nginx 如何作為反向代理,協調 Nuxt(前端)和 Laravel(後端)之間的關係。

Docker 環境架構的整體說明

首先,讓我們快速回顧一下整個 Docker 環境的架構:

  • Laravel (backend):後端 API 服務,使用 PHP-FPM 運行。
  • Nuxt (frontend):前端應用,使用 NodeJS 運行,作為 Vue 的服務端渲染框架。
  • Nginx:作為反向代理,處理來自瀏覽器的請求,並將它們分別轉發給 Nuxt 和 Laravel。
  • MariaDB:資料庫服務,用於存儲 Laravel API 的數據。
    我們使用了 Docker Compose 來定義這些容器,讓它們在同一個網路下協同工作。現在,讓我們深入了解每個部分的設定,並探討為什麼要這麼做。

一、docker-compose.yml:容器協調的大腦

docker-compose.yml 是整個 Docker 環境的核心,負責協調各個服務。我們來逐段解析這個檔案,了解每個設定的目的。

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

為什麼這麼設定?

  • build:指定 Dockerfile 的路徑,構建 Laravel 的容器環境。
  • volumes:將本機的 ./api 目錄掛載到容器內的 /var/www/html,方便我們在本機編輯代碼,容器即時更新。
  • environment:設定 Laravel 環境變數,特別是資料庫的連線資訊,讓 Laravel 知道該連接到哪個資料庫。
  • command:這裡有點技巧,我們在容器啟動時檢查 composer.json 是否存在,沒有的話就創建一個新的 Laravel 專案。接著安裝依賴並啟動 PHP-FPM。
  • depends_on:確保在啟動 backend 服務前,資料庫服務 db 已經啟動。
  • networks:將服務加入同一個網路,方便容器之間的通訊。

小提醒

別忘了:環境變數中的資料庫資訊要與資料庫服務的設定相匹配,否則 Laravel 可是會鬧脾氣的。

二、Dockerfile:打造專屬的容器環境

1. Laravel 的 Dockerfile

位於 .docker-env/api/Dockerfile,這個檔案定義了 Laravel 容器的環境。

# 使用 PHP 基礎映像檔
FROM php:8.2-fpm

# 安裝必要的系統套件和 PHP 擴展
RUN apt-get update && apt-get install -y \
git \
unzip \
libjpeg-dev \
libpng-dev \
libzip-dev \
&& docker-php-ext-install pdo_mysql zip

# 安裝 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 and start PHP-FPM
EXPOSE 9000
CMD ["php-fpm"]

為什麼這麼設定?

  • FROM php:8.2-fpm:使用官方的 PHP 8.2 FPM 映像作為基礎,為什麼?因為 Laravel 需要 PHP 環境,而 FPM 能夠與 Nginx 整合。
  • 安裝系統套件和 PHP 擴展:Laravel 依賴於一些 PHP 擴展,如 pdo_mysql、zip 等,沒有它們,某些功能會無法運作。
  • 安裝 Composer:Composer 是 PHP 的套件管理工具,Laravel 的依賴都透過它來管理。
  • 設定工作目錄:將工作目錄設為 /var/www/html,這是 Nginx 預設的網頁根目錄。
  • COPY 專案檔案:將我們的 Laravel 專案代碼複製到容器內。
  • 設置權限:確保網頁服務有權限讀取和寫入必要的檔案。
  • CMD ["php-fpm"]:啟動 PHP-FPM 服務。

個人經驗分享

小技巧:有時候忘記安裝某個 PHP 擴展,結果功能跑不起來,那種感覺就像買了新電器卻沒電池。所以,提前確認所需的擴展,能省下不少時間。

2. Nuxt 的 Dockerfile

位於 .docker-env/web/Dockerfile,定義了 Nuxt 容器的環境。

# 使用 Node.js 20 映像
FROM node:20-alpine

# 設定工作目錄
WORKDIR /app

# 複製 package.json
COPY package*.json ./

# 暴露端口
EXPOSE 3000

# 啟動命令將在 docker-compose.yml 中定義

為什麼這麼設定?

  • FROM node:20-alpine:使用輕量級的 Node.js 20 Alpine 映像,節省空間和資源。
  • WORKDIR /app:設置工作目錄為 /app。
  • COPY package.json ./*:將 package.json 複製進去,方便後續安裝依賴。
  • EXPOSE 3000:暴露 Nuxt 預設的 3000 端口。

三、Nginx 配置:反向代理的魔法師

Nginx 作為反向代理,負責將不同的請求導向正確的服務。我們需要兩個配置檔案:api.conf 和 web.conf。

1. Laravel 的 Nginx 配置 (api.conf)

server {
listen 80;
server_name api.localhost;
root /var/www/html/public;
index index.php index.html;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
include fastcgi_params;
fastcgi_pass laravel-app:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

location ~ /\.ht {
deny all;
}
}

為什麼這麼設定?

  • server_name api.localhost:指定服務的域名,方便本地開發時區分前後端。
  • root /var/www/html/public:Laravel 的入口位於 public 資料夾。
  • location /:處理所有請求,使用 try_files 嘗試找到對應的檔案,否則轉到 index.php。
  • location ~ .php$:處理 PHP 檔案的請求,透過 FastCGI 傳遞給 PHP-FPM(laravel-app:9000)。

2. Nuxt 的 Nginx 配置 (web.conf)

server {
listen 80;
server_name web.localhost;

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;
}
}

為什麼這麼設定?

  • server_name web.localhost:指定前端服務的域名。
  • proxy_pass http://nuxt-app:3000:將所有請求代理到 Nuxt 應用的容器。
  • proxy_set_header:設定必要的頭資訊,確保 WebSocket 等功能正常運作。

小故事時間

曾經有一次,我忘了在 Nginx 配置中設定 proxy_set_header,結果 WebSocket 連線一直失敗。那種抓不到 bug 的感覺,真的是讓人懷疑人生。所以,細節真的很重要!

四、MariaDB:資料庫的心臟

在 docker-compose.yml 中,MariaDB 的配置如下:

# MySQL (MariaDB)
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

為什麼這麼設定?

  • image: mariadb:latest:使用最新的 MariaDB 映像,提供 MySQL 兼容的資料庫服務。
  • environment:設定資料庫的初始用戶名、密碼和資料庫名稱。
  • volumes:將資料庫資料持久化到本機,避免容器重啟時數據丟失。
  • networks:加入同一個網路,讓 Laravel 可以連接到資料庫。

驗證資料庫連線

要確認 Laravel 是否成功連接到資料庫,可以在容器中執行遷移命令:

docker-compose exec backend php artisan migrate

如果看到遷移成功的訊息,表示 Laravel 與資料庫的連線正常。

五、Docker 指令小抄

以下是一些常用的 Docker 指令,方便你在開發過程中操作:

  • 啟動所有服務:
docker-compose up -d --build
  • 查看容器日誌:
docker-compose logs -f [service_name]
  • 進入容器終端:
docker-compose exec [service_name] bash
  • 重新啟動服務:
docker-compose restart [service_name]
  • 停止並移除容器:
docker-compose down

六、為什麼要這樣架構?

  • Docker 的好處:透過容器化,我們可以確保在任何環境下都能有一致的開發和部署環境,再也不用擔心「在我電腦上可以跑啊!」的問題。
  • Nginx 反向代理:統一管理請求,未來要加入 HTTPS、負載均衡等功能都更方便。
  • 服務解耦:前端、後端、資料庫各自獨立,方便維護和升級。

小結

恭喜你!我們已經深入了解了整個 Docker 環境的架構和配置。現在,你不僅知道「怎麼做」,還了解了「為什麼要這麼做」。這種理解將讓你在未來的開發中更加游刃有餘。

最後的叮嚀

別害怕嘗試和錯誤,有時候問題的解答就藏在那些看似不起眼的細節中。就像我常說的,「調整了 N 個配置,只為了解決一個小問題,但這就是成長的過程」。

接下來,我們將進行第一階驗收,看看這一切是否如我們預期的那樣順利運行!

這是一系列以軟體開發為主題的輕鬆分享,內容涵蓋了技術選擇、開發經驗、實戰應用等多方面的議題。無論是如何在眾多框架中做出選擇,還是如何應對技術轉移的挑戰,作者都用幽默、有趣的對話風格,將複雜的技術問題轉化為易懂的故事。
留言0
查看全部
發表第一個留言支持創作者!
好了,到了這個階段,我們終於要進入 Docker 的世界了!前幾篇文章我們討論了系統規劃與需求,現在來到實作的部分,要為整個開發環境打好基礎。這篇文章將帶你一步步打造出一個基於 Docker 的開發環境,裡面包含了 Laravel(後端)、Nuxt(前端)、Nginx(伺服器),以及 MariaDB
這篇文章深入探討了開發個人財務管理系統的規劃過程,包括需求確認、環境建置及技術選型等關鍵步驟。作者強調在開發前進行充分的規劃與設計是成功的基礎,並提供了具體的工具與技術選擇,如PHP、Laravel和Docker。通過清晰的步驟指引,文章幫助讀者掌握系統開發的核心要素,確保順利推進專案。
獨自開發並不等於掌握所有技術,而是具備解決問題和完成專案的能力。透過選擇實用且具挑戰性的專題,如個人財務管理系統,開發者可以快速實現最小可行性產品(MVP)。本文將探討如何從前端或後端開始,搭建核心功能並優化系統,以提升用戶體驗,並持續學習和成長。
這個「我獨自開發」系列,來自我多年的工程師經歷。雖然常聽到大家說團隊合作,但實際上,很多時候我們都在獨自解決問題。無論是學新技術,還是完成某個功能,大部分的時間都是自己在面對螢幕、查資料、試錯誤、解Bug。 所以...
延續上篇: 功能實作篇 框架與結構 接下來我們將深入實作 Laravel 框架中的路由(Router)、控制器(Controller)、業務邏輯(Service)、儲存庫模式(Repository Pattern),以及模型(Model)的細節。這些部分將構成我們縮網址系統的核心功能。
好了,到了這個階段,我們終於要進入 Docker 的世界了!前幾篇文章我們討論了系統規劃與需求,現在來到實作的部分,要為整個開發環境打好基礎。這篇文章將帶你一步步打造出一個基於 Docker 的開發環境,裡面包含了 Laravel(後端)、Nuxt(前端)、Nginx(伺服器),以及 MariaDB
這篇文章深入探討了開發個人財務管理系統的規劃過程,包括需求確認、環境建置及技術選型等關鍵步驟。作者強調在開發前進行充分的規劃與設計是成功的基礎,並提供了具體的工具與技術選擇,如PHP、Laravel和Docker。通過清晰的步驟指引,文章幫助讀者掌握系統開發的核心要素,確保順利推進專案。
獨自開發並不等於掌握所有技術,而是具備解決問題和完成專案的能力。透過選擇實用且具挑戰性的專題,如個人財務管理系統,開發者可以快速實現最小可行性產品(MVP)。本文將探討如何從前端或後端開始,搭建核心功能並優化系統,以提升用戶體驗,並持續學習和成長。
這個「我獨自開發」系列,來自我多年的工程師經歷。雖然常聽到大家說團隊合作,但實際上,很多時候我們都在獨自解決問題。無論是學新技術,還是完成某個功能,大部分的時間都是自己在面對螢幕、查資料、試錯誤、解Bug。 所以...
延續上篇: 功能實作篇 框架與結構 接下來我們將深入實作 Laravel 框架中的路由(Router)、控制器(Controller)、業務邏輯(Service)、儲存庫模式(Repository Pattern),以及模型(Model)的細節。這些部分將構成我們縮網址系統的核心功能。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
前言 大家好上次我們教了如何下載 Docker Image 使用,今天我們要教如何產出自己的 Image,這次會使用一個 Dockerfile 範例,自行打包 Docker Image,初步練習使用 Docker 指令 下載 Dockerfile 教學檔案 在這裡我已經幫忙寫好一個 Docke
Thumbnail
當你安裝完docker,並且設定好所有相關程序後。你正要使用docker去進行操作,讓專案可以在容器哩,方便平台移轉、備份、共用等等等等等;如果你遇到CUDA docker runtime 的問題時,這篇正適合你閱讀。 開始之前,如果你要參考怎麼安裝docker,設定docker環境,請參考:
Thumbnail
前言 上次講到 Dockerfile、DockerImage、Docker Container 他們之間的關係,今天我們要來熟悉 Docker Image 如何使用,教你如何抓取雲端上的 Docker Image, Docker Image 下載來源 當我們今天要要使用 Docker Imag
Thumbnail
前言 上次我們初步體驗 Docker 快速佈署能力,今天我們要來講解 Dockerfile、Docker Image 與 Docker Container 這些常見的名詞,我們來了解在我們佈署的時候做哪些事情 Docker 佈署流程 首先看到如下圖上半部,在我們一個完整的佈署流程,我們會先將我
Thumbnail
前言 大家好在先前我們講了什麼是 Docker,Docker 好處有什麼以及怎麼安裝 Docker,今天我們要來開始初體驗 Docker 容器,使用後您會發現 Docker 非常的方便快速 Docker Hub 介紹 首先在開始學怎麼抓取 Docker Image 之前,我們要先來介紹 Doc
Thumbnail
前言 上次我們講到 Docker 的功用與好處,今天我們要在講解,如何安裝 Docker 這個容器,讓我們在之後的教學應用更好的實作與練習,現在讓我們開始吧 Docker Engine 與 Docker Desktop 首先在講解怎麼安裝 Docker 時,我們先講解 Docker Engin
Thumbnail
前言 上次我們對 Docker 架構進行了講解,今天我們來講解 Docker 的好處,他到底可以幫助我們什麼事情 ? 為什麼 Docker 如此受人喜歡 ? 現在就來講述 Docker 有什麼好處 跨平台 Docker 可以確保在不同的作業系統是可運作的,可減少機器運作的問題 版本控制 打
Thumbnail
前言 上次我們針對 Docker 這樣容器化技術做了一點介紹,今天我們要來講解 Docker 架構,你是否發現在每次程式上伺服器的流程很麻煩呢 ? 是否發現你寫的程式在別的作業系統不能用呢 ? 如果你遇到這些問題,Docker 都可以幫助你解決這些問題 Docker 架構 在 Docker 這
Thumbnail
前言 大家好我們今天要來教 Docker 這項技術,什麼是 Docker ? Docker 可以幫助我們做什麼事情 ? Docker 是一項容器化技術,他可以降低我們在佈署 App 時,讓我們可以有效的分配作業系統資源,降低佈署作業成本,現在讓我們來了解 Docker 要解決的問題 傳統佈署遇
Thumbnail
env 環境變數的設定,通常是為為了 server 而設定的,能快速的切換狀態,但現在的網頁開始,前端的範圍逐漸往後端靠近,所以在設定,也會有 client 的變數會想要在 .env 的情況。此篇就是以 nuxt 為實作,分享此內容 前端架構 最常見的 front 架構,就是把專案 buil
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
前言 大家好上次我們教了如何下載 Docker Image 使用,今天我們要教如何產出自己的 Image,這次會使用一個 Dockerfile 範例,自行打包 Docker Image,初步練習使用 Docker 指令 下載 Dockerfile 教學檔案 在這裡我已經幫忙寫好一個 Docke
Thumbnail
當你安裝完docker,並且設定好所有相關程序後。你正要使用docker去進行操作,讓專案可以在容器哩,方便平台移轉、備份、共用等等等等等;如果你遇到CUDA docker runtime 的問題時,這篇正適合你閱讀。 開始之前,如果你要參考怎麼安裝docker,設定docker環境,請參考:
Thumbnail
前言 上次講到 Dockerfile、DockerImage、Docker Container 他們之間的關係,今天我們要來熟悉 Docker Image 如何使用,教你如何抓取雲端上的 Docker Image, Docker Image 下載來源 當我們今天要要使用 Docker Imag
Thumbnail
前言 上次我們初步體驗 Docker 快速佈署能力,今天我們要來講解 Dockerfile、Docker Image 與 Docker Container 這些常見的名詞,我們來了解在我們佈署的時候做哪些事情 Docker 佈署流程 首先看到如下圖上半部,在我們一個完整的佈署流程,我們會先將我
Thumbnail
前言 大家好在先前我們講了什麼是 Docker,Docker 好處有什麼以及怎麼安裝 Docker,今天我們要來開始初體驗 Docker 容器,使用後您會發現 Docker 非常的方便快速 Docker Hub 介紹 首先在開始學怎麼抓取 Docker Image 之前,我們要先來介紹 Doc
Thumbnail
前言 上次我們講到 Docker 的功用與好處,今天我們要在講解,如何安裝 Docker 這個容器,讓我們在之後的教學應用更好的實作與練習,現在讓我們開始吧 Docker Engine 與 Docker Desktop 首先在講解怎麼安裝 Docker 時,我們先講解 Docker Engin
Thumbnail
前言 上次我們對 Docker 架構進行了講解,今天我們來講解 Docker 的好處,他到底可以幫助我們什麼事情 ? 為什麼 Docker 如此受人喜歡 ? 現在就來講述 Docker 有什麼好處 跨平台 Docker 可以確保在不同的作業系統是可運作的,可減少機器運作的問題 版本控制 打
Thumbnail
前言 上次我們針對 Docker 這樣容器化技術做了一點介紹,今天我們要來講解 Docker 架構,你是否發現在每次程式上伺服器的流程很麻煩呢 ? 是否發現你寫的程式在別的作業系統不能用呢 ? 如果你遇到這些問題,Docker 都可以幫助你解決這些問題 Docker 架構 在 Docker 這
Thumbnail
前言 大家好我們今天要來教 Docker 這項技術,什麼是 Docker ? Docker 可以幫助我們做什麼事情 ? Docker 是一項容器化技術,他可以降低我們在佈署 App 時,讓我們可以有效的分配作業系統資源,降低佈署作業成本,現在讓我們來了解 Docker 要解決的問題 傳統佈署遇
Thumbnail
env 環境變數的設定,通常是為為了 server 而設定的,能快速的切換狀態,但現在的網頁開始,前端的範圍逐漸往後端靠近,所以在設定,也會有 client 的變數會想要在 .env 的情況。此篇就是以 nuxt 為實作,分享此內容 前端架構 最常見的 front 架構,就是把專案 buil