Can not connect from golang to docker postgres container - postgresql

I spin up the docker container for postgres
docker run -i -t -v=":/var/lib/postgresql" -p 5432:5432 my_image/postgresql:9.3
And verify that it is reachable from host using
psql -h my_docker_ip -p 5432 -U pguser -W pgdb // passowrd: pguser
Now I want to connect to the container postgres using go in my host machine.
import (
"database/sql"
_ "github.com/lib/pq"
"fmt"
)
func main() {
db, err := sql.Open("postgres", "user=pguser password='pguser' host=192.168.99.100 port=5432 sslmode=verify-full")
if err != nil {
fmt.Println(err)
}
rows, err := db.Query("SELECT * FROM test")
fmt.Println(rows)
}
While there were no error on initializing the db instance reference, the test query itself print out
<nil>
This should not happen because I created table test and multiple rows in table test prior to running the go code.
Can someone tell me what I am doing wrong?
Thanks

I saw the same error when using mysql client in golang:
Failed to connect to database: x509: cannot validate certificate for 10.111.202.229 because it doesn't contain any IP SANs
The solution in https://stackoverflow.com/a/54636760/8645590 worked for me.

Related

Can't connect to PostgreSQL database using pgx driver but can using terminal

From code
The code bellow outputs the following:
2022/06/21 16:01:07 Failed to connect to db: failed to connect to 'host=localhost user=postgres database=local': server error (FATAL: Ident authentication failed for user "postgres" (SQLSTATE 28000)) exit status 1
import (
"context"
"log"
"github.com/jackc/pgx/v4"
)
func main() {
dbCtx := context.Background()
db, err := pgx.Connect(
dbCtx,
"postgres://postgres:smashthestate#localhost:5432/local",
)
if err != nil {
log.Fatalf("Failed to connect to db: %v\n", err)
}
defer db.Close(dbCtx)
// do stuff with db...
}
From terminal
However, connection to db is possible from terminal. For example, this command if run with the same parameters (db name, user name, password) will give correct output:
psql -d local -U postgres -W -c 'select * from interest;'
Notes
Command works correctly even if sent by user that is neither root nor postgres.
Authentication method for local connection is set to trust inside pg_hba.conf:
local all all trust
So, what am I missing here? Why everything works fine from the command line but doesn't work from code?
Go's defaults are different from psql's. If no hostname is given, Go defaults to using localhost, while psql defaults to using the Unix domain sockets.
To specify a Unix domain socket to Go, you need to do it oddly to get it to survive URI validation:
postgres://postgres:smashthestate#:5432/local?host=%2Ftmp
Though the end might need to be more like ?host=%2Fvar%2Frun%2Fpostgresql, depending on how the server was configured.
But why are you specifying a password which is not needed? That is going to cause pointless confusion.

AWS SAM golang lambda localhost connection refused to postgres

