iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 30
1
Modern Web

RRR撞到不負責之 Laravel + Nuxt.js 踩坑全紀錄系列 第 30

Day 30. 博大坑深的 Docker 部屬 - Nuxt (2/2)

昨天介紹完 laradock 今天要把最後的 Nuxt 架起來。和 laradock 不一樣,小弟這邊沒有特別去找 image 或是開源,而是土炮自製了一個也順便熟悉一下 Docker!

Nuxt 部屬

  1. 在專案中建立 docker 資料夾,我們要將 docker 相關檔案建立在這個資料夾當中,像 laradock 一樣。

  2. 建立 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
    
  3. 建立 .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
    
  4. 建立 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 只是簡單描述、不完全正確,完整的觀念可以參考這份文件

  5. 建立 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!

    這裡另外有一個坑,撰寫 shbash 記得換行要用 「LF」,尤其是經過 Git 被修改的話,記得要改回來!

  6. 將 Nuxt 專案的 package.json 複製到 docker 資料夾底下,讓初始的 image 安裝基本套件。

  7. 架站啦! 執行下面指令把 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)
    
  8. 上面都完成之後跟昨天一樣,用 docker 分配到的 IP 檢查看看 Nuxt 有沒有架成功!

  9. 如果跟小弟一樣是使用 toolbox,接下來測試 API 的串接大多會失敗,因為在 laravel 專案中的 config/cors.php 要將 docker 分配到的 IP 也加到 allowedOrigins 裡面,並重啟服務,這樣才會正常喔!


以上就是小弟常是土炮造輪子架設 Nuxt 專案的一些分享,如果各位鐵人大大有找到好用的 docker image 或是開源歡迎分享,讓小弟可以有更多時間 耍廢吸貓 XD


上一篇
Day 29. 博大坑深的 Docker 部屬 - laradock (1/2)
下一篇
Day NaN. 完賽心得
系列文
RRR撞到不負責之 Laravel + Nuxt.js 踩坑全紀錄31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言