首页 > 解决方案 > 为什么 Docker 不接受代码更改,尽管“修剪所有”、“不构建缓存”然后“强制重新创建”?

问题描述

我正在对接一个 django 应用程序(webapp)。但是,当我进行代码更改时,它们似乎不会在重建容器时反映出来。

我正在尝试测试是否可以点击“app”,但名称已更改为“newapp”。

测试用例.py

from django.test import TestCase
import requests

class TestServerUp(TestCase):

    def testhitendpoint(self):
        r = requests.get(host='app', port=1234)

        self.assertEquals(r.status_code, 200)

运行命令sudo docker exec -it webapp python manage.py test tests.testcase失败,因为主机应该是“newapp”

requests.exceptions.ConnectionError: HTTPConnectionPool(host='app', port=1234): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fd97d430550>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))

我将测试用例更改为:

from django.test import TestCase
import requests

class TestServerUp(TestCase):

    def testhitendpoint(self):
        r = requests.get(host='newapp', port=1234)

        self.assertEquals(r.status_code, 200)

我把容器放下: sudo docker-compose -f ./deploy/docker-compose.yaml down

我从 docker: 中删除容器 sudo docker system prune --all --volumes -f,然后 sudo docker rm -f $(sudo docker ps -aq)确定。

我重建容器: sudo docker-compose -f ./deploy/docker-compose.yaml build --no-cache

然后我旋转容器: sudo docker-compose -f ./deploy/docker-compose.yaml up --force-recreate -d

我再次运行测试:( sudo docker exec -it webapp python manage.py test tests.testcasesudo docker exec -it [container-id] python manage.py test tests.testcase

我得到完全相同的错误消息:

requests.exceptions.ConnectionError: HTTPConnectionPool(host='app', port=1234): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fd97d430550>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))

查看容器 ( sudo docker exec -it webapp /bin/bash) 并运行cat tests/testcase.py显示第一个测试用例 (host='app') 的原始代码,而不是修改后的 (host='newapp')。

部署/docker-compse.yaml

version: "3.0"

services:
  db:
    image: postgres
    container_name: postgres_db
    restart: always
    ports:
      - 5433:5432
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_DB=$POSTGRES_DB
      - POSTGRES_USER=$POSTGRES_USER
      - POSTGRES_PASSWORD=$POSTGRES_PASSWORD

  app:
    build: ../webapp
    container_name: webapp
    entrypoint: /entrypoint.sh
    ports:
      - 8000:8000
    volumes:
      - app_data:/webapp
    environment:
      - DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY
      - ENVIRONMENT=$ENVIRONMENT
      - POSTGRES_DB=$POSTGRES_DB
      - POSTGRES_USER=$POSTGRES_USER
      - POSTGRES_PASSWORD=$POSTGRES_PASSWORD
    depends_on:
      - db
 
volumes:
  postgres_data:
  app_data:

网络应用程序/Dockerfile

FROM python:3.8.7-buster
ENV PYTHONUNBUFFERED=1

WORKDIR /webapp
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV USE_DOCKER=true
# install dependencies
RUN pip install --upgrade pip &&\
    apt-get update &&\
    apt-get install -y libpq-dev python3-dev
COPY requirements.txt /webapp/
RUN pip install -r requirements.txt
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
COPY . /webapp/
RUN mkdir /webapp/staticfiles

webapp/entrypoint.sh

#!/bin/bash

# Collect static files
echo "Collect static files"
python manage.py collectstatic --noinput

# Apply database migrations
echo "Apply database migrations"
python manage.py migrate --noinput

# Start server
echo "Starting server"
gunicorn webapp.wsgi:application --bind 0.0.0.0:8000

我认为 docker 要么从我没有删除的缓存中提取,要么正在针对旧容器运行“docker exec -it”。

任何我可能忽略的建议将不胜感激!

标签: pythondjangodockerdocker-compose

解决方案


您的容器声明应将 Docker 命名卷挂载到您的应用程序树上:

volumes:
  - app_data:/webapp

完全删除此块。

这显然在您第一次运行时有效,因为当 Docker 创建一个新的命名卷并将其挂载到容器中时,第一次它只会将映像中的内容复制到卷中。但是,第二次运行容器时,卷的(旧)内容会替换(更新的)映像中的内容。没有办法让 Docker 自动更新卷内容,而无需手动将其复制到入口点脚本之类的东西中;完全删除音量更容易。


推荐阅读