<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 筆記 [TOC=3,8] ---- ### 鏡像包含什么? - 操作系統 root 根文件和目錄 - 包含運行程序依賴的環境及其配置,如 sdk、php、python - 包含完整的運行程序(如 源程序、應用配置等 以及 依賴的三方包和庫) ---- ### 應該選擇什么版本的基礎鏡像? 如果不知道該選擇哪個發行版,那么鏡像大小就是最主要的參考,考慮到部署分發,容器當然是越小越好。 這里有一個參考: php:7.4.33-cli-alpine3.16(83.5MB) 比 7.4.33-cli-bullseye(474MB) 要小5倍(要看下載解壓到本地時的空間占用),但卻提供了常用的命令 vi curl nc 等,簡直是專門為容器而生的版本啊。 ---- ### 理解 Dockerfile **Dockerfile 是操作記錄** Dockerfile 的本質是一個包含創建鏡像時的每一行命令記錄的文件。有了操作記錄,那么鏡像的創建過程就不再是一個黑盒了。 如此設計的更重要的意義還在于由于操作記錄是固定的,那么這個過程就是可重現的,這是 docker 一次構建多處運行的基礎,也是 docker 受歡迎的主要原因。 當鏡像被其它鏡像所依賴時,只需要在構建好成品 ———— 鏡像本體上接著操作就行了,而不必再重復執行構建過程,如果想知道所依賴鏡像構成細節,查看其 Dockerfile 文件就行了,因為這一切都是透明的,所以大家相互共享鏡像就沒有信任的問題了。 > 需要注意的是: ENTRYPOINT CMD 為運行容器時默認的主進程啟動命令,只會在運行容器時執行,構建鏡像時不會執行,如果被作為依賴鏡像時,也不會執行,而是執行當前啟動鏡像的命令。但如果當前容器鏡像沒有 CMD 或 ENTRYPOINT 指令,那么就會執行其依賴鏡像的啟動命令。(若在當前層重寫了上層的 ENTRYPOINT, 那么 CMD 也必須重寫,否則不會繼承過來,換句話說 每層的 ENTRYPOINT CMD 是相互成對的 ) 多層鏡像依賴其實是多個鏡像層而已,而 對于命令 ENTRYPOINT CMD, 后層的命令會覆蓋前一層的命令。 > 注意 如果有 sh 腳本,一定要檢查行尾是否為 Unix ,否則構建時可能出現意外的失敗。(Sublime Text: 查看 > 行尾 > Unix) ---- **Dockerfile 每一行命令都是一個層** 鏡像并非是一個像 ISO 那樣的打包文件,鏡像只是一個虛擬的概念,其實際體現并非由一個文件組成,而是由一組文件系統組成,或者說,由多層文件系統聯合組成。 所以寫每一行時需要考慮緩存的問題。 ---- **如何理解 FROM** Dockerfile 從 FROM 開始,表示 從一個環境開始,后面的 上下文語境即都是已進入到這個環境下了。 FROM 是進入環境的入口,這個入口可以是 一個 OS 發行版,也可以是 scratch 空白的鏡像。 即 FROM 后的所有命令都是在其源環境內了,所以每一行操作都會直接影響構建環境,即影響最終構建的鏡像。 ---- ### 構建最快的鏡像: 多階段構建 多階段構建 只是將 原本需要創建多個 Dockerfile 的構建項目,如 從前一個鏡像中復制文件到后一層鏡像中 等過程簡化了,將其合并成一個 Dockerfile 文件,方便構建操作而已,本質上還是要構建多個鏡像。 多階段的每一階段都從 FROM 開始,最終的 鏡像 只會從 最后一個階段構建,不會包含前面階段產生的層,因此可以減少鏡像的體積。 就像預制菜可以直接由半成品加熱就可以吃,而不用買菜洗菜的環節。 ---- ### 鏡像 通常我們所說的鏡像具體是指某個軟件倉庫的某個版本,即 `倉庫名:tag` ,如 `ubuntu:18.04` , `xiaobu191/php:7.4.33-cli` **Tag** 通常,一個倉庫會包含同一個軟件不同版本的鏡像,而標簽就常用于對應該軟件的各個版本。我們可以通過 `<倉庫名>:<標簽>`的格式來指定具體是這個軟件哪個版本的鏡像。如果不給出標簽,將以 `latest` 作為默認標簽。 **OS/ARCH** 一個 tag標簽 對應 一個鏡像,一個鏡像 可對應多個不同 OS/ARCH (操作系統/硬件結構), 每個都有一個唯一的 DIGEST 值(sha256 摘要),即每個鏡像在特定平臺下都有一個鏡像文件。 **IMAGE ID** 同一鏡像(同一軟件、倉庫)的 不同 Tag 版本 的鏡像ID 是相同的,因為它們對應的是同一個鏡像。 鏡像的 唯一標識 除了 鏡像ID 還有 鏡像摘要,其實 也是 `鏡像:tag:OS/ARCH` 的摘要。 他們的關系如下: ~~~ 鏡像 ubuntu 97ba4bbc97fc tag1 ubuntu:18.04 x86 DIGEST:sha256:2852f36559cee4a83bf2a5102d91bde01826c2516fb9e78f3981775acf381292 arm64 ... tag2 x86 ... ... ~~~ ---- ### 運行容器 **容器只能包含一個“進程”?** 首先說明的是這個進程是打引號的,并不是指一個容器中只能運行一個進程。 在解釋這個問題之前先了解一下背景: 宿主系統的 1號進程 是所有進程的父進程,通常是 `/usr/lib/systemd/systemd`,這個父進程會托管照管所有進程(詳細可了解 孤兒進程和僵尸進程的相關知識), 在 docker 中 查看 1號進程會發現它就是我們的 容器入口程序,這個 1號進程 就是我們的容器進程, docker 通過判斷這個進程的狀態來判斷容器是否啟動。 此外這個進程需要承擔 托管其它進程的責任,所以說容器只能包含一個“進程”指的是容器內只能有一個這樣的1號進程,如 nginx 、workerman 這種 master/worker 的進程模型。 如果我們的容器是由多個獨立的進程,不是這種進程模型怎么辦?也是有辦法的,可以使用 supervisor , pm2 這類工具管理進程,如把 pm2 當成 容器入口程序就行了,否則的話 docker 容器將無法按預期正常的管理進程。 > 對于容器而言,其啟動程序就是容器應用進程,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義,從而退出,其它輔助進程不是它需要關心的東西。 ~~~ $: docker run -it --rm ubuntu:18.04 bash # 上面的命令的進程模型為: /usr/lib/systemd/systemd /usr/sbin/sshd sshd -zsh docker run -it --rm ubuntu:18.04 bash # 容器中啟動的 1號進程 bash 的 進程架構: /usr/lib/systemd/systemd /usr/bin/containerd-shim-runc-v2 bash ~~~ ~~~shell $: docker run -it --rm ubuntu:18.04 bash ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 18504 2040 pts/0 Ss 05:56 0:00 bash root 16 0.0 0.0 34400 1508 pts/0 R+ 06:01 0:00 ps -aux ~~~ ~~~shell $: docker run --name webserver -d -p 8080:80 nginx $: docker exec -it webserver bash $: apt-get update $: apt-get install procps $: ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 9720 3528 ? Ss 05:46 0:00 nginx: master process nginx -g daemon off; nginx 29 0.0 0.0 10116 1772 ? S 05:46 0:00 nginx: worker process nginx 30 0.0 0.0 10116 2028 ? S 05:46 0:00 nginx: worker process nginx 31 0.0 0.0 10116 2024 ? S 05:46 0:00 nginx: worker process nginx 32 0.0 0.0 10116 1784 ? S 05:46 0:00 nginx: worker process root 33 0.0 0.0 4144 2184 pts/0 Ss 05:50 0:00 bash root 402 0.0 0.0 6740 1480 pts/0 R+ 06:01 0:00 ps -aux ~~~ 宿主機上 ~~~shell $: ps -aux | grep bash root 5151 0.1 0.5 1027444 28332 pts/0 Sl+ 13:50 0:01 docker exec -it webserver bash root 5170 0.0 0.0 4144 2188 pts/0 Ss+ 13:50 0:00 bash $: ps -aux | grep nginx root 4852 0.0 0.0 9720 3528 ? Ss 13:46 0:00 nginx: master process nginx -g daemon off; 101 4908 0.0 0.0 10116 1772 ? S 13:46 0:00 nginx: worker process 101 4909 0.0 0.0 10116 2028 ? S 13:46 0:00 nginx: worker process 101 4910 0.0 0.0 10116 2024 ? S 13:46 0:00 nginx: worker process 101 4911 0.0 0.0 10116 1784 ? S 13:46 0:00 nginx: worker process root 5869 0.0 0.0 112824 1004 pts/1 S+ 14:07 0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox ngin $: ps 4831 PID TTY STAT TIME COMMAND 4831 ? Sl 0:02 /usr/bin/containerd-shim-runc-v2 -namespace moby -id fe0efd3de7c27588db1ec86d31aaebd6075d10059ff8652d877de94e2897060b -address /run/containerd/containerd.sock ~~~ 1. 容器里面的 nginx: master 和 進入的 bash pid 都是0 2. 他們對應宿主上的 pid 為:1 => 4852, 33 => 5170 3. 容器內的 主進程 不需要被托管(畢竟容器內的進程是虛擬的) 需要注意的是,這里的 nginx 是在 docker-entrypoint.sh 入口點程序中使用 exec 啟動 `nginx -g daemon off;` 命令的, 因為 `exec` 命令會 替代當前進程(這里的 sh 進程),所以 nginx 的父進程不是 sh 進程(它直接取待了 啟動它的sh),而其自身也就成了主進程作為容器內的 1號進程。 **容器主進程退出后其它進程會怎么樣?** 待實驗,猜測:容器是為主進程而存在的,如果主進程退出,此時容器中還有其它進程,那么會被 dockerd 強制 kill 掉。 ---- ### 數據卷 數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性: - 數據卷是宿主主機中的目錄,掛載點為容器內目錄 - 數據卷可以在容器間共享和重用 - 對數據卷的修改會立即生效 - 對數據卷的更新,不會影響鏡像 - 數據卷是被設計用來持久化數據的,它的生命周期獨立于容器 - 數據卷默認會一直存在,即使容器被刪除 - 數據卷的使用,類似于 Linux 下對目錄或文件進行掛載(mount) - 鏡像中被指定為掛載點的目錄中的文件會復制到數據卷中(僅數據卷為空時會復制) ~~~ 掛載細節: 1. docker run --rm -it -v /yf_api/php.ini:/usr/local/etc/php/php.ini xiaobu191/yf_api sh -v 無法將容器內的文件/目錄暴露出來,只能是宿主覆蓋到容器中(宿主 => 容器),并且宿主上文件必須存在(否則會失敗,并在宿主上生成一個目錄而不是文件) 2. 可以將容器內的目錄復制暴露到數據卷中(非宿主自定義目錄),僅數據卷為空時,否則卷目錄會覆蓋容器中的目錄 3. 所以如果想將容器內文件暴露出來,只能 docker cp <容器ID或名稱>:/path/to/container/file /path/to/host/ ~~~ **VOLUME** ``` # 1. Dockerfile 中指定目錄 掛載為 匿名卷 VOLUME /data ``` Docker 容器原則上是臨時、無狀態的,不應該在容器內(容器存儲層)寫入大量數據,為了防止其在容器存儲層寫入數據, 可以用 VOLUME 命令 事先指定容器內某些目錄掛載為 匿名卷(容器外): /var/lib/docker/volumes/4f2d4...d27652/_data ,這樣容器運行時數據就保存外部 匿名卷的位置了,容器停止并銷毀時數據也不會丟失。 如果不使用卷和掛載,那么默認容器運行時數據會寫入到容器存儲層: /var/lib/docker/overlay2/d7d2...182/ diff merged work 容器日志 /var/lib/docker/containers/容器id/容器id-json.log (docker inspect --format='{{.LogPath}}' 容器id or 容器名) ```shell # 創建命名卷 # /var/lib/docker/volumes/mydata/_data docker volume create mydata # 2. 容器運行時 指定目錄掛載為 命名卷 docker run -d -v mydata:/data xxxx # 3. 容器運行時 指定容器內目錄掛載為主機目錄 docker run -d -v /data:/data xxxx ``` ~~~ $: docker volume $: docker volume inspect mydata [ { "CreatedAt": "2023-06-04T09:40:50+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/mydata/_data", "Name": "mydata", "Options": {}, "Scope": "local" } ] ~~~ ~~~ $: docker run --rm -it --name php -v mydata:/data xiaobu191/php-7.4.33-cli sh $: docker inspect php ... "Mounts": [ { "Type": "volume", "Name": "mydata", "Source": "/var/lib/docker/volumes/mydata/_data", "Destination": "/data", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" } ], ... ~~~ ~~~ ... $: docker run --rm -it --name php -v /mnt/web:/web xiaobu191/php-7.4.33-cli sh $: docker inspect php "Mounts": [ { "Type": "bind", "Source": "/mnt/web", "Destination": "/web", "Mode": "", "RW": true, "Propagation": "rprivate" } ], ... ~~~ ~~~ $: docker run --rm -it --name php --mount type=bind,source=/mnt/web,target=/web xiaobu191/php-7.4.33-cli sh $: docker inspect php ... "Mounts": [ { "Type": "bind", "Source": "/mnt/web", "Destination": "/web", "Mode": "", "RW": true, "Propagation": "rprivate" } ], ... ~~~ ~~~ $: docker run --rm -it --name php --mount type=tmpfs,target=/web xiaobu191/php-7.4.33-cli sh $: docker inspect php "Mounts": [ { "Type": "tmpfs", "Source": "", "Destination": "/web", "Mode": "", "RW": true, "Propagation": "" } ], ~~~ 也可以在啟動容器時 通過 `-v` 參數指定 命名卷 或 目錄 掛載到 容器內的目錄上。 將容器外的 目錄 直接映射到 容器內的目錄上 常用于宿主與容器共享文件 或 測試,如放置一些文件到本地,映射到容器中看是否正常工作 而使用 卷 常用于規范容器運行時數據保存。 **`--mount` 與 `-v` 的去區別?** 1. 都是主機目錄掛載到容器內的目錄,只是掛載類型不同: `--mount`: Mounts.Type: bind `-v`: Mounts.Type: volume --mount 更靈活,可以指定掛載類型: bind, volume, tmpfs 2. `-v` 本地目錄不存在 Docker 會自動為你創建一個文件夾, `--mount` 本地目錄不存在,Docker 會報錯。 https://vuepress.mirror.docker-practice.com/data_management/bind-mounts/#查看數據卷的具體信息 https://blog.csdn.net/gongdiwudu/article/details/128756465 ~~~ 掛載細節(重要): - 本地目錄/文件(或卷) 掛載到 容器中,本地優先、卷優先,原則上 容器是臨時的 - 如果 本地有(或卷),那么就會 映射、覆蓋到容器中,并可選 容器內 對其 是否可寫 - 如果 本地沒有(或卷),容器內有,那么 會將容器中的文件 復制到 本地 - 如果 都沒有,那么雙方寫入都相互可見 ~~~ ... ---- ### 容器空間占用 [如何清理 docker 磁盤空間 附講解(全)_docker 清理_碼農研究僧的博客-CSDN博客](https://blog.csdn.net/weixin_47872288/article/details/128244770) https://www.codetd.com/article/14982610 https://tool.4xseo.com/a/11941.html ```shell $: docker system df $: docker system df -v # 清除沒有被容器使用的鏡像 $: docker image prune -af # 清除未被使用的 volume 等 $: docker system prune -f $: docker system prune -a # 容器鏡像、運行時目錄 merged 、 diff 、 work /var/lib/docker/overlay2 /var/lib/docker/overlay2/7078...f12/diff/root/.pm2 # 容器日志目錄 容器id/容器id-json.log /var/lib/docker/containers # k8s 日志 /var/log/containers /var/log/pods # 匿名卷、命名卷 /var/lib/docker/volumes ``` https://blog.csdn.net/czf19950601/article/details/125064452 ```shell $: vi /etc/docker/daemon.json { "log-driver": "json-file", "log-opts": { "max-size": "256m", "max-file": "12", "compress": "true" } } $: sudo systemctl daemon-reload $: sudo systemctl restart docker.service $: docker inspect yf-web-phpfpm $: docker inspect -f {{.HostConfig.LogConfig}} yf-web-phpfpm $: docker info --format '{{.LoggingDriver}}' ``` https://blog.51cto.com/u_14035463/5583658 ---- **workerman 日志問題** pm2 就不需要記錄日志了,因為 workerman 自己已經記錄到文件了,不然會記錄三份(容器輸出日志、/root/.pm2/logs、workerman 日志) ~~~ 1. 前臺時,不允許設置 STDOUT 2. 前臺時,log() 同時會輸出到 STDOUT 我們是后臺設置了 STDOUT 為 logFile,所以 不滿足 2 ,不會寫兩次到日志文件 如果是前臺,那么又設置不了 STDOUT, 2 同時輸入到 STDOUT ,會寫到終端輸出和 docker log ,也不會 寫兩次 日志文件 所以不論是前后還是后臺,都不會出現寫兩次 workerman 日志文件的情況。 ~~~ ---- ### 容器網絡 **容器互聯** Docker 允許通過 外部訪問容器 或 容器互聯 的方式來提供網絡服務。 ```shell $: cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 266aca625bb7 $: ping 266aca625bb7 PING 266aca625bb7 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.183 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.093 m ``` 可以看到 docker 在容器啟動后自動其創建了一個 主機名(通過自動修改 hosts),名稱為當前的容器名稱或容器id,這樣在同一容器網絡下的容器間可以通過容器名作為 主機名/服務名 來相互訪問了。(容器把自己的名稱寫到自己的 hosts 中,而 docker 底層把加入到同一網絡的容器做了特殊處理,使其 hosts “相互融合了”) 1. 創建 Docker 網絡 ```shell $: docker network create -d bridge my-net $: docker network ls ``` 2. 連接到 Docker 網絡 ``` $: docker run --rm -it --name php --network my-net xiaobu191/php-7.4.33-cli sh $: docker run --rm -it --name php2 --network my-net xiaobu191/php-7.4.33-cli sh $: docker run --rm -it --name php3 xiaobu191/php-7.4.33-cli sh ``` 在上面兩個容器終端里相互 `ping php` 或 `ping 31851287fcc8` (對方的容器名或容器id) 都能成功解析到虛擬ip地址,而在第三個終端里 `ping` 不通其它容器名稱和容器id,并且自身也不能被其它容器 `ping` 通,這證明了加入到 Docker 網絡 的容器可以實現互聯。 > 需要注意的是,容器互聯的端口是一個容器直接連另一個容器的內部端口 **外部訪問容器** ~~~ # -P 標記時,Docker 會隨機映射一個端口到內部容器開放的網絡端口(如 EXPOSE 80) -P -p 容器外部:容器內部 ~~~ 1. 映射所有ip地址 使用 hostPort:containerPort 格式本地的 80 端口映射到容器的 80 端口: ```shell $: docker run -d -p 80:80 nginx:alpine ``` 這也是用的最多的方式,`-p` 標記也可以多次使用來綁定多個端口。 2. 映射指定ip地址的指定端口 可以使用 ip:hostPort:containerPort 格式指定映射使用一個特定地址,比如 localhost 地址 127.0.0.1 ```shell $: docker run -d -p 127.0.0.1:80:80 nginx:alpine ``` 3. 映射指定ip地址的隨機端口 使用 ip::containerPort 綁定 localhost 的任意端口到容器的 80 端口,本地主機會自動分配一個端口。 ```shell $: docker run -d -p 127.0.0.1::80 nginx:alpine ``` ```shell # 還可以使用 udp 標記來指定 udp 端口 $: docker run -d -p 127.0.0.1:80:80/udp nginx:alpine # 查看映射端口配置 $: docker port 容器id 80 0.0.0.0:32768 ``` **為容器配置 DNS** DNS 服務器 用來 解析不在 /etc/hosts 中的主機名,所以 hosts 文件可以用于配置跳過 DNS 服務器解析而 直接指向的IP 的 地址名(域名或主機地址)。 https://vuepress.mirror.docker-practice.com/network/dns/ ```shell cat /etc/hosts (host 文件) cat /etc/hostname (主機名) ``` ```shell $: cat /etc/resolv.conf (DNS) # Generated by NetworkManager nameserver 114.114.114.114 nameserver 8.8.8.8 nameserver 1.1.1.1 ``` 目前發現沒加入 Docker 網絡 的容器反而自動繼承了宿主機的 DNS 配置了,而加入了 Docker 網絡 的容器呢則沒有宿主機的 DNS 了: ``` $: cat etc/resolv.conf nameserver 127.0.0.11 options ndots:0 ``` 還可以通過 `-h HOSTNAME` 或者 `--hostname=HOSTNAME` 設定容器的主機名,也可以通過 `--dns=IP_ADDRESS` 設置容器的 DNS 服務器 ---- ### 高級網絡配置 ---- ### 容器組 Compose Docker Compose 允許用戶通過一個單獨的 docker-compose.yml 模板文件來定義一組相關聯的應用容器為一個項目,這樣在生產中就能提高多容器部署的效率。 Compose 中有兩個重要的概念: 服務 (service):一個應用的容器,實際上可以包括若干運行相同鏡像的容器實例(多個相同應用節點)。 項目 (project):由一組關聯的應用容器組成的一個完整業務單元(多個服務),在 docker-compose.yml 文件中定義。 Compose 的默認管理對象是項目,通過子命令對項目中的一組容器進行便捷地生命周期管理。 ```yaml version: '3' services: phpfpm: image: "xiaobu191/php-7.4.33-fpm" ports: - "9000:9000" nginx: image: "xiaobu191/nginx" ports: - "80:80" ``` ```shell # 生產環境下可使用 -d 在后臺啟動 $: docker compose up [+] Running 3/3 ? Network compose_default Created 0.2s ? Container compose-nginx-1 Created 0.2s ? Container compose-phpfpm-1 Created 0.2s Attaching to compose-nginx-1, compose-phpfpm-1 compose-phpfpm-1 | [05-Jun-2023 07:47:55] NOTICE: fpm is running, pid 1 compose-phpfpm-1 | [05-Jun-2023 07:47:55] NOTICE: ready to handle connections compose-nginx-1 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration compose-nginx-1 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ compose-nginx-1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh compose-nginx-1 | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf compose-nginx-1 | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf compose-nginx-1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh compose-nginx-1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh compose-nginx-1 | /docker-entrypoint.sh: Configuration complete; ready for start up compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: using the "epoll" event method compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: nginx/1.25.0 compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r4) compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: OS: Linux 3.10.0-1160.76.1.el7.x86_64 compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: start worker processes compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: start worker process 30 compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: start worker process 31 compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: start worker process 32 compose-nginx-1 | 2023/06/05 07:47:55 [notice] 1#1: start worker process 33 ``` ~~~ 常用參數 -d 在后臺運行服務容器。 --no-color 不使用顏色來區分不同的服務的控制臺輸出。 --no-deps 不啟動服務所鏈接的容器。 --force-recreate 強制重新創建容器,不能與 --no-recreate 同時使用。 --no-recreate 如果容器已經存在了,則不重新創建,不能與 --force-recreate 同時使用。 --no-build 不自動構建缺失的服務鏡像。 -t, --timeout TIMEOUT 停止容器時候的超時(默認為 10 秒)。 ~~~ ``` $: docker compose top compose-nginx-1 UID PID PPID C STIME TTY TIME CMD root 3410 3376 0 15:47 ? 00:00:00 nginx: master process nginx -g daemon off; 101 3531 3410 0 15:47 ? 00:00:00 nginx: worker process 101 3532 3410 0 15:47 ? 00:00:00 nginx: worker process 101 3533 3410 0 15:47 ? 00:00:00 nginx: worker process 101 3534 3410 0 15:47 ? 00:00:00 nginx: worker process root 3786 3376 0 15:53 pts/0 00:00:00 sh compose-phpfpm-1 UID PID PPID C STIME TTY TIME CMD root 3399 3354 0 15:47 ? 00:00:00 php-fpm: master process (/usr/local/etc/php-fpm.conf) 82 3500 3399 0 15:47 ? 00:00:00 php-fpm: pool www 82 3501 3399 0 15:47 ? 00:00:00 php-fpm: pool www root 3829 3354 0 15:59 pts/0 00:00:00 sh ``` > 宿主上并沒有 82 www-data 這個用戶 ```shell $: docker compose ps $: docker network ls ``` 可以看到啟動了兩個容器 `compose-phpfpm-1`、`compose-nginx-1`,并默認創建了名為 `compose_default` 的 Docker 網絡,兩個容器也加入到了該網絡中。 進入兩個容器后能通過 容器id 或 容器名 或 服務名 相互 `ping` 通對方: ```shell $: ping compose-nginx-1 $: ping nginx $: nc -z -w 1 compose-nginx-1 80 && echo 1 1 $: nc -z -w 1 nginx 80 && echo 1 1 ``` ```shell $: nc -z -w 1 compose-phpfpm-1 9000 && echo 1 1 ``` 不過要注意的時,兩個容器是相互獨立的,nginx 中并不能 `nc` 通 `127.0.0.1 9000`,所以配置文件中 `fastcgi_pass phpfpm:9000` 應該使用服務名。 ```shell # 通過服務名暫停 (不同于 stop ,進程并沒有停止,nc 端口也是通的,但是 curl 不響應了) # 它利用了cgroups的特性將運行中的進程空間暫停 https://cloud.tencent.com/developer/article/2108558 $: docker compose pause nginx # 恢復處于暫停狀態中的服務 $: docker compose unpause nginx ``` ---- ### 用戶權限相關 ``` # 查看所有用戶信息 $: cat /etc/passwd # 查看某個用戶詳細 $: id www-data uid=82(www-data) gid=82(www-data) groups=82(www-data),82(www-data) # 查看所有用戶 $: compgen -u ``` ``` # https://github.com/docker-library/php/blob/b9f17156020c3aef71df681b27684533529347a7/7.4/alpine3.16/fpm/Dockerfile#L33 $: adduser -u 82 -D -S -G www-data www-data $: chown www-data:www-data /var/www/html $: chmod 777 -R /var/www/html ``` ---- ### 容器健康檢查 與 信號處理 ```shell # https://vuepress.mirror.docker-practice.com/compose/commands/#kill $: docker compose kill -s SIGINT ``` ~~~ # https://vuepress.mirror.docker-practice.com/image/dockerfile/healthcheck/ HEALTHCHECK --interval=5s --timeout=3s \ CMD curl -fs http://localhost/ || exit 1 ~~~ ~~~ # https://github.com/docker-library/php/blob/b9f17156020c3aef71df681b27684533529347a7/7.4/alpine3.16/fpm/Dockerfile#L255 STOPSIGNAL SIGQUIT ~~~ ---- ### 應用 docker 化改造 EXPOSE 80 9390 # 先指定目錄掛在為匿名卷 VOLUME /home/myweb/apps_share_data # 創建命名卷 docker volume apps_share_data /home/myweb/apps_share_data # 將命名卷掛載到某個目錄,替代 Dockerfile 中定義的匿名卷的掛在位置 run ... -v apps_share_data:/home/myweb/apps_share_data service: nginx: 80:80 admin.yf5g.cn admin.api.yf5g.cn admin.test.yf5g.cn admin.api.test.yf5g.cn php-fpm: 9000:9000 vue: php-cli: workerman gatewayworker php-fpm vue 需要把 源碼 暴露給 nginx 的 root 配置使用,如何做到?用 VOLUME 卷嗎? https://www.imooc.com/wenda/detail/399719 docker build -t xiaobu191/laravel --target=yf_api . docker build -t xiaobu191/nginx --target=nginx . $: docker network create yf_api $: docker run -dit --rm --name=yf_api --network=yf_api xiaobu191/yf_api $: docker run -dit --rm --name=nginx --network=yf_api -p 8080:80 xiaobu191/nginx ---- 目前 yf 服務器上的 /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf --pid /usr/local/php/var/run/php-fpm.pid /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf -g 'daemon off;' ---- 標準 php-fpm nginx -g 'daemon off;' 配置全部都用了默認配置,我們可能需要根據情況在 入口點 腳本中進行 調整,可參考 https://github.com/docker-library/php/blob/b9f17156020c3aef71df681b27684533529347a7/7.4/bullseye/fpm/Dockerfile https://github.com/nginxinc/docker-nginx/blob/3591b5e431af710432bd4852d9ee26eb19992776/mainline/debian/Dockerfile ---- /usr/local/nginx/sbin/nginx -V /usr/local/php/sbin/php-fpm --version 服務管理 ls /etc/rc.d/init.d -ls vi /etc/rc.d/init.d/nginx vi /etc/rc.d/init.d/php-fpm vi /etc/rc.d/init.d/yf-autostart.sh service nginx reload systemctl reload php-fpm.service ls /etc/systemd/system/ -ls systemctl start filebeat ---- ### 多前端應用部署方案 1. 共用一個 nginx 容器 2. 每個前端應用提供自己的 虛擬主機配置文件 3. 應用 的 靜態文件 和 配置文件 在 nginx 啟動時就掛在進去 > 在一個節點上盡量不啟動多個 nginx 容器,前端項目部署應盡可能簡單,甚至根本用不著容器。 ``` $: docker run --name=static-app -v nginx-conf:/etc/nginx/conf.d static-app $: docker create --name=static-app -v /root/conf.d:/etc/nginx/conf.d static-app ``` ``` # 先嘗試采用通過宿主的卷以共享文件的方式(不可行) $: docker volume create apps $: docker volume create nginx-conf $: ls /var/lib/docker/volumes/apps/_data -ls $: ls /var/lib/docker/volumes/nginx-conf/_data -ls $: docker run --rm -it --name phpfpm --network phpfpm-network xiaobu191/php-api # 可以看到 php-api-nginx 鏡像中的 /etc/nginx/conf.d 目錄被復制到了 nginx-conf 卷中 $: docker run --rm -it --name nginx -v nginx-conf:/etc/nginx/conf.d -v apps:/home/myweb/apps --network phpfpm-network xiaobu191/php-api-nginx # 現在我們只需要 將其它 應用 靜態文件 也這樣復制到 apps 卷中就行了,這樣 nginx 容器中就有這些配置了 # 將 容器內的 虛機配置 復制到 nginx-conf 卷中 # 將 容器內的 靜態文件 復制到 apps 卷中 $: docker run \ -v nginx-conf:/home/myweb/apps/static/static.conf \ -v apps:/home/myweb/apps/ \ xiaobu191/static-app ``` ``` # Host 的數據復制到容器內部(這可能是前端項目部署最可行的方案) $: docker cp static-app/admin.yf5g.cn.conf php-api-nginx:/etc/nginx/conf.d/ $: docker cp static-app/public php-api-nginx:/home/myweb/apps/static-app # nginx 進程重載 $: docker kill -s SIGHUP nginx $: kill -HUP `docker inspect -f '{{.State.Pid}}' nginx || echo -n "nginx can't reload" ``` ```shell $: docker run -d \ --name php-api-nginx \ -p 80:80 \ --network phpfpm-network \ # 當需要替換容器內配置時 # -v /path-on-host-machine/nginx.conf:/etc/nginx.conf \ # -v /path-on-host-machine/admin.api.yf5g.cn.conf:/etc/nginx/conf.d/ \ xiaobu191/php-api-nginx ``` https://www.imooc.com/wenda/detail/399719 https://blog.csdn.net/IT_ZRS/article/details/126763116 ~~~ 鏡像、容器中的文件拷貝出來 https://vuepress.mirror.docker-practice.com/image/multistage-builds/#分散到多個-dockerfile docker build -t go/helloworld:build . -f Dockerfile.build docker create --name extract go/helloworld:build docker cp extract:/go/src/github.com/go/helloworld/app ./app docker rm -f extract ~~~ ~~~ 還有一種辦法, 前端 入口 sh 就是 將 容器內靜態文件 掛載到 卷,并將 配置也掛載到卷,然后 向 nginx 容器 發送重載信號就行了 行不通,因為 容器的入口程序在容器內,無法操作宿主的其它容器。 ~~~ ---- ### 備份和恢復容器數據 **備份 MongoDB 數據演示** 1. 容器數據保存到 mongo-data 數據卷 中 ```shell $: docker run -p 27018:27017 --name mongo -v mongo-data:/data -d mongo:4.4 ``` 2. 用另一個 Ubuntu 容器來將數據備份出來 a. 運行一個 Ubuntu 的容器,掛載 要備份的容器的所有 volume b. 映射宿主機的 backup 目錄到容器里面的 /backup 目錄 c. 將卷中要備份的數據 壓縮打包 ```shell $: docker run --rm --volumes-from mongo -v d:/backup:/backup ubuntu tar cvf /backup/backup.tar /data/ ``` 最后你就可以拿著這個 backup.tar 文件去其他地方導入了。 **恢復 Volume 數據演示** 運行一個 ubuntu 容器,掛載 要備份的 容器的所有 volumes,然后讀取 /backup 目錄中的備份文件,解壓到 /data/ 目錄 ```shell $: docker run --rm --volumes-from mongo -v d:/backup:/backup ubuntu bash -c "cd /data/ && tar xvf /backup/backup.tar --strip 1" ``` https://docker.easydoc.net/doc/81170005/cCewZWoN/XQEqNjiu 其實備份容器數據不用這么麻煩,直接進入容器打包,或者 在宿主機上操作備份 /var/lib/docker/volumes/mongo-data/_data 卷數據也可以。 ---- ### 阿里云私有 Docker Registry 倉庫 [容器鏡像服務 ACR - 阿里云](https://cr.console.aliyun.com/cn-hangzhou/instance/dashboard) ~~~ 公網: registry.cn-hangzhou.aliyuncs.com 內網: registry-internal.cn-hangzhou.aliyuncs.com 訪問憑證 password: ****** ~~~ 使用方法: **登錄** ```shell $: docker login registry.cn-hangzhou.aliyuncs.com --username=811800545@qq.com # 輸入 訪問憑證 # auths info: cat /root/.docker/config.json ``` **推送和拉取鏡像** ```shell $: docker tag xiaobu191/php-api registry.cn-hangzhou.aliyuncs.com/yf5g/php-api $: docker push registry.cn-hangzhou.aliyuncs.com/yf5g/php-api $: docker pull registry.cn-hangzhou.aliyuncs.com/yf5g/php-api ``` 免費版本限額: - 全球地域下倉庫默認限額為 300,請遷移至企業版獲取更高配額 - 全球地域下命名空間默認限額為 3,請遷移企業版獲取更高配額 - [什么是容器鏡像服務ACR](https://help.aliyun.com/document_detail/257112.html?spm=5176.8351553.help.dexternal.421c1991CHGvZp) [阿里云Docker倉庫_imonkeyi的博客-CSDN博客](https://blog.csdn.net/imonkeyi/article/details/120557675) ---- ### 相關資源 https://github.com/khs1994-docker/laravel-demo/blob/master/Dockerfile https://github.com/mlocati/docker-php-extension-installer **php-cli:** docker pull php:7.4.33-cli-alpine3.16 https://hub.docker.com/layers/library/php/7.4.33-cli-alpine3.16/images/sha256-1e1b3bb4ee1bcb039f559adb9a3fae391c87205ba239b619cdc239b78b7f2557?context=explore https://github.com/docker-library/php/blob/b9f17156020c3aef71df681b27684533529347a7/7.4/alpine3.16/cli/Dockerfile **php-fpm:** docker pull php:7.4.33-fpm-alpine3.16 https://hub.docker.com/layers/library/php/7.4.33-fpm-alpine3.16/images/sha256-4ca7fd8bea83cb12e43d192531576ca9a6b6a2d995763d3aaaee34f0d643f206?context=explore https://github.com/docker-library/php/blob/b9f17156020c3aef71df681b27684533529347a7/7.4/alpine3.16/fpm/Dockerfile **nginx:** docker pull nginx:1.25.0-alpine3.17 https://hub.docker.com/layers/library/nginx/1.25.0-alpine3.17/images/sha256-0b0af14a00ea0e4fd9b09e77d2b89b71b5c5a97f9aa073553f355415bc34ae33?context=explore https://github.com/nginxinc/docker-nginx/blob/3591b5e431af710432bd4852d9ee26eb19992776/mainline/alpine-slim/Dockerfile https://github.com/nginxinc/docker-nginx/blob/123ef33694fccfefcb7db63251b21c0496537c76/mainline/alpine/Dockerfile ----
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看