自建Supabase Realtime镜像无法连接数据库问题求助
问题
我运行以下Docker Compose文件:
version: '3' services: db: image: supabase/postgres:14.1.0.105 container_name: realtime-db ports: - "5432:5432" volumes: - ./dev/postgres:/docker-entrypoint-initdb.d/ command: postgres -c config_file=/etc/postgresql/postgresql.conf environment: POSTGRES_HOST: /var/run/postgresql POSTGRES_PASSWORD: postgres realtime: depends_on: - db #build: . image: supabase/realtime:v2.22.5 container_name: realtime-server ports: - "4000:4000" environment: PORT: 4000 DB_HOST: host.docker.internal DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: postgres DB_NAME: postgres DB_ENC_KEY: supabaserealtime DB_AFTER_CONNECT_QUERY: 'SET search_path TO _realtime' API_JWT_SECRET: dc447559-996d-4761-a306-f47a5eab1623 FLY_ALLOC_ID: fly123 FLY_APP_NAME: realtime SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq ERL_AFLAGS: -proto_dist inet_tcp ENABLE_TAILSCALE: "false" DNS_NODES: "''" command: sh -c "/app/bin/migrate && /app/bin/realtime eval 'Realtime.Release.seeds(Realtime.Repo)' && /app/bin/server"
出现如下错误:
Recreating realtime-server ... done Attaching to realtime-db, realtime-server realtime-db | realtime-db | PostgreSQL Database directory appears to contain a database; Skipping initialization realtime-db | realtime-db | 2023-09-05 16:38:00.017 UTC [1] LOG: pgaudit extension initialized realtime-db | 2023-09-05 16:38:00.062 UTC [1] LOG: starting PostgreSQL 14.6 (Debian 14.6-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit realtime-db | 2023-09-05 16:38:00.062 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 realtime-db | 2023-09-05 16:38:00.062 UTC [1] LOG: listening on IPv6 address "::", port 5432 realtime-db | 2023-09-05 16:38:00.069 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" realtime-db | 2023-09-05 16:38:00.077 UTC [29] LOG: database system was shut down at 2023-09-05 16:25:23 UTC realtime-server | Setting RLIMIT_NOFILE to 100000 realtime-db | 2023-09-05 16:38:00.083 UTC [1] LOG: database system is ready to accept connections realtime-db | 2023-09-05 16:38:00.084 UTC [35] LOG: TimescaleDB background worker launcher connected to shared catalogs realtime-db | 2023-09-05 16:38:00.085 UTC [37] LOG: pg_cron scheduler started realtime-server | 16:38:00.673 [error] Postgrex.Protocol (#PID<0.137.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (host.docker.internal:5432): non-existing domain - :nxdomain realtime-server | 16:38:00.673 [error] Postgrex.Protocol (#PID<0.136.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (host.docker.internal:5432): non-existing domain - :nxdomain realtime-server | 16:38:03.166 [error] Postgrex.Protocol (#PID<0.136.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (host.docker.internal:5432): non-existing domain - :nxdomain realtime-server | 16:38:03.440 [error] Postgrex.Protocol (#PID<0.137.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (host.docker.internal:5432): non-existing domain - :nxdomain realtime-server | 16:38:07.352 [error] Postgrex.Protocol (#PID<0.136.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (host.docker.internal:5432): non-existing domain - :nxdomain realtime-server | 16:38:07.736 [error] Postgrex.Protocol (#PID<0.137.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (host.docker.internal:5432): non-existing domain - :nxdomain realtime-server | 16:38:15.660 [error] Could not create schema migrations table. This error usually happens due to the following: realtime-server | realtime-server | * The database does not exist realtime-server | * The "schema_migrations" table, which Ecto uses for managing realtime-server | migrations, was defined by another library realtime-server | * There is a deadlock while migrating (such as using concurrent realtime-server | indexes with a migration_lock) realtime-server | realtime-server | To fix the first issue, run "mix ecto.create". realtime-server | realtime-server | To address the second, you can run "mix ecto.drop" followed by realtime-server | "mix ecto.create". Alternatively you may configure Ecto to use realtime-server | another table and/or repository for managing migrations: realtime-server | realtime-server | config :realtime, Realtime.Repo, realtime-server | migration_source: "some_other_table_for_schema_migrations", realtime-server | migration_repo: AnotherRepoForSchemaMigrations realtime-server | realtime-server | The full error report is shown below. realtime-server | realtime-server | ** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 14993ms. This means requests are coming in and your connection pool cannot serve them fast enough. You can address this by: realtime-server | realtime-server | 1. Ensuring your database is available and that you can connect to it realtime-server | 2. Tracking down slow queries and making sure they are running fast enough realtime-server | 3. Increasing the pool_size (although this increases resource consumption) realtime-server | 4. Allowing requests to wait longer by increasing :queue_target and :queue_interval realtime-server | realtime-server | See DBConnection.start_link/2 for more information realtime-server | realtime-server | (ecto_sql 3.8.3) lib/ecto/adapters/sql.ex:932: Ecto.Adapters.SQL.raise_sql_call_error/1 realtime-server | (elixir 1.14.3) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2 realtime-server | (ecto_sql 3.8.3) lib/ecto/adapters/sql.ex:1024: Ecto.Adapters.SQL.execute_ddl/4 realtime-server | (ecto_sql 3.8.3) lib/ecto/migrator.ex:696: Ecto.Migrator.verbose_schema_migration/3 realtime-server | (ecto_sql 3.8.3) lib/ecto/migrator.ex:510: Ecto.Migrator.lock_for_migrations/4 realtime-server | (ecto_sql 3.8.3) lib/ecto/migrator.ex:422: Ecto.Migrator.run/4 realtime-server | (ecto_sql 3.8.3) lib/ecto/migrator.ex:146: Ecto.Migrator.with_repo/3 realtime-server | nofile:1: (file) realtime-server exited with code 1
请问该问题的原因是什么?
问题原因与解决办法
核心原因
错误日志中的tcp connect (host.docker.internal:5432): non-existing domain - :nxdomain是关键,说明realtime容器无法解析host.docker.internal这个域名。
host.docker.internal是Docker提供的用于访问宿主机的特殊域名,但在Docker Compose默认的桥接网络中,容器之间需要通过服务名称互相访问,而非该域名。你的PostgreSQL服务名称是db,因此realtime容器应该使用db作为DB_HOST,而非host.docker.internal。
另外,depends_on仅保证容器启动顺序,不确保PostgreSQL服务完全就绪(如完成初始化并能接受连接),这也会加重连接失败的问题。
解决步骤
修改DB_HOST配置
在realtime服务的environment配置中,将DB_HOST: host.docker.internal改为DB_HOST: db。Docker Compose会自动在内部网络中为每个服务创建DNS记录,使用服务名即可直接访问对应容器。添加数据库健康检查(可选但推荐)
为db服务添加健康检查,确保PostgreSQL真正就绪后再启动realtime服务,避免因数据库未完全初始化导致的连接失败:db: # 保留原有配置 healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 realtime: # 保留原有配置 depends_on: db: condition: service_healthy重新启动服务
执行以下命令重新部署:docker-compose down docker-compose up -d
内容的提问来源于stack exchange,提问作者ventsyv
相关产品推荐
相关产品推荐

