[容器] 如何寫 Dockerfile

前面兩篇筆記都在整理如何操作 docker container,要怎麼製作最重要的 Image 呢? 我會在這篇整理出來

要建立出一個可以用來執行的 Image,就必須透過 Dockerfile 來設定,Dockerfile 是一個類似文字檔的設定檔,docker 會依 Dockerfile 內的設定建立出一個可以部屬到 Registry 的 Image,其設定內容其實不複雜,以下為簡單語法介紹

Dockerfile 結構與使用語法

如之前所說,Image 所能執行的 OS 必須跟底層 docker server 跑的 OS 一樣或是使用同種 Kernel,所以當 docker server 是跑在 Linux base 上,那 Dockerfile 能跑的環境也只能是 Linux base。下面是一個簡單的範例

1
2
3
4
FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
  • FROM Image 將執行的環境,這邊可以使用別人建立好的 Base Image,通常是作業系統,例如 ubuntu, centos 或是 core/aspnet 的執行環境
  • COPY 複製本機檔案到 Image 裡,本機根目錄的認定為 Dockerfile 所處的目錄
  • RUN 執行 Linux 指令
  • CMD 當執行 docker run 時會執行的指令,如果有個 CMD 只有最後一行會生效

如果能看懂跟理解上面的 Dockerfile,那基本上就只是 Dockerfile 語法及環境設定的熟悉度了,下面再列出幾個常用的指令

  • WORKDIR 設定當前的工作目錄

    1
    WORKDIR /app
  • LABEL Image 的 Metadata 資訊

    1
    LABEL description="這是LABEL的範例" version="1.0" owner="CK's Notepad"
  • ENV 設定環境變數

    1
    ENV <KEY> <Value>
  • ENTRYPOINT 作用跟 CMD 一樣,差異在他不會被 docker run <image> <command> 給覆蓋掉

  • EXPOSE 宣告 Container 運行時對外有哪些 Port 可以使用 (宣告而已)

實際 Dockerfile 範例

asp.net core

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
RUN dotnet restore

# copy everything else and build app
COPY aspnetapp/. ./aspnetapp/
WORKDIR /app/aspnetapp
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS runtime
WORKDIR /app
COPY --from=build /app/aspnetapp/out ./
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

Angular

  • 單純可以執行的

    1
    2
    3
    FROM nginx:alpine
    COPY /dist/app-to-run-inside-docker /usr/share/nginx/html
    EXPOSE 80
  • 在 docker 環境內建置部屬 (multiple-stage)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # stage 1
    FROM node:alpine AS my-app-build
    WORKDIR /app
    COPY . .
    RUN npm install && npm run build

    # stage 2
    FROM nginx:alpine
    COPY --from=my-app-build /app/dist/app-to-run-inside-docker /usr/share/nginx/html
    EXPOSE 80

建置 Dockerfile

要建置 Image 透過指令就可以完成了

1
2
3
docker build [OPTIONS] PATH | URL | -
// 範例
docker build -t angular-app .
  • -t : 上 Tag