Docker未持久化Postgres卷[django]

34 浏览
0 Comments

Docker未持久化Postgres卷[django]

这里有很多类似问题的提问,例如这个这个这个这个,它们非常相似,但是没有一个解决方案能解决我的问题。请不要关闭这个问题。

问题:

我在Docker上运行django、nginx和postgres。秘密信息存储在.env文件中。我的postgres数据在使用docker-compose up/startdocker-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 ,但这次只看到了超级用户,没有管理用户。

(说明:我在此处使用正斜杠来展示我在不同尝试中所尝试的不同命令组合。我尝试了这里显示的每种命令组合。)

0
0 Comments

问题的原因:在入口脚本中运行了"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卷的问题。

0
0 Comments

Docker不持久化Postgres卷[django]的原因是使用了Docker卷,而卷在容器删除时会被移除。为了解决这个问题,可以指定一个实际的磁盘路径来持久化数据,而不是使用卷。这样,容器的Postgres数据位置将被映射到您指定的路径上,数据将直接持久化在磁盘上,除非被有意删除。从安全角度来看,只要保护服务器的访问权限,使用这种方式与使用卷没有任何区别。如果攻击者能够访问您的服务器,他将能够读取数据库文件夹,就像他能够访问容器一样。因此,使用这种方式与使用卷的初始方法一样安全。感谢详细的回答,非常感谢。

0