Docker踩過的坑


前言

主要是記錄Docker遇到的坑,更多的是因為自己的粗心大意,以此警示

正文

Dockerfile里的RUN

某一次把啟動服務的命令寫在了 Dockerfile 中,后來發現服務一直拉不起來.
原來是把啟動命令寫在了 Dockerfile 的 RUN 里
Dockerfile 的 RUN 命令只有在打包時才會用到
Dockerfile 的 CMD 命令才是在鏡像啟動時執行,我們只需要將啟動命令放在 CMD 里即可
但是為了分開 (Dockerfile 只負責打包,執行由 Docker-compose ),我個人一般將啟動命令放在 Docker-compose 的 command 里

Docker 內部的服務不會更新

某一次寫了服務, 發現該服務有一個問題,修復后重新 go build 用 Docker 重新制作並測試
使用 Docker-compose 進行測試(docker-compose up ),只有編譯過后的二進制服務更新了, 其余沒更新
發現代碼在 Docker 里沒有更新(通過比對 md5 )
Dockerfile 文件如下

# 基礎系統鏡像
FROM debian:stable-slim

# 新建文件夾
RUN mkdir /root/gophish

# 設置工作目錄
WORKDIR /root/gophish

# COPY當前目錄所有文件到WORKDIR
COPY . .

# 設置執行權限並執行
RUN chmod +x gophish

# 注意:RUN后面的命令只有在構建鏡像時執行,CMD才是啟動時執行,也可以將啟動寫到DockerCompose中方便管理

原因是在多次 build 時, 基礎鏡像 stable-slim 里有上一次編譯的 gophish 二進制文件
也就是說, mkdir 並不會執行, WORKDIR也不會執行, 走到 COPY 時, Docker沒有檢測到二進制文件 gophish 更新了,
所以鏡像內部的 gohish 一直是老得版本
解決問題有多種方法, 比如把原來的鏡像刪除/COPY時不要一次全部COPY指定文件夾依次COPY等等,我是直接修改Dockerfile

# 基礎系統鏡像
FROM debian:stable-slim

# 新建文件夾, 防止Docker識別不出文件改動,在COPY前先刪除原有文件
RUN rm -rf /root/gophish/ && mkdir /root/gophish

# 設置工作目錄
WORKDIR /root/gophish

# COPY當前目錄所有文件到WORKDIR
COPY . .

# 設置執行權限並執行
RUN chmod +x gophish

# 注意:RUN后面的命令只有在構建鏡像時執行,CMD才是啟動時執行,也可以將啟動寫到DockerCompose中方便管理

COPY 的藝術

看到許多教程都建議 COPY . .
也就是將本地文件夾所有文件都 COPY 到 Docker 中
這種方式跟普通的一個文件夾一個文件夾的 COPY 相比, 雖然減少了幾行命令, 但是也有其缺點
就是會將所有文件都 COPY 比如 .git 文件夾等不需要 COPY 的文件夾和文件
比如

Docker-compose up 時代碼不會更新

如果在 docker-compose 中有

    image: xxx:1.0
    build: .

這代表image不存在時才會 build
如果存在老的版本你改動了代碼也不會重新build
解決方法是刪除 xxx 的image 或者運行 docker-compose build

docker-compose demo

version: "3"  # 指定語法版本


services:  # 定義service

  db:  # 定義名字叫db的service

    image: mysql:8  # 鏡像是mysql版本8(默認數據庫格式為utf8mb4)

    restart: always  # 出現問題重新啟動

    environment:  # 設置環境變量
      MYSQL_ROOT_PASSWORD: example  # root密碼
      MYSQL_DATABASE: gophish  # 設置數據庫名

    networks:  # 配置所屬網絡組
      - gophish_network

    expose:  # 開放該容器的端口給同個組
      - 3306  # 同一個network下的service可以通過 db:3306 訪問, 主機無法訪問

    volumes:
      - ./data:/var/lib/mysql  # 將Mysql數據掛載到宿主機


  gophish:

    image: gophish:1.0  # 與自己打包的Docker鏡像名字相同

    build: .  # 沒有找到鏡像就build所在目錄下的

    restart: always  # 出現問題重新啟動

    depends_on:  # 配置前置條件,
      - db  # db的service啟動后才啟動gophish

    networks:
      - gophish_network  # 所屬網絡組

    ports:  # 放開端口給主機的映射關系, 主機可直接訪問
      - 80:80  # 主機的80對應gophish的80
      - 3333:3333

    volumes:  # 掛載文件
      - ./config.json:/root/gophish/config.json  # 將compose同級的config.json與該server的/root/gophish/config.json同步,service目錄是絕對路徑

    command: /root/gophish/gophish  # 執行啟動鏡像

    #    network_mode: "host"  # 更改組網方式為host,默認的是橋接,分配一個虛擬ip,外部無法直接訪問, 不能和networks一起使用
    # host方式與宿主機綁定,端口共享,可能出現端口占用
    # https://www.jianshu.com/p/2d02bb9a9da5


networks:  # 設置網絡組讓多個service通訊

  gophish_network:  # 設置一個網絡組


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM