製作Docker映象

misakivv發表於2024-05-29

目錄
  • 一、Docker構建映象的原理
    • 1、映象分層原理
    • 2、Docker的映象結構
    • 3、分層儲存原理
    • 4、構建命令與層的關係
    • 5、最終映象的建立
  • 二、docker commit 構建映象
    • 1、使用場景
    • 2、手動製作yum版的nginx映象
      • 2.1、啟動一個centos容器,安裝好常用的軟體以及nginx
      • 2.2、關閉nginx後臺執行
      • 2.3、自定義web頁面
      • 2.4、提交為映象
      • 2.5、從自己的映象啟動容器
  • 三、DockerFile
    • 1、什麼是DockerFile
    • 2、DockerFile構建映象過程
  • 四、DockerFile的常用指令
    • 1、FROM
      • 1.1、指令格式
      • 1.2、示例
    • 2、ARG
      • 2.1、指令格式
      • 2.2、作用域
      • 2.3、預定義ARG
      • 2.4、示例
    • 3、LABEL
      • 3.1、指令格式
      • 3.2、示例
      • 3.3、多個標籤
      • 3.4、單行多標籤
      • 3.5、多行多標籤(推薦)
      • 3.6、檢視映象標籤
    • 4、EXPOSE
      • 4.1、指令格式
      • 4.2、示例:同時監聽TCP和UDP協議的埠
    • 5、ENV
      • 5.1、指令格式
      • 5.2、示例
      • 5.3、持續性
      • 5.4、注意事項
    • 6、ADD
      • 6.1、指令格式
      • 6.2、選項
      • 6.3、示例
        • 1、萬用字元匹配
        • 2、相對路徑
        • 3、絕對路徑
        • 4、特殊字元處理
    • 7、COPY
      • 7.1、指令格式
      • 7.2、選項
      • 7.3、COPY --from
      • 7.4、COPY --chown 和 COPY --chmod
      • 7.5、COPY --link
    • 8、USER
      • 8.1、指令格式
      • 8.2、示例
    • 9、WORKDIR
      • 9.1、指令格式
      • 9.2、示例
    • 10、VOLUME
      • 10.1、指令格式
      • 10.2、示例
      • 10.3、注意事項
    • 11、ENTRYPOINT
      • 11.1、指令格式
      • 11.2、示例
    • 12、RUN
      • 12.1、指令格式
      • 12.2、示例:快取Go包
      • 12.3、示例:快取apt包
      • 12.4、示例:訪問GitLab
    • 13、CMD
      • 13.1、指令格式
      • 13.2、注意事項
  • 五、DockerFile製作映象(製作nginx映象)
    • 1、下載centos映象
    • 2、建立對應目錄
    • 3、進入指定目錄下載原始碼包
    • 4、編寫DockerFile
      • 4.1、解析
    • 5、構建映象
    • 6、測試驗證
  • 六、映象上傳
    • 1、阿里雲倉庫
      • 1.1、註冊賬戶
      • 1.2、建立個人版例項
      • 1.3、設定Registry登入密碼
      • 1.4、建立映象倉庫
      • 1.5、登入阿里雲Docker Registry
      • 1.6、將映象推送到Registry
    • 2、Docker Hub上傳映象

一、Docker構建映象的原理

1、映象分層原理

Docker映象是由一系列只讀的層(layers)組成的,每個層代表了一組檔案系統的更改。這些更改可以是新增檔案、刪除檔案、修改檔案等操作。映象的最底層通常是一個基礎映象,比如基於CentOS、Ubuntu、Alpine等作業系統。往上每一層代表了Dockerfile中每個指令的執行結果。重要的是,每一層都是不可變的,一旦建立就不會被修改,新的更改會在其上新建一層。

2、Docker的映象結構

489206588e3d8b2b61c611f85790f220

docker的分層映象結構如圖所示,映象的最底層必須是一個啟動檔案系統(bootfs)的映象層。bootfs的上層映象稱為根映象(rootfs)或者基礎映象(Base Image),它一般是作業系統,比如centos、debian或者Ubuntu。

