Docker未持久化Postgres卷[django]
Docker未持久化Postgres卷[django]
这里有很多类似问题的提问,例如这个,这个,这个和这个,它们非常相似,但是没有一个解决方案能解决我的问题。请不要关闭这个问题。
问题:
我在Docker上运行django、nginx和postgres。秘密信息存储在.env文件中。我的postgres数据在使用docker-compose up/start
和docker-compose down/stop/restart
时无法持久化。
这是我的docker-compose
文件:
version: '3.7' services: web: build: ./app command: gunicorn umngane_project.wsgi:application --bind 0.0.0.0:8000 volumes: - ./app/:/usr/src/app/ expose: - 8000 environment: - SECRET_KEY=${SECRET} - SQL_ENGINE=django.db.backends.postgresql - SQL_DATABASE=postgres - SQL_USER=${POSTGRESQLUSER} - SQL_PASSWORD=${POSTGRESQLPASSWORD} - SQL_HOST=db - SQL_PORT=5432 - SU_NAME=${SU_NAME} - SU_EMAIL=${SU_EMAIL} - SU_PASSWORD=${SU_PASSWORD} depends_on: - db db: image: postgres:11.2-alpine volumes: - postgres_data:/var/lib/postgresql/data/ nginx: build: ./nginx volumes: - static_volume:/usr/src/app/assets ports: - 1337:80 depends_on: - web volumes: postgres_data: external: true # I tried running without this and the result is the same static_volume:
我的入口点脚本是这样的:
python manage.py flush --no-input python manage.py makemigrations python manage.py migrate python manage.py createsuperuser --user "${SU_NAME}" --email "${SU_EMAIL}" --password "${SU_PASSWORD}" python manage.py collectstatic --no-input exec "$@"
其中createsuperuser
是一个创建应用程序超级用户的自定义模块。
这个设置不能持久化postgres_data
中的信息。
附加信息:
在进行任何操作之前,我使用docker volume ls
检查是否存在名为postgres_data
的卷,结果是没有。
然后我运行docker-compose up -d
/docker-compose up -d --build
,一切都正常,没有错误。
我运行docker inspect postgres_data
,它显示"CreatedAt": "X1"
。
我能够登录超级用户。我继续创建管理用户,以超级用户身份注销,然后作为任何管理用户登录,没有任何问题。
我运行docker exec -it postgres_data psql -U
,确保管理用户在数据库中,结果是确实存在。
然后我运行docker-compose down
/docker-compose stop
,没有任何问题。我运行docker volume ls
,它显示postgres_data
仍然存在。
我运行docker inspect postgres_data
,它显示"CreatedAt": "X2"
。
为了测试一切是否按预期工作,我运行docker-compose up -d
/docker-compose up -d --build
/docker-compose start
/docker-compose restart
。
我运行docker inspect postgres_data
,它显示"CreatedAt": "X3"
。
然后我尝试以管理员用户登录,但无法登录。我再次运行docker exec -it postgres_data psql -U
,但这次只看到了超级用户,没有管理用户。
(说明:我在此处使用正斜杠来展示我在不同尝试中所尝试的不同命令组合。我尝试了这里显示的每种命令组合。)
问题的原因:在入口脚本中运行了"flush"命令,这会清空数据库。每当启动或重新创建容器时,入口脚本都会运行。
解决方法:删除入口脚本中的"flush"命令,以避免清空数据库。
以下是解决方法的代码示例:
# Dockerfile
# 选择基础镜像
FROM python:3.9
# 设置工作目录
WORKDIR /app
# 安装依赖
COPY requirements.txt .
RUN pip install -r requirements.txt
# 复制项目文件
COPY . .
# 删除入口脚本中的"flush"命令
RUN sed -i '/flush/d' entrypoint.sh
# 设置容器入口命令
ENTRYPOINT ["/app/entrypoint.sh"]
通过删除入口脚本中的"flush"命令,重新构建和运行容器,即可解决Docker不保留postgres卷的问题。