我有多個服務需要使用相同的本地構建映像。
所以我創建了一個幫助服務來構建影像,所有其他服務都將依賴于構建器服務來確保首先構建影像。這里的 docker-compose.yml 只有 2 個服務,但實際上,我有大約 20 個服務。
version: "3.5"
services:
api:
image: test-image # using the image built below
networks:
- mylab
depends_on:
- tests-container-builder
volumes:
- ./tests:/tests
command: pytest -v -p no:cacheprovider /tests/api.py
license-chrome:
image: test-image
networks:
- mylab
depends_on:
- tests-container-builder
volumes:
- ./tests:/tests
command: sh -c "/tests/health-check-script.sh && pytest -v -p no:cacheprovider -n=1 /tests/license.py"
tests-container-builder:
build:
context: .
dockerfile: ./tests/Dockerfile
target: test-env
image: test-image # this service builds the image
但是當我使用構建和運行容器時
docker-compose up --build api; \
docker-compose up --scale license-chrome
我收到類似的錯誤
ERROR: for mylab_visual_ner-chrome_1 no such image: sha256:ceff9945d8722c89331696aa33d88f84703e322fbb64c1ebaa8f83c6e19a4cfa: No such image: sha256:ceff9945d8722c89331696aa33d88f84703e322fbb64c1ebaa8f83c6e19a4cfa
ERROR: for visual_ner-chrome no such image: sha256:ceff9945d8722c89331696aa33d88f84703e322fbb64c1ebaa8f83c6e19a4cfa: No such image: sha256:ceff9945d8722c89331696aa33d88f84703e322fbb64c1ebaa8f83c6e19a4cfa
ERROR: The image for the service you're trying to recreate has been removed. If you continue, volume data could be lost. Consider backing up your data before continuing.
Continue with the new image? [yN]
如果我洗掉test-container-builder服務并build在所有服務中使用命令,它作業正常。
使用不同的服務來構建鏡像是否被認為是一種反模式?這樣做的正確方法是什么?
uj5u.com熱心網友回復:
我認為絕對最佳實踐的 Compose 設定只包含長時間運行的容器,而不是您不希望實際運行的容器。在您的情況下,“構建器”容器實際上并沒有做任何事情,我不會將它包含在 Compose 設定中。相反,build:從相同的源代碼中獲取幾乎完全相同的影像幾乎是免費的;Docker 需要掃描構建背景關系來確定兩個鏡像是否相同,但最終你只會得到同一個物理鏡像的兩個不同名稱。
根據@TheFool 的建議使用 YAML 錨點來避免重復構建設定,我可能會寫:
version: '3.8'
services:
api:
build: &build-definition
context: .
dockerfile: ./tests/Dockerfile
target: test-env # (can you avoid this?)
command: pytest -v -p no:cacheprovider /tests/api.py
license-chrome:
build: *build-definition
# (does the health check belong in an ENTRYPOINT wrapper in the image?)
command: sh -c "/tests/health-check-script.sh && pytest -v -p no:cacheprovider -n=1 /tests/license.py"
我省略了不必要的networks:,因為 Compose 創建了一個以default您命名的完全可用的網路,并且volumes:,因為您的代碼通常應該內置到影像中。
如果您想顯式構建鏡像并將其包含在 Compose 設定中(也許您想將其推送到注冊表),那么您需要手動docker-compose build構建構建器鏡像,而不是您要運行的任何容器。Compose 設定看起來像
version: '3.8'
services:
api:
image: registry.example.com/my-name/test-image:${TAG:-latest}
command: pytest -v -p no:cacheprovider /tests/api.py
license-chrome:
image: registry.example.com/my-name/test-image:${TAG:-latest}
command: sh -c "/tests/health-check-script.sh && pytest -v -p no:cacheprovider -n=1 /tests/license.py"
tests-container-builder:
image: registry.example.com/my-name/test-image:${TAG:-latest}
build:
context: .
dockerfile: ./tests/Dockerfile
target: test-env
restart: "no"
command: exit 0
與我之前的 Compose 設定和您的問題相比,我明確指出容器應該立即退出而不是重新啟動,并且我使用了一個注冊表限定名稱。 depends_on:只影響容器開始啟動的順序,不包括對鏡像構建的任何依賴。
如果您使用此設定,您需要docker-compose build的建設者“容器”運行其余部分之前:
export TAG=20211124 # often useful to avoid ...:latest
docker-compose build test-container-builder # not "api"
# docker-compose push test-container-builder # if required
docker-compose up -d # could just launch specific containers
uj5u.com熱心網友回復:
這可能不是一個真正的答案,但我重新創建了您的場景,并且它出人意料地有效。如果您只想構建在配置中沒有構建鍵的容器,我確實希望它會失敗。
docker system prune -af # ensure we dont get confused with pre build images or chaching
docker-compose up --build two # try to run only service two
撰寫檔案:
version: "3.9"
volumes:
data: null
services:
one:
image: foo
build:
context: ./
dockerfile: Dockerfile
target: stage1
command: sh -c 'sleep 5 && echo "one done"'
two:
image: foo
command: sh -c 'sleep 5 && echo "two done"'
volumes:
- data:/stuff
- ./test:/test
depends_on:
- one
檔案
FROM busybox as stage1
RUN echo "Hello World"
FROM busybox
CMD sleep infinity
我得到的輸出如下。這可能是有道理的,因為在閱讀 --build 標志的定義時 Build images before starting containers.,聽起來有點像它并不關心您要啟動什么服務。它只是構建所有影像。
docker-compose up --build two
Creating network "test_default" with the default driver
Building one
[ ] Building 3.3s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 121B 0.0s
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/busybox:latest 2.3s
=> [stage1 1/2] FROM docker.io/library/busybox@sha256:b5cfd4befc119a590ca1a81d6bb0fa1fb19f1fbeb 0.4s
=> => resolve docker.io/library/busybox@sha256:b5cfd4befc119a590ca1a81d6bb0fa1fb19f1fbebd0397f2 0.0s
=> => sha256:b5cfd4befc119a590ca1a81d6bb0fa1fb19f1fbebd0397f25fae164abe1e8a6a 2.29kB / 2.29kB 0.0s
=> => sha256:50e44504ea4f19f141118a8a8868e6c5bb9856efa33f2183f5ccea7ac62aacc9 527B / 527B 0.0s
=> => sha256:ffe9d497c32414b1c5cdad8178a85602ee72453082da2463f1dede592ac7d5af 1.46kB / 1.46kB 0.0s
=> => sha256:3cb635b06aa273034d7080e0242e4b6628c59347d6ddefff019bfd82f45aa7 772.78kB / 772.78kB 0.3s
=> => extracting sha256:3cb635b06aa273034d7080e0242e4b6628c59347d6ddefff019bfd82f45aa7d5 0.1s
=> [stage1 2/2] RUN echo "Hello World" 0.4s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:81893d72f6be148599854469098e9f8c80a73e28acd5991a1757033440d34e5c 0.0s
=> => naming to docker.io/library/foo 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Creating test_one_1 ... done
Creating test_two_1 ... done
Attaching to test_two_1
two_1 | two done
test_two_1 exited with code 0
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/392468.html