使用者的映象必須構建在基礎映象之上。如圖所示,emacs映象層就是在基礎映象上安裝emacs建立出來的映象,在此基礎上安裝apache又建立了新的映象層。利用這個新的映象層啟動的容器裡執行的是一個已經安裝好emacs和apache的Debian系統。

3、分層儲存原理

Docker映象採用UnionFS(聯合檔案系統,如AUFS、OverlayFS等)實現分層儲存。UnionFS允許將多個檔案系統層次疊加以形成一個單一的合併檢視。對於Docker映象來說,每個層都是隻讀的,除了最頂層的可寫層(在容器執行時建立)。

  • 基礎層:通常是作業系統層,包含最低階別的檔案和庫。
  • 中間層:由Dockerfile中的每個指令生成,每個層都是對前一層的增量修改。
  • 讀寫層(容器層):容器執行時,會在映象的頂部新增一個可寫的層,用於儲存容器執行時的所有改動。

4、構建命令與層的關係

  • 在Dockerfile中,每個RUNCOPYADD等指令執行後,都會在現有映象基礎上新增一個新的只讀層。
  • 如果指令沒有導致檔案系統的變化(例如,執行一個檢查系統狀態的命令但不改變任何檔案),Docker可能不會建立新的層。
  • 重複的構建步驟可以透過Docker的快取機制避免重複執行,從而加速構建過程。

5、最終映象的建立

構建過程的最後,Docker將所有這些層組合起來,併為這個組合賦予一個唯一的ID,這就是最終的Docker映象。這個映象可以被打上標籤(tag),便於識別和後續的拉取、推送操作。

二、docker commit 構建映象

1、使用場景

  • 構建臨時的測試映象;
  • 容器被入侵後,使用docker commit,基於被入侵的容器構建映象,從而保留現場,方便以後追溯。

2、手動製作yum版的nginx映象

2.1、啟動一個centos容器,安裝好常用的軟體以及nginx

[root@localhost ~]# docker run -it --name centos-v1 centos:7 bash
[root@95ef0464ffb2 /]# yum install -y epel-release
[root@95ef0464ffb2 /]# yum install -y nginx
[root@95ef0464ffb2 /]# yum install -y wget vim pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop

2.2、關閉nginx後臺執行

[root@95ef0464ffb2 /]# sed -i '/^pid \/run\/nginx.pid;$/a daemon off;' /etc/nginx/nginx.conf

[root@95ef0464ffb2 /]# egrep -v "^$|^#" /etc/nginx/nginx.conf | head -5
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
daemon off;

2.3、自定義web頁面

[root@95ef0464ffb2 /]# echo 'hello yum_nginx' > /usr/share/nginx/html/index.html

2.4、提交為映象

docker commit -m "my first nginx image v1" centos-v1 centos_nginx:v1

image-20240526175243723

2.5、從自己的映象啟動容器

docker run -d -p 8080:80 --name my_centos_nginx centos_nginx:v1 /usr/sbin/nginx

image-20240526175506018

三、DockerFile

1、什麼是DockerFile

DockerFile 是一個用於自動構建 Docker 映象的文字檔案,其中包含了使用者可以給出的所有構建映象所需的指令和引數。

這個檔案按照從上至下的順序定義了一系列構建映象的步驟,每個指令通常對應於映象中的一個層。

DockerFile 的設計使得映象的建立過程高度可程式設計、可重複及可共享,有利於實現持續整合和持續部署(CI/CD)的工作流程。

2、DockerFile構建映象過程

1、首先,建立一個目錄用於存放應用程式以及構建過程中使用到的各個檔案等;
2、然後,在這個目錄下建立一個Dockerfile檔案,一般建議Dockerfile的檔名就是Dockerfile;
3、編寫Dockerfile檔案,編寫指令,如,使用FROM 指令指定基礎映象,COPY指令複製檔案,RUN指令指定要執行的命令,ENV設定環境變數,EXPOSE指定容器要暴露的埠,WORKDIR設定當前工作目錄,CMD容器啟動時執行命令,等等指令構建映象;
4、Dockerfile編寫完成就可以構建映象了,使用docker build -t 映象名:tag . 命令來構建映象,最後一個點是表示當前目錄,docker會預設尋找當前目錄下的Dockerfile檔案來構建映象,如果不使用預設,可以使用-f引數來指定dockerfile檔案,如:docker build -t 映象名:tag -f /xx/xxx/Dockerfile
5、使用docker build命令構建之後,docker就會將當前目錄下所有的檔案傳送給docker daemon,順序執行Dockerfile檔案裡的指令,在這過程中會生成臨時容器,在臨時容器裡面安裝RUN指定的命令,安裝成功後,docker底層會使用類似於docker commit命令來將容器儲存為映象,然後刪除臨時容器,以此類推,一層層的構建映象,執行臨時容器安裝軟體,直到最後的映象構建成功。

四、DockerFile的常用指令

官方文件

1、FROM

指定基礎映象,必須為第一個命令

1.1、指令格式

FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
  • FROM指令用於指定基礎映象
  • –platform選項可用在FROM多平臺映象的情況下指定平臺。例如,linux/amd64、lunux/arm64、windows/amd64。
  • AS name表示為構建階段命令,在後續FROM和COPY --from=name說明中可以使用這個名詞,引用此階段構建的映像。
  • tag或digest值是可選的。如果您省略其中任何一個,構建器預設使用latest標籤。如果找不到指定tag,構建起將返回錯誤。
  • 為了保證映象精簡,可以選用體積較小的Alpin或Debian作為基礎映象

1.2、示例

ARG  CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD  /code/run-app

FROM extras:${CODE_VERSION}
CMD  /code/run-extras

2、ARG

定義建立映象過程中使用的變數

ARG是唯一可以位於FROM指令之前的指令

2.1、指令格式

ARG <name>[=<default value>]

<name>是變數名,[=<default value>]是可選的預設值。

2.2、作用域

ARG變數的定義從其在Dockerfile中的定義行開始生效,並在構建階段結束時失效。

要在多個構建階段使用相同的ARG,每個階段都需要重新宣告ARG。

2.3、預定義ARG

Docker預定義了一系列ARG變數,如HTTP_PROXY、HTTPS_PROXY等,這些可以在構建時不需在Dockerfile中宣告,直接透過命令列的--build-arg使用。

2.4、示例

FROM busybox
ARG user1
ARG buildno=1

在這個例子中,user1沒有預設值,而buildno的預設值是1。

3、LABEL

為生成的映象新增後設資料標籤資訊

這些後設資料以鍵值對的形式存在

3.1、指令格式

LABEL <key>=<value> <key>=<value> <key>=<value> ...
  • 鍵(key):應當是唯一的識別符號,用於描述標籤的內容類別。
  • 值(value):與鍵相關聯的具體資料內容,可以包含任何字串,包括空格。如果值中需要包含空格或特殊字元,應使用雙引號包圍並適當使用跳脫字元(如\)。

3.2、示例

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

3.3、多個標籤

可以在單行或多行上指定多個標籤,儘管這樣做在Docker 1.10版本後不再減少最終映象的大小,但仍然是一種組織程式碼的可選方式

3.4、單行多標籤

LABEL multi.label1="value1" multi.label2="value2" other="value3"

3.5、多行多標籤(推薦)

LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

使用雙引號而非單引號:當值中包含環境變數插值等需要解析的元素時,必須使用雙引號,因為單引號會阻止變數展開。

如果基礎映象(即FROM指令指定的映象)中已經包含了某些標籤,那麼這些標籤會被繼承。如果有相同鍵的標籤在新映象的Dockerfile中被重新定義,那麼新定義的值將覆蓋原有的值。

3.6、檢視映象標籤

docker image inspect --format='{{json .Config.Labels}}' myimage
{
  "com.example.vendor": "ACME Incorporated",
  "com.example.label-with-value": "foo",
  "version": "1.0",
  "description": "This text illustrates that label-values can span multiple lines.",
  "multi.label1": "value1",
  "multi.label2": "value2",
  "other": "value3"
}

