【问题标题】:run postgres container when using docker使用 docker 时运行 postgres 容器
【发布时间】:2019-07-31 14:38:11
【问题描述】:

我在 django 项目中使用了cookiecutter-django。我正在使用 docker 在本地运行项目。该项目运行良好。但是,我在使用 docker 时无法探索 postgres。

这是我运行项目所遵循的步骤

docker-compose -f local.yml build

docker-compose -f local.yml up -d

docker-compose run django python manage.py makemigrations

docker-compose run django python manage.py migrate

local.yml 如下所示

version: '3'

volumes:
  local_postgres_data: {}
  local_postgres_data_backups: {}

services:
  django: &django
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: travel_local_django
    depends_on:
      - postgres
      - mailhog
    volumes:
      - .:/app
    env_file:
      - ./.envs/.local/.django
      - ./.envs/.local/.postgres
    ports:
      - "8000:8000"
    command: /start

  postgres:
    build:
      context: .
      dockerfile: ./compose/production/postgres/Dockerfile
    image: travel_production_postgres
    volumes:
      - local_postgres_data:/var/lib/postgresql/data
      - local_postgres_data_backups:/backups
    env_file:
      - ./.envs/.local/.postgres


compose/production/postgres/Dockerfile

FROM postgres:11.3

COPY ./compose/production/postgres/maintenance /usr/local/bin/maintenance
RUN chmod +x /usr/local/bin/maintenance/*
RUN mv /usr/local/bin/maintenance/* /usr/local/bin \
    && rmdir /usr/local/bin/maintenance


.envs/.local/.postgres

# PostgreSQL
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=simplifytour
POSTGRES_USER=debug
POSTGRES_PASSWORD=debug

当我做docker-compose -f local.yml ps 时,我得到了与这个项目相关的容器。然后我使用命令docker exec -it travel_postgres_1 sh 执行了postgres 容器。在那里我尝试运行psqlpsql -U postgres 之类的命令,但对我没有任何帮助。我想探索 postgres,比如列出表、连接到数据库等。

我错过了任何步骤吗?我如何使用 postgres 容器?

【问题讨论】:

    标签: python django docker cookiecutter-django


    【解决方案1】:

    TL;DR

    如果您想访问容器化的 postgres 安装,您必须将端口映射添加到您的配置中:

      postgres:
        build:
          context: .
          dockerfile: ./compose/production/postgres/Dockerfile
        image: travel_production_postgres
        volumes:
          - local_postgres_data:/var/lib/postgresql/data
          - local_postgres_data_backups:/backups
        env_file:
          - ./.envs/.local/.postgres
        ports:
          - "5432:5432"
    

    注意最后两行是如何添加端口映射的。

    如果您有本地 postgres 安装,您可能希望使用不同的主机端口,不过(例如 "8001:5432")。更多详情请见下文。

    更改将在容器重启后生效:docker-compose -f local.yml up。不需要单独启动 postgres 容器(由于 django-service 中的depends_on: -postgres 设置,每当 django-service 启动时它都会由 docker 启动)。

    解释

    对端口部分的更改允许您连接到端口 5432 并访问绑定到同一端口的容器中的服务。端口的顺序是"HOST_PORT:CONTAINER_PORT",这样就可以将不同的端口相互映射。如果例如您已经在本地安装并运行了 postgres(因此在您的主机上),这可能是必要的。当您的本地 postgres 安装已经使用端口 5432 时,您可以将容器公开到不同的端口,这样仍然可以区分和访问两个 postgres 实例。

    为什么 postgres 默认不可用?

    如果只是用于 django,则不需要转发这些端口,因为 docker compose 的工作方式:

    “默认情况下,Compose 会为您的应用程序设置一个网络。服务的每个容器都加入默认网络,并且该网络上的其他容器都可以访问,并且可以通过与容器名称相同的主机名发现它们。”

    来自 docker 文档:Networking in Compose

    由于 docker compose 完成了网络处理,因此 django 容器无需任何端口转发即可到达 postgres 容器。为了使您的主机可以访问端口,因此必须显式转发它(例如使用 django 服务本身完成,以允许在端口 8080 下访问开发服务器)。

    旁注:虽然您可以安全地更改本地配置,但要小心更改生产配置。您使用的每个额外端口也可能被滥用。因此,如果您知道(安全)后果,请仅在此处添加端口。

    【讨论】:

      【解决方案2】:

      你可以使用django dbshell:

      docker-compose run django python manage.py dbshell
      

      或者,如果django 容器已经在运行:

      docker exec -it django python manage.py dbshell
      

      【讨论】:

        【解决方案3】:

        除了前面的答案,我还需要确保我的容器中安装了 postgres 客户端。对我们来说,这是在需要时安装的,而不是添加到我们的 Dockerfile 中。

        所以从容器终端中运行 apt-get install -y postgresql-client 然后 ./manage.py dbshell 成功地将我存放在 postgres shell 中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-12
          • 2016-11-06
          • 2018-04-09
          • 2019-01-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多