昨天介紹完 laradock
今天要把最後的 Nuxt 架起來。和 laradock
不一樣,小弟這邊沒有特別去找 image 或是開源,而是土炮自製了一個也順便熟悉一下 Docker!
在專案中建立 docker
資料夾,我們要將 docker 相關檔案建立在這個資料夾當中,像 laradock 一樣。
建立 Dockerfile
:
# 因為 Nuxt 要跑 SSR 所以需要 node.js
# 小弟是以 node:12.6.0-alpine 作為基礎 image
FROM node:12.6.0-alpine
# 全域變數先宣告好
ARG APP_CODE_PATH_HOST
ARG APP_CODE_PATH_CONTAINER
ARG APP_PORT_CONTAINER
# 建立 Nuxt 目標資料夾
RUN mkdir -p ${APP_CODE_PATH_CONTAINER}
WORKDIR ${APP_CODE_PATH_CONTAINER}
# 建立 nuxt.config.js 檔案,之後映射要用的
RUN touch nuxt.config.js
# 更新以及安裝套件
RUN apk update & apk upgrade
RUN apk add git
# 複製 run.sh 以及 package.json 兩個檔案作為 image 的一部份
# run.sh 之後會提到
COPY run.sh ${APP_CODE_PATH_CONTAINER}
COPY package.json ${APP_CODE_PATH_CONTAINER}
# 安裝 npm 套件
RUN npm install
# 在 container 開通 port 號
EXPOSE ${APP_PORT_CONTAINER}
# 設定 Nuxt 在 container 要使用的 IP
ENV NUXT_HOST=0.0.0.0
# invoke several commands after container start up
# 當 container 執行起來之後,會呼叫 run.sh 執行額外指令
CMD ./run.sh
建立 .env
以及設定全域變數
# 實際 Nuxt 專案程式碼的位置 (相對於 Dockerfile 以及 docker-compose.yml)
APP_CODE_PATH_HOST=../
# Nuxt 專案的程式碼要複製到 container 的位置
APP_CODE_PATH_CONTAINER=/usr/src/nuxt
# Nuxt 在實際運用時候的 port (舊式瀏覽器上面打的 port)
APP_PORT_HOST=80
# Nuxt 在 container 中所使用的 port (就用預設的 3000)
APP_PORT_CONTAINER=3000
建立 docker-compose.yml
:
version: '3'
services:
# service name 可以隨意取
nuxt:
# container 取名的時候要留意不要跟將要運行的其他 containers 撞名
container_name: nuxt-container
build:
# 簡單來說是 Dockerfile 的位置 (相對於 docker-compose.yml)
context: .
args:
- APP_CODE_PATH_HOST=${APP_CODE_PATH_HOST}
- APP_CODE_PATH_CONTAINER=${APP_CODE_PATH_CONTAINER}
- APP_PORT_CONTAINER=${APP_PORT_CONTAINER}
# 映射資料目前只有將所有目錄及檔案都對到 container 才會成功,
# 之後如果有甚麼新發現在回來修改
volumes:
- ${APP_CODE_PATH_HOST}/assets:${APP_CODE_PATH_CONTAINER}/assets
- ${APP_CODE_PATH_HOST}/components:${APP_CODE_PATH_CONTAINER}/components
- ${APP_CODE_PATH_HOST}/configs:${APP_CODE_PATH_CONTAINER}/configs
- ${APP_CODE_PATH_HOST}/layouts:${APP_CODE_PATH_CONTAINER}/layouts
- ${APP_CODE_PATH_HOST}/middleware:${APP_CODE_PATH_CONTAINER}/middleware
- ${APP_CODE_PATH_HOST}/pages:${APP_CODE_PATH_CONTAINER}/pages
- ${APP_CODE_PATH_HOST}/plugins:${APP_CODE_PATH_CONTAINER}/plugins
- ${APP_CODE_PATH_HOST}/static:${APP_CODE_PATH_CONTAINER}/static
- ${APP_CODE_PATH_HOST}/store:${APP_CODE_PATH_CONTAINER}/store
- ${APP_CODE_PATH_HOST}/nuxt.config.js:${APP_CODE_PATH_CONTAINER}/nuxt.config.js
- ${APP_CODE_PATH_HOST}/package.json:${APP_CODE_PATH_CONTAINER}/package.json
- ${APP_CODE_PATH_HOST}/package-lock.json:${APP_CODE_PATH_CONTAINER}/package-lock.json
# 實際瀏覽器上面輸入的跟 container 之間的 port 對應
ports:
- "${APP_PORT_HOST}:${APP_PORT_CONTAINER}"
上面的 context
只是簡單描述、不完全正確,完整的觀念可以參考這份文件。
建立 run.sh
,這份檔案是當 container 建立之後,我們希望在 container 中執行的一些指令:
#!/bin/sh
# 進入道專案目錄中
cd /usr/src/nuxt
# 更新套件
npm update
wait
# 重新 compile Nuxt 專案並啟動
npm run build
wait
npm run start
# 上面也可以改為 npm run dev 做 hot reload
上面如果使用 npm run dev
,即便在 docker-compose.yml
有將所有檔案映射到 container 當中,但是當我們修改檔案之後,進入 container 用 cat 來看雖然內容有跟著更改,可是 hot reload 並沒有被觸發,只有在 container 內用直接改程式碼才會觸發,這部分小弟也還在研究當中 QAQ!
這裡另外有一個坑,撰寫 sh
或 bash
記得換行要用 「LF
」,尤其是經過 Git 被修改的話,記得要改回來!
將 Nuxt 專案的 package.json
複製到 docker
資料夾底下,讓初始的 image 安裝基本套件。
架站啦! 執行下面指令把 Nuxt 架起來吧!
docker-compose up nuxt
在過程中出現下面錯誤,如果沒有停下來就不用管他,如果錯誤停下來沒有正常建立 image 以及 container 就過一下子重新執行指令!
ERROR: Unable to lock database: Resource temporarily unavailable
ERROR: Failed to open apk database: temporary error (try again later)
上面都完成之後跟昨天一樣,用 docker 分配到的 IP 檢查看看 Nuxt 有沒有架成功!
如果跟小弟一樣是使用 toolbox,接下來測試 API 的串接大多會失敗,因為在 laravel
專案中的 config/cors.php
要將 docker 分配到的 IP 也加到 allowedOrigins
裡面,並重啟服務,這樣才會正常喔!
以上就是小弟常是土炮造輪子架設 Nuxt 專案的一些分享,如果各位鐵人大大有找到好用的 docker image 或是開源歡迎分享,讓小弟可以有更多時間 耍廢吸貓 XD 。