4、EXPOSE

宣告映象內服務監聽的埠

  • 文件作用EXPOSE主要是為了提供一種文件記錄的方式,幫助理解容器設計意圖中哪些埠需要被外部訪問。它不改變容器的實際行為,也不直接導致埠暴露給宿主機或其他網路服務。
  • TCP與UDP:預設情況下,如果沒有指定協議,EXPOSE認為埠使用TCP協議。你也可以明確指定埠為UDP,如EXPOSE 80/udp。若需同時支援TCP和UDP,需分別宣告兩次:EXPOSE 80/tcpEXPOSE 80/udp
  • 執行時覆蓋:儘管Dockerfile中指定了EXPOSE,但在執行容器時,可以透過docker run-p標誌靈活地重寫這些設定,比如對映到不同的宿主機埠,或者更改協議。

4.1、指令格式

EXPOSE <port> [<port>/<protocol>...]

4.2、示例:同時監聽TCP和UDP協議的埠

EXPOSE 80/tcp
EXPOSE 80/udp
docker run -p 80:80/tcp -p 80:80/udp ...

5、ENV

用於設定環境變數

5.1、指令格式

ENV <key>=<value> ...
  • 設定環境變數:允許為後續構建階段中的所有指令設定環境變數,變數名是<key>,變數值是<value>。這些環境變數可以在後續的RUNCMD等指令中透過引用,支援環境變數替換。
  • 巢狀解析:環境變數的值可以包含或引用其他環境變數,並且支援使用引號和反斜槓來包含空格或特殊字元,但引號會被移除,除非轉義。

5.2、示例

ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
    MY_CAT=fluffy
    
#批次設定

5.3、持續性

  • 持久化:透過ENV設定的環境變數不僅在構建階段有效,還會保留在從該映象建立的容器中。你可以使用docker inspect檢視這些值,透過docker run --env <key>=<value>來覆蓋它們。
  • 繼承性:在多階段構建中,子階段會繼承父階段設定的環境變數。

5.4、注意事項

  • 副作用:環境變數的永續性可能導致意料之外的行為變化。例如,設定DEBIAN_FRONTEND=noninteractive會改變apt-get的行為,可能給映象的使用者帶來混淆。

  • 構建時使用:如果環境變數只在構建過程中需要,而在最終映象中不需要,可以考慮在單獨的命令中設定,如:

    RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...
    
  • 使用ARG:或者,可以使用ARG指令來設定構建時的變數,這些變數不會儲存在最終的映象中。

6、ADD

用於將檔案、目錄或遠端檔案URL新增到映象的檔案系統中

6.1、指令格式

ADD [OPTIONS] <src> ... <dest>
ADD [OPTIONS] ["<src>", "<dest>"]
  • <src>可以是本地路徑、通配檔案、目錄或URL。支援萬用字元(如*?)。URL要求絕對路徑必須指向檔案。
  • <dest>目標路徑,絕對或相對於當前WORKDIR。指定目錄。如果 <dest>結尾是/<src>是URL,Docker會根據URL中的檔名來命名解壓,解壓後的檔案儲存在指定的目錄中。

6.2、選項

--keep-git-dir: 保留遠端Git倉庫中的.git目錄。

--checksum: 驗證資源的校驗籤。

--chown: 設定檔案許可權。

--link:硬連結處理。

--exclude:排除模式匹配的檔案或目錄。

6.3、示例

1、萬用字元匹配
ADD hom* /mydir/
#新增以"hom"開頭的所有檔案到mydir目錄中

ADD hom?.txt /mydir/
#單字元匹配
2、相對路徑

<dest>是相對路徑,它會相對於當前的WORKDIR

ADD test.txt relativeDir/
#將test.txt新增到relativeDir內
3、絕對路徑

<dest>以斜槓開頭,它是絕對路徑。

ADD test.txt /absoluteDir/
#將test.txt新增到absoluteDir根目錄下
4、特殊字元處理

如果檔名包含如方括號等特殊字元,需要按照Go語言規則轉義路徑

