【问题标题】:Docker not persisting postgres volume [django]Docker 没有持久化 postgres 卷 [django]
【发布时间】:2019-08-12 19:47:11
【问题描述】:

这里有很多关于我遇到的类似问题的问题,例如this、this、this 和this,它们非常相似,但没有一个解决方案可以解决我的问题.请不要关闭此问题。

问题:

我在 docker 上使用 nginx 和 postgres 运行 django。秘密信息存储在 .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 <postgres_user> 以确保管理员用户在数据库中并找到它。

此时我继续运行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 <postgres_user>,但这次只看到超级用户,没有管理员用户。

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

【问题讨论】:

  • 您的入口点中有“python manage.py flush --no-input”。每次重新创建容器时,它都会运行并删除您的所有数据。如果这能解决您的问题,请告诉我,我会从中创建答案。
  • 而不是仅仅放置“postgres_data”,而是将主机的整个路径以“postgres_data”结尾
  • @Trent 解决了我的问题
  • @FelipeToledo 如果我理解正确,你是说我应该像@Bogsan 给出的答案那样创建一个本地路径?
  • @dot64dot - 添加我的评论作为答案。

标签: django postgresql docker docker-compose docker-volume


【解决方案1】:

问题是您在清除数据库的入口点脚本中运行“flush”。每当您启动或重新创建容器时,入口点都会运行。

【讨论】:

    【解决方案2】:

    获得持久数据的一种方法是指定磁盘上的实际路径,而不是创建卷:

    ...
      db:
        image: postgres:11.2-alpine
        volumes:
          - "/local/path/to/postgres/data:/var/lib/postgresql/data/"
    ...
    

    这样,容器的 postgres 数据位置会映射到您指定的路径。这样,除非有意删除,否则数据会直接保存在磁盘上。 据我所知,一个 docker 卷将在容器移除时被移除。

    【讨论】:

    • 这有什么安全隐患?如果我在服务器上启动我的系统是否意味着我会有额外的故障点?
    • 就我而言,只要对您的服务器的访问受到保护,这种方式或使用卷之间应该没有任何区别。有权访问您计算机的攻击者将能够读取数据库文件夹,因为他将获得对容器的访问权限。最重要的是,我认为这与使用卷的初始方法一样安全。
    • 感谢您的详细回复,非常感谢
    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多