python - 为什么 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.testcase
或sudo 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”。
任何我可能忽略的建议将不胜感激!
解决方案
您的容器声明应将 Docker 命名卷挂载到您的应用程序树上:
volumes:
- app_data:/webapp
完全删除此块。
这显然在您第一次运行时有效,因为当 Docker 创建一个新的命名卷并将其挂载到容器中时,第一次它只会将映像中的内容复制到卷中。但是,第二次运行容器时,卷的(旧)内容会替换(更新的)映像中的内容。没有办法让 Docker 自动更新卷内容,而无需手动将其复制到入口点脚本之类的东西中;完全删除音量更容易。
推荐阅读
- bash - Grep 部分匹配(数字),对搜索字符串没有任何控制
- javascript - 从指令 Angular 加载 Mat 图标
- elasticsearch - filebeat 在将日志发送到 elasticsearch 时是否添加元数据?
- python - 提高循环速度
- kismet-wireless - Kismet API:仅卷曲设备名称和 MAC 地址?
- postgresql - 以 LEFT JOIN PostgreSQL 为条件
- hive - 将镶木地板文件从 Hive 复制到 Vertica 的时间戳问题
- javascript - 如何在 Express 中定义路由参数用冒号分隔的路由?
- json - 如何在序列化期间忽略类的受保护只读成员
- java - 我正在写一个字幕阅读应用程序。我希望它的运行方式与玩家的运行方式相似,但是我正在为时间安排而苦苦挣扎