如何在 VSCode 远程开发容器中处理多个 `network_mode`?

How to deal with more than one `network_mode` in a VSCode Remote dev container?

我想在开发容器中有一个应用程序、数据库和 redis 服务 运行,这样我就可以在容器、应用程序和 Windows 上访问我的数据库和 redis ,这就是我目前对我的应用程序和数据库的要求:

.devcontainer.json:

{
  "name": "Node.js, TypeScript, PostgreSQL & Redis",
  "dockerComposeFile": "docker-compose.yml",
  "service": "akira",
  "workspaceFolder": "/workspace",
  "settings": {
    "typescript.tsdk": "node_modules/typescript/lib",
    "sqltools.connections": [
      {
        "name": "Container database",
        "driver": "PostgreSQL",
        "previewLimit": 50,
        "server": "database",
        "port": 5432,
        "database": "akira",
        "username": "ailuropoda",
        "password": "melanoleuca"
      }
    ],
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.fixAll": true
    }
  },
  "extensions": [
    "aaron-bond.better-comments",
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "mtxr.sqltools",
    "mtxr.sqltools-driver-pg",
    "redhat.vscode-yaml"
  ],
  "forwardPorts": [5432],
  "postCreateCommand": "npm install",
  "remoteUser": "node"
}

docker-compose.yml:

version: "3.8"

services:
  akira:
    build:
      context: .
      dockerfile: Dockerfile
    command: sleep infinity
    env_file: .env
    volumes:
      - ..:/workspace:cached

  database:
    image: postgres:latest
    restart: unless-stopped
    environment:
      POSTGRES_USER: ailuropoda
      POSTGRES_DB: akira
      POSTGRES_PASSWORD: melanoleuca
    ports:
      - 5432:5432
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:alpine
    tty: true
    ports:
      - 6379:6379

volumes:
  pgdata:

Dockerfile:

ARG VARIANT="16-bullseye"
FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-${VARIANT}

如您所见,我已经尝试使用 networks 实现我想要的,但没有成功,我的问题是:如何将 Redis 添加到我的服务中,同时仍然能够连接 Redis 和内部数据库应用程序和 Windows?

删除所有 network_mode: 设置。 Compose 将使用默认值 network_mode: bridge。您将能够使用其 Compose 服务名称作为主机名在容器之间进行通信,如 Docker 文档中的 Networking in Compose 所述。

version: "3.8"
services:
  akira:
    build: .
    env_file: .env
    environment:
      PGHOST: database

  database:
    image: postgres:latest
    ...

在 SO 问题中,我经常看到尝试使用 network_mode: 使其他内容显示为 localhost。该主机名对上下文非常敏感;如果你问我的笔记本电脑、Stack Overflow HTTP 服务器之一、你的应用程序容器或你的数据库容器 localhost 是谁,他们每个人都会独立地说“我当然是”,但指的是不同的网络上下文. network_mode: service:... 听起来你正试图让另一个容器成为 localhost;实际上,使用它是非常不寻常的。

您可能需要更改应用程序代码以使数据库位置等设置可配置,具体取决于它们所在的位置 运行,环境变量是在 Docker 中进行设置的简单方法.对于这个特定示例,我使用了标准 PostgreSQL 客户端库使用的 $PGHOST 变量;在 Typescript/Node 上下文中,您可能需要更改代码以引用 process.env.SOME_HOSTNAME 而不是 'localhost'.

如果你在 WSL 上使用 Docker,我发现当进程正在侦听 ::1 时,我经常无法连接,但是当显式绑定端口到 127.0.0.1 时,服务可以访问通过 Windows.

所以像

ports:
  - 127.0.0.1:5432:5432

可能有用

将所有非开发容器切换到 network_mode:service:akira

version: '3.8'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ../..:/workspace:cached
    command: sleep infinity
  postgresql:
    image: postgres:14.1
    network_mode: service:akira
    restart: unless-stopped
    volumes:
      - ../docker/volumes/postgresql:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: pornapp
  redis:
    image: redis
    network_mode: service:akira
    restart: unless-stopped
    volumes:
      - ../docker/volumes/redis:/data

这似乎是原始配置: https://github.com/microsoft/vscode-dev-containers/pull/523

但它被恢复了,因为如果你重建开发容器而其他服务是 运行,端口转发将会中断: https://github.com/microsoft/vscode-dev-containers/issues/537