ADD arr[[]0].txt /mydir/

7、COPY

編寫Dockerfile的時候copy宿主機檔案到映象中。

7.1、指令格式

COPY [OPTIONS] <src> ... <dest>
COPY [OPTIONS] ["<src>", ... "<dest>"]

7.2、選項

  • --from=<name>:從之前的構建階段或指定的映象中複製檔案,而非當前構建上下文。
  • --chown=<user>:<group>:設定複製檔案的使用者和組所有權。
  • --chmod=<perms>:設定複製檔案的許可權模式。
  • --link[=<boolean>]:啟用連結層機制,使得檔案獨立於前序層,最佳化快取使用。
  • --parents[=<boolean>]:保留源路徑中的父目錄結構。
  • --exclude=<pattern>:排除符合指定模式的檔案或目錄

7.3、COPY --from

允許從一個已有的映象、構建階段或者其他命名的上下文中複製檔案

FROM alpine AS build
COPY . .
RUN apk add clang
RUN clang -o /hello hello.c

FROM scratch
COPY --from=build /hello /

在一個多階段構建中,可以指定從名為build的構建階段複製檔案

COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
#也可以直接從其他映象複製檔案,比如從官方的Nginx映象中複製配置檔案

7.4、COPY --chown 和 COPY --chmod

COPY [--chown=<使用者>:<組>] [--chmod=<許可權>...] <源路徑>... <目標路徑>
COPY --chown=55:mygroup files* /somedir/
COPY --chown=bin files* /somedir/
COPY --chown=1 files* /somedir/
COPY --chown=10:11 files* /somedir/
COPY --chown=myuser:mygroup --chmod=644 files* /somedir/
COPY [--link[=<布林值>]] <源路徑> ... <目標路徑>
# syntax=docker/dockerfile:1
FROM alpine
COPY --link /foo /bar

相當於

FROM alpine
# 第一個構建

FROM scratch
COPY /foo /bar
# 第二個構建,並將兩個映象的所有層合併在一起

8、USER

用於設定後續當前構建階段中預設使用的使用者名稱(或 UID)以及可選的使用者組(或 GID)。

如果所指定的使用者沒有主組,那麼映象(或之後的指令)將會以根組(root group)的身份執行。

8.1、指令格式

USER <user>[:<group>]

USER <UID>[:<GID>]

8.2、示例

FROM microsoft/windowsservercore
# 在容器中建立 Windows 使用者
RUN net user /add patrick
# 為後續指令設定使用者 patrick
USER patrick

9、WORKDIR

用於為 Dockerfile 中隨後的 RUN, CMD, ENTRYPOINT, COPY, 和 ADD 指令設定工作目錄。

如果指定的工作目錄不存在,即使之後的 Dockerfile 指令未使用到它,也會被建立。

9.1、指令格式

WORKDIR /path/to/workdir

9.2、示例

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

Dockerfile 中可以多次使用 WORKDIR 指令。如果給出的是相對路徑,它將是相對於前一個 WORKDIR 指令的路徑。

最後的 pwd 命令的輸出將是 /a/b/c

10、VOLUME

建立一個資料卷掛載點

10.1、指令格式

VOLUME ["/data"]

10.2、示例

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

這個 Dockerfile 將生成一個映象,使得執行 docker run 時會在 /myvol 建立一個新的掛載點,並將 greeting 檔案複製到新建立的卷裡。

