我似乎无法使用Docker容器连接到CloudSQL。
首先是我的文件路径:https://imgur.com/a/Nmx41o6
Dockerfile.dev:
FROM node:14-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . ./Dockerfile.sql
RUN mkdir /cloudsql
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY ./cloud_sql_proxy ./
COPY ./service_acct.json ./version: '3.8'
services:
cloud-sql-proxy:
build:
context: .
dockerfile: DockerFile.sql
volumes:
- /cloudsql:/cloudsql
- /service_acct.json:/app/service_acct.json
command: ./cloud_sql_proxy -dir=/cloudsql -instances=test-game-199281:us-east1:testgame -credential_file=/app/service_acct.json
app:
build:
context: .
dockerfile: DockerFile.dev
env_file:
- ./.env
volumes:
# since we copied root into host in dockerfile, we can map the whole directory with app.
- "./src:/app/src"
ports:
- "5000:5001"
command: sh -c "npm run dev"我的节点index.js文件。我不认为有什么问题,也许我输入了错误的连接字符串格式?据我所知,密码和用户是正确的。
const express = require('express');
const { Pool, Client } = require('pg')
const app = express();
require('dotenv').config({path:'../.env'})
const pool = new Pool({
user: 'postgres',
host: '/cloudsql/test-game-199281:us-east1:testgame',
database: 'TestDB',
password: '********',
port: 5432
})
app.get('/', (req, res) => {
pool.connect(function(err, client, done) {
if (err) {
console.log("not able to get connection " + err);
res.status(400).send(err);
return
}
client.query("SELECT * FROM company", [1], (err, result) =>{
done();
if (err) {
console.log(err);
res.status(400).send(err);
}
res.status(200).send(result.rows);
});
});
});我收到以下错误:
Hello world listening on port 5001
app_1 | Error: connect ENOENT /cloudsql/test-game-199281:us-east1:testgame
/.s.PGSQL.5432
app_1 | at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1146:16) {
app_1 | errno: -2,
app_1 | code: 'ENOENT',
app_1 | syscall: 'connect',
app_1 | address: '/cloudsql/test-game-199281:us-east1:testgame
/.s.PGSQL.5432'
app_1 | }解决方法:我切换到了TCP。螺钉unix插座。太让人困惑了。
发布于 2021-05-11 12:53:24
ENOENT错误意味着连接器实用程序找不到要连接到数据库的主机。这里有一个good answer进一步解释了这一点。
在您的docker-compose文件上,Cloud SQL代理正在通过TCP进行侦听,但您的代码正在尝试通过Unix套接字进行连接。您的代码无法连接到主机,因为套接字不存在。
解决方案是将代理配置为create和listen to a Unix Socket。将命令更改为:
/cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME -dir=/cloudsql -credential_file=/tmp/keys/keyfile.json无需暴露任何端口即可通过Unix套接字进行连接。我还建议使用上面链接中的配置对象或pg-pool指定的配置对象来构建池连接,而不是DB,以避免出现无法使用connectionString URL连接到Unix套接字的可能的issue。
发布于 2021-05-11 13:25:25
在不同的dockers之间进行连接时,您可以尝试使用服务名cloud-sql-proxy:5432而不是localhost:5432。
每个docker都是一个隔离的网络,因此您不能使用localhost,因为localhost将引用docker容器自己的本地网络。
发布于 2021-05-11 22:37:53
您已经指示Cloud SQL Auth代理使用此标志-instances=test-game-199281:us-east1:testgame=tcp:0.0.0.0:5432侦听0.0.0.0:5432。
但是,您已经指示您的应用程序连接到/cloudsql/<INSTANCE_CONNCECTION_NAME>,这是一个unix套接字。
你需要选择一个,并确保你的应用程序和代理之间的一致性。
如果您使用TCP,则必须将容器中的端口映射到您机器上的端口(或您的应用程序可以到达的docker-compose网络中的某个位置)。你必须更新你的应用程序才能连接到127.0.0.1 (或者网络中任何它的docker IP地址)。您可以在docker-compose networking here上查看更多内容。
如果你使用Unix域套接字,你需要卷共享包含套接字的文件夹,以便两个应用程序都可以访问它。因此,如果是在/cloudsql中,您将需要在代理容器和应用程序容器之间共享/cloudsql。您可以在docker-compose volumes here上查看更多信息。
Cloud SQL的管理数据库连接页面has examples of connecting with both TCP and Unix domain sockets。
https://stackoverflow.com/questions/67480206
复制相似问题