Dockerize Nuxt專案紀錄

Wells Zheng
5 min readJul 15, 2020

--

前一陣子為了將原本的nuxt專案改到AWS ECS上發佈,花了一點時間把原本的專案dockerize了,以下紀錄過程中需要注意的地方。本篇不會介紹docker是什麼喔,對於docker是什麼不太清楚的可以參考Docker官網

第一步就是將原本的專案製作成image,因為之後會將image上傳到AWS的ECR上儲存,並且用ECS FARGATE來把容器跑起來,所以就沒有使用docker-compose而直接使用docker build來製作image。在專案的根目錄新增Dockerfile檔案,內容如下

FROM node:12.18.0-alpineRUN apk add --no-cache openssh-client git
ARG SSH_PRIVATE_KEY
RUN mkdir /root/.ssh/
RUN echo "${SSH_PRIVATE_KEY}" >> /root/.ssh/id_rsa
RUN chmod 0600 /root/.ssh/id_rsa
RUN touch /root/.ssh/known_hosts
RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts
WORKDIR /app/
COPY package.json yarn.lock* ./
RUN yarn install && yarn cache clean
COPY . /app/
RUN yarn build
FROM node:12.18.0-alpine
ENV NODE_ENV=production
WORKDIR /usr/src/
COPY --from=0 /app/ /usr/src/
ENV HOST=0.0.0.0
EXPOSE 3333
CMD ["node", "/usr/src/server/index.js"]

簡單的說明Dockerfile裡面的指令意義

FROM node:12.18.0-alpine

代表image使用的環境,node版本選擇12.18而alpine是製作容器常使用的OS,優點是檔案大小相當小,可以有效地縮小image檔案的大小,而且要安裝package也有很方便的指令apk add來安裝,如果沒有其他特別需求建議可以用alpine即可。

RUN apk add --no-cache openssh-client git
ARG SSH_PRIVATE_KEY
RUN mkdir /root/.ssh/
RUN echo "${SSH_PRIVATE_KEY}" >> /root/.ssh/id_rsa
RUN chmod 0600 /root/.ssh/id_rsa
RUN touch /root/.ssh/known_hosts
RUN ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts

這一段是因為專案內有package是抓私有的git repository,之後在yarn install的時候如果沒有SSH key就沒有辦法安裝,所以我們利用ARG這個參數,在執行docker build指令的時候將key傳進來這樣才能夠正常的把專案所需的package抓進來。另外一種狀況是當你的專案內容不是從本機複製進image,而是需要把專案直接從私有的repository抓回來的話,也會需要處理ssh key的問題。

WORKDIR /app/

會將工作資料夾設定到/app/上,如果image內沒有/app/資料夾寫了這行就會替你建立起來,不需要先寫RUN mkdir /app/

COPY package.json yarn.lock* ./
RUN yarn install && yarn cache clean
COPY . /app/
RUN yarn build

這一行指令就是將本機專案資料夾裡的package.json和yarn.lock複製到image內的工作資料夾,並且在image裡執行yarn install把專案所需要的package給裝起來,接著再將專案內容複製進/app資料夾,然後才執行yarn build將我們的nuxt專案build起來。專案build完之後,因為這一份image裡面存有剛剛丟進來的ssh key,所以當然不能夠直接使用,所以會使用multi-stage的方法製作最終的image

FROM node:12.18.0-alpine
ENV NODE_ENV=production
WORKDIR /usr/src/
COPY --from=0 /app/ /usr/src/
ENV HOST=0.0.0.0
EXPOSE 3333
CMD ["node", "/usr/src/server/index.js"]

最後一樣使用node:12.18.0-alpine作為image的基礎,然後將之前存放的在stage 1 的/app資料夾複製到最終這一個stage 2 image裡面,並且將環境和對外連接的port設定好,最後將專案啟動。

接著在專案資料夾內執行

docker build --build-arg SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)" -t project_name .

就會依據Dockerfile一步一步的將image建立起來,這裏的 — build-arg就是上述為了將ssh key傳進去容器內使用的。

另外需要建立.dockerignore檔案,把不需要複製的檔案設定好,基本上可以複製.gitignore即可。

因為是選擇使用ECS的FARGATE來啟動容器,就不需要另外安裝nginx來做伺服器代理,直接透過loadbalancer來處理流量即可,如果是要在EC2上面使用docker來佈建,就會建議改用docker-compose來處理容器的建立。

發佈到ECS的時候要注意的是因為ECS對於docker-compose的支援不高,使用了VPC連線之後各個container就沒辦法透過docker network來溝通,所以如果需要像是redis或者資料庫的話就要特別的留意溝通的問題。

--

--

Wells Zheng
Wells Zheng

Written by Wells Zheng

Backend Developer @ WeibyApps

No responses yet