10.3、注意事項

  • 在基於 Windows 的容器上,容器內卷的目標必須是:
    • 一個不存在或為空的目錄
    • 除了 C: 以外的其他驅動器
  • 若在 Dockerfile 中宣告卷後,有任何構建步驟修改了卷內的資料,這些更改將會被丟棄。
  • 列表解析遵循 JSON 陣列格式。你需要使用雙引號(")而不是單引號(')來包圍文字。
  • 宿主機目錄是在容器執行時宣告的:由於宿主機目錄(即掛載點)依附於特定宿主機,為了保持映象的可移植性(因為無法確保特定的宿主機目錄在所有宿主機上都存在),你不能在 Dockerfile 中直接從宿主機掛載目錄。VOLUME 指令不支援指定宿主機目錄引數。你需要在建立或啟動容器時指定掛載點。

11、ENTRYPOINT

指定映象的預設入口命令,該入口命令會在啟動容器時作為根命令執行,所有傳入值作為該命令的引數

每個DockerFile中只能有一個ENTRYPOINT,當指定多個時只有最後一個起效

11.1、指令格式

ENTRYPOINT ["executable", "param1", "param2"]
#exec形式

ENTRYPOINT command param1 param2
#shell形式

11.2、示例

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

當你執行這個容器時,可以看到top是唯一的程序:

docker run -it --rm --name test top -H

12、RUN

執行指定命令

每條RUN指令將在當前映象基礎上執行指定命令,並提交為新的映象層

當命令較長時可以使用\來換行

12.1、指令格式

RUN [OPTIONS] <command> ...
#shell形式

RUN [OPTIONS] [ "<command>", ... ]
#exec形式

12.2、示例:快取Go包

# syntax=docker/dockerfile:1
FROM golang
RUN --mount=type=cache,target=/root/.cache/go-build \
  go build ...

12.3、示例:快取apt包

# syntax=docker/dockerfile:1
FROM ubuntu
RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
  --mount=type=cache,target=/var/lib/apt,sharing=locked \
  apt update && apt-get --no-install-recommends install -y gcc

12.4、示例:訪問GitLab

# syntax=docker/dockerfile:1
FROM alpine
RUN apk add --no-cache openssh-client
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
RUN --mount=type=ssh \
  ssh -q -T git@gitlab.com 2>&1 | tee /hello
# "Welcome to GitLab, @GITLAB_USERNAME_ASSOCIATED_WITH_SSHKEY" should be printed here
# with the type of build progress is defined as `plain`.
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa
(Input your passphrase here)
docker buildx build --ssh default=$SSH_AUTH_SOCK .

13、CMD

CMD指令用來指定啟動容器時預設執行的命令

13.1、指令格式

CMD ["executable","param1","param2"]
#相當於執行executable param1 param2

CMD ["param1","param2"]
#提供給ENTRYPOINT的預設引數

CMD command param1 param2
#在預設的shell中執行,提供給需要互動的應用

每個Dockerfile 只能有一條CMD命令。如果指定了多條命令,只有最後一條會被執行

13.2、注意事項

如果使用CMDENTRYPOINT指令提供預設引數,那麼CMDENTRYPOINT指令都應該以exec形式指定。

RUN實際上執行一個命令並提交結果;CMD在構建時不執行任何操作,但指定了映象的預期命令。

五、DockerFile製作映象(製作nginx映象)

1、下載centos映象

docker pull centos:7

2、建立對應目錄

mkdir -pv dockerfile/{web/{nginx,apache},system/{centos,ubuntu}}

image-20240528231449034

3、進入指定目錄下載原始碼包

[root@localhost ~]# cd dockerfile/web/nginx/
[root@localhost nginx]# pwd
/root/dockerfile/web/nginx
[root@localhost nginx]# wget http://nginx.org/download/nginx-1.20.1.tar.gz
[root@localhost nginx]# ls
nginx-1.20.1.tar.gz

4、編寫DockerFile

[root@localhost nginx]# vim Dockerfile

FROM centos:7

MAINTAINER misakivv 2830909671@qq.com

RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop

ADD nginx-1.20.1.tar.gz /usr/local/src/

RUN cd /usr/local/src/nginx-1.20.1 \
&& ./configure --prefix=/usr/local/nginx --with-http_sub_module \
&& make \
&& make install \
&& cd /usr/local/nginx

# ADD nginx.conf /usr/local/nginx/conf/nginx.conf

RUN useradd -s /sbin/nologin nginx \
&& ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx \
&& echo 'test nginx !' > /usr/local/nginx/html/index.html

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]