I'm unable to connect an AWS SAM lambda function to a local postgres instance. I'll be specific in a moment, but first let me say that the same code works for my coworker and that I've tried using Postgres within a docker container as well as installed manually. To simplify the problem I started over with the SAM helloworld golang example and added the following:
import (
_ "github.com/lib/pq"
"database/sql"
)
.
.
.
const (
host = "localhost"
port = 5432
user = "postgres"
password = "postgres"
dbname = "postgres"
)
.
.
.
.
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
db, err := sql.Open("postgres", psqlInfo)
if err != nil {
panic(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Successfully connected!")
And I get the following error:
dial tcp 127.0.0.1:5432: connect: connection refused: OpError
[{"path":"github.com/aws/aws-lambda-go#v1.13.3/lambda/function.go","line":35,"label":"(*Function).Invoke.func1"},{"path":"runtime/panic.go","line":969,"label":"gopanic"},{"path":"hello-world/main.go","line":67,"label":"handler"},{"path":"reflect/value.go","line":475,"label":"Value.call"},{"path":"reflect/value.go","line":336,"label":"Value.Call"},{"path":"github.com/aws/aws-lambda-go#v1.13.3/lambda/handler.go","line":124,"label":"NewHandler.func1"},{"path":"github.com/aws/aws-lambda-go#v1.13.3/lambda/handler.go","line":24,"label":"lambdaHandler.Invoke"},{"path":"github.com/aws/aws-lambda-go#v1.13.3/lambda/function.go","line":67,"label":"(*Function).Invoke"},{"path":"reflect/value.go","line":475,"label":"V
alue.call"},{"path":"reflect/value.go","line":336,"label":"Value.Call"},{"path":"net/rpc/server.go","line":377,"label":"(*service).call"},{"path":"runtime/asm_amd64.s","line":1374,"label":"goexit"}]
SAM CLI, version 1.21.1
I've now tried this on two machines and get the same error. Is there there something that I'm just missing there? I can confirm that the the database is receiving connections fine. I hit it every day from a node app. Also, I can build the golang code outside of SAM and it will work fine. So there's something with my SAM setup that's wrong.
Figured it out. Within the lambda I needed to set the postgres connection string to hit host.docker.internal
I spend a lot of time figuring out how to connect using AWS SAM to a local Postgres and finally found that changing the dbhostname from localhost to host.docker.internal works.
connectionString = 'postgresql://dbuser:dbpassword#host.docker.internal:5432/dbname';

Connect to Postgres DB by a user which has no password

I created a user by:
sudo -u postgres psql -c "CREATE USER sample;"
Then created a database:
sudo -u postgres psql -c "CREATE DATABASE practice OWNER sample;"
Now I'm trying to connect to this DB by following snippet:
dsn := url.URL{
User: url.UserPassword("sample", ""),
Scheme: "postgres",
Host: fmt.Sprintf("%s", "localhost"),
Path: "practice",
RawQuery: (&url.Values{"sslmode": []string{"disable"}}).Encode(),
}
db, err := gorm.Open(
"postgres",
dsn.String(),
)
if err != nil {
log.Fatal(err)
}
But the output is:
2020/07/07 16:43:44 pq: password authentication failed for user "sample"
How do I connect to DB with a user which has no password?
Either assign the user a password and then use it, or change your pg_hba.conf file so that some other method of authentication is used for that user/dbname/connection-method/host (and then restart your server so the change takes effect).
sudo -u postgres psql -c "ALTER USER sample password 'yahkeixuom5R';"

Gorm can't connect to local postgres db

I'm new to GoLang and I`ve an issue with connecting my Go webserver with Postgres Database.
Can someone tell me what I'm doing wrong here?
All these credentials are correct btw. User exists, Password is correct, DB exists and belongs to the user.
package app
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
)
func connectDB(){
db, err := gorm.Open("postgres", "host=localhost port=5432 user=power_user dbname=local_db password=power_user")
if err != nil {
log.Fatal("DB Connection failed")
}
}
If you're sure about psql server is running, try to modify pg_hba.conf, locates at /etc/postgresql/${version}/main/pg_hba.conf usually:
# TYPE DATABASE USER ADDRESS METHOD
local all all trust

Golang lib/pg can't connect to postgres

I have such code:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
func main() {
db, err := sql.Open("postgres", "user=postgres dbname=vagrant sslmode=disable")
if err != nil {
log.Fatal(err)
}
rows, err := db.Query("SELECT 3+5")
if err != nil {
log.Fatal(err)
}
fmt.Println(rows)
}
And its result is:
[vagrant#localhost go-postgres]$ go run test.go
2015/12/19 11:03:53 pq: Ident authentication failed for user "postgres"
exit status 1
But I can access postgres:
[vagrant#localhost go-postgres]$ psql -U postgres vagrant
psql (9.4.4)
Type "help" for help.
vagrant=#
And I don't have any troubles with using Rails app with postgres.
Anyone has an idea?
EDIT:
Here is my pg_hba.conf:
local all all trust
host all all 127.0.0.1/32 ident
host all all ::1/128 ident
EDIT2:
I found this in my postgres logs:
< 2015-12-19 12:13:05.094 UTC >LOG: could not connect to Ident server at address "::1", port 113: Connection refused
< 2015-12-19 12:13:05.094 UTC >FATAL: Ident authentication failed for user "postgres"
< 2015-12-19 12:13:05.094 UTC >DETAIL: Connection matched pg_hba.conf line 84: "host all all ::1/128 ident"
I think it will really help ;)
Ok,
correct connection string is:
"user=postgres host=/tmp dbname=vagrant sslmode=disable"
I assumed pg library uses same defaults as psql or ruby driver. Lesson learned.
Run in console:
psql "user=postgres dbname=vagrant sslmode=disable"
If you cannot connect so it needs to change sslmode else I will think more.
For me, setting host to /run/postgresql worked.
Credit: https://github.com/lib/pq/issues/645#issuecomment-320799610
The host url depends on the socket Postgres is using. The socket location varies based on how and where postgres was built. The socket location can be found using:
Inside psql, run \conninfo. It shows the socket location along with other details
unix_socket_directory value in postgresql.conf
In my Ubuntu distro, /var/run is a soft link to /run, that's why /run/postgresql works even though unix_socket_directory and \conninfo mention /var/run/postgresql.