docker - 容器没有代码更改,图像有
问题描述
是的,这个问题之前已经发布过。是的,我已经应用了相关的解决方案并忽略了不相关的解决方案。我只是不明白这里发生了什么。
问题:我通过修改默认返回消息来更改我的源代码。我将 src 树复制到我的 baseImage 中(多阶段构建)。我从 baseImage 构建了一个 stagingImage。baseImage 有代码更改,但运行 stagingImage 的容器返回代码更改前消息。我已经在 MacOs (Catalina) 和 Amazon Linux 2 上复制了这种行为。
请注意,我是手动执行此操作的,即我不依赖 IDE 和 inotfy-s 等。唯一涉及的工具是 CLI、vim、make 和 docker(-compose)。
详细信息:我有一个能够进行多阶段构建的 Dockerfile。这是 baseImage 构建的相关部分:
COPY ./composer.json /var/www/html/composer.json
COPY ./php-apache/auth.json /root/.composer
COPY ./ /var/www/html
这是我如何构建其他图像的示例:
FROM php:7.4-apache AS cleanImage
COPY --from=baseImage / /
FROM cleanImage AS stagingImage
COPY ./.env.staging /var/www/html/.env
RUN /bin/bash -c 'rm -rf /var/lib/apt/lists/*'
# Set entrypoint
CMD ["-D", "FOREGROUND"]
ENTRYPOINT ["apachectl"]
我修改了“Docker In Action”第 10 章中的 Makefile。这是一个示例:
## image-base : Build the base image that the others are based on
.PHONY: image-base
image-base: metadata
@echo "Building Base Image"
docker image build --no-cache --force-rm --tag src:$(BUILD_ID)-base \
-f src/Dockerfile \
--target baseImage \
--build-arg BUILD_ID='$(BUILD_ID)' \
--build-arg BUILD_DATE='$(BUILD_TIME_RFC_3339)' \
--build-arg VCS_REF='$(VCS_REF)' \
./src
@echo "Built Base Image. BUILD_ID: $(BUILD_ID)"
## image-staging : Build the staging image
.PHONY: image-staging
image-staging: metadata image-base
@echo "Building Staging App Image"
docker image build -t src:$(BUILD_ID)-staging \
-f src/Dockerfile \
--target=stagingImage \
--build-arg BUILD_ID='$(BUILD_ID)' \
--build-arg BUILD_DATE='$(BUILD_TIME_RFC_3339)' \
--build-arg VCS_REF='$(VCS_REF)' \
./src
@echo "Built Staging App Image. BUILD_ID: $(BUILD_ID)-staging"
## up env=<env> : Bring up environments. env values are prod, local, staging.
.PHONY: up
up:
ifeq ($(strip $(BUILD_ID)),)
$(error BUILD_ID environment variable is not set. Run `make metadata` to generate one)
endif
docker-compose -f docker-compose.yml -f docker-$(env).yml up -d
其中 BUILD_ID 的格式为 YYYYMMDD-epoch-git_SHA。请注意,baseImage 使用 --no-cache 标志。
到目前为止,一切都很好(我认为)。
我的 docker-compose.yml 文件如下所示:
version: '3.7'
volumes:
web_app:
services:
php-apache:
logging:
driver: "json-file"
options:
max-file: "5"
max-size: "10m"
volumes:
- web_app:/var/www/html
env_file:
- ./src/.env.prod
我的docker-staging.yml
文件如下所示:
version: '3.7'
services:
php-apache:
image: 'src:20200924-174443-3f16358-staging'
container_name: perfboard-staging
ports:
- 8888:80
- 9261:443
env_file:
- ./src/.env.staging
是的,为了调试,我已经硬编码了 stagingImage 的名称。
我希望看到的内容:当我点击 localhost:8888 时,我希望看到我修改后的消息。我不。
检查 baseImage 时,修改后的消息就在那里。我无法直接检查 stagingImage,因为我不断收到 Apache 错误,大概是因为入口点。
如果我从系统中删除每个图像和容器,这将按预期运行。
删除上述特定的 baseIamge 和 stagingImage 并不能解决问题。
关于在哪里看的任何想法?
解决方案
您的docker-compose.yml
文件指定
volumes:
- web_app:/var/www/html
这会导致web_app
卷的内容被挂载到/var/www/html
容器中的目录上,隐藏最初在映像中的任何内容。
您应该删除此卷声明。
只有在第一次运行容器时,Docker 才会将镜像的内容复制到一个空的命名卷中。从那时起,它将卷视为用户数据并且永远不会对其进行任何更改;即使基础映像已更新,卷内容也不会更新,并且当您运行容器时,卷优先于更新后的映像代码。
依赖于“从映像复制到卷”行为存在许多实际问题(它不适用于主机绑定挂载;它不适用于 Kubernetes;它会导致映像更新被忽略),我会非常努力地避免在您的应用程序代码上安装任何类型的卷。
如果您认为出于其他原因拥有该卷很重要,则需要使 Compose 删除它,以便重新创建它并再次具有“仅限第一次”行为。 docker-compose down -v
将删除所有容器、网络和卷,但这也将包括您的数据库数据之类的内容。您可以使用docker-compose down
(不带-v
)停止容器,然后使用docker volume ls; docker volume rm dirname_web_app
手动删除卷。
推荐阅读
- javascript - JavaScript:每列生成表列
- npm - JFrog 私有注册表无法 npm 安装
- discord - webhook 和角色/权限概念的问题
- css - 反应中的可重用搜索组件-文本溢出时css失败
- r - PCA 分析:dim desc() 中出现错误:数据不方便
- meteor - 在 MeteorJS 中的表单上提交后路由到新 URL
- php - 在 Wordpress 中在一页上使用 PHP 更改永久链接
- java - 你怎么知道如何限制有多少客户端可以进入你的基本群聊应用服务器?(最多 10 个)
- hadoop - 由于输入字符串的 java.lang.NumberFormatException 导致 Apache Tez 作业失败:“30s”
- java - Java中的Chrome sqlite数据库Cookie过期转换