4.1、解析

  1. FROM centos:7: 基於CentOS 7映象來建立新的Docker映象。這是構建過程的起點。
  2. MAINTAINER misakivv 2830909671@qq.com: 指定維護者的資訊,包括姓名(或暱稱)和聯絡方式。不過,這個指令在Dockerfile最佳實踐中已不再推薦使用,建議使用LABEL替代以提供更多後設資料資訊。
  3. RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop: 安裝一系列必要的軟體包,包括開發工具、編譯器、Nginx依賴庫等,-y參數列示自動確認安裝過程中的所有提示。
  4. ADD nginx-1.20.1.tar.gz /usr/local/src/: 將當前目錄下的nginx-1.20.1.tar.gz檔案新增到容器的/usr/local/src/目錄中。
  5. 接下來的幾行命令是在容器內編譯並安裝Nginx:
    • cd /usr/local/src/nginx-1.20.1: 進入剛剛解壓的Nginx原始碼目錄。
    • ./configure --prefix=/usr/local/nginx --with-http_sub_module: 配置Nginx,指定安裝路徑為/usr/local/nginx,並啟用http_sub_module模組,該模組用於字串替換,增強URL重寫能力。
    • make && make install: 編譯並安裝Nginx。
    • cd /usr/local/nginx: 回到Nginx的安裝目錄。
  6. 註釋掉的# ADD nginx.conf /usr/local/nginx/conf/nginx.conf行原本打算將自定義的nginx配置檔案複製到Nginx配置目錄,但已被註釋,意味著使用Nginx預設配置。
  7. RUN useradd -s /sbin/nologin nginx: 建立一個名為nginx的系統使用者,並且該使用者不能登入(-s /sbin/nologin)。
  8. && ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx: 建立一個軟連結,使得可以從系統的標準路徑呼叫Nginx可執行檔案。
  9. && echo 'test nginx !' > /usr/local/nginx/html/index.html: 在Nginx的預設網頁目錄建立一個簡單的測試索引頁。
  10. EXPOSE 80 443: 宣告容器執行時需要監聽的埠,分別是HTTP(80)和HTTPS(443)埠。
  11. CMD ["nginx", "-g", "daemon off;"]: 設定容器啟動時執行的命令,這裡是以非守護程序模式啟動Nginx,方便直接檢視輸出和進行除錯。

5、構建映象

[root@localhost nginx]# docker build -t nginx:v1 .
[root@localhost nginx]# docker images | grep v1
nginx        v1        e5d32f022cdc   56 seconds ago   650MB

image-20240528232421939

6、測試驗證

[root@localhost nginx]# docker run -itd -p 8088:80 nginx:v1
0c2810cb9b168890b59264a1990dcc5b5e8782e337a757c99d42dc061cb08a7c

image-20240528232551175

六、映象上傳

1、阿里雲倉庫

阿里雲容器映象服務

1.1、註冊賬戶

image-20240529090130985

1.2、建立個人版例項

image-20240529090213618
image-20240529090253777

1.3、設定Registry登入密碼

image-20240529090420788

1.4、建立映象倉庫

image-20240529090713347
image-20240529091119916
image-20240529091246114

1.5、登入阿里雲Docker Registry

docker login --username=misaki0 registry.cn-hangzhou.aliyuncs.com

image-20240529091435645

用於登入的使用者名稱為阿里雲賬號全名,密碼為開通服務時設定的密碼。

您可以在訪問憑證頁面修改憑證密碼。

1.6、將映象推送到Registry

docker tag nginx:v1 registry.cn-hangzhou.aliyuncs.com/misaki_nginx/my_nginx:v1
#將本地nginx:v1映象建立標籤並歸屬到阿里雲映象服務的指定倉庫中
docker push registry.cn-hangzhou.aliyuncs.com/misaki_nginx/my_nginx:v1
#將重新標記的映象推送到阿里雲的容器映象倉庫中

image-20240529092258256

image-20240529092901705

2、Docker Hub上傳映象

目前我還沒註冊,暫時寫不了這部分的映象上傳

但基本思路還是註冊登入賬戶--> 本地登入倉庫--> 給需要上傳的映象tag標籤 --> docker push -->官網驗證即可

相關文章