I have the following go code:
func NewConnection(connectionString string) (*sql.DB, error) {
db, err := sql.Open("postgres", connectionString)
if err := db.Ping(); err != nil {
log.Panic(err)
}
return db, err
}
And the following Dockerfile:
# Build env
FROM golang:alpine AS build
ARG stage
RUN apk update && apk upgrade && \
apk add --no-cache bash git openssh build-base && \
go get -u golang.org/x/vgo
ADD . /src
WORKDIR /src
RUN vgo mod init && vgo install ./...&& vgo build -o service
# Runtime env
FROM alpine
ARG stage
RUN apk update && apk add --no-cache ca-certificates openssl openssl-dev
WORKDIR /app
COPY --from=build /src/${stage}-env.yml /app/
COPY --from=build /src/service /app/
ENV CONFIG_PATH=.
ENTRYPOINT ./service
My NewConnection function retrieves a Redshift connection string from a queue, along with some data. Which all works locally when I test against a postgres container. However, when I deploy my service, I get the following error:
panic: pq: parameter "ssl" cannot be changed after server start
My connection contains ?ssl=true
and it should be SSL, we're connecting from a Fargate service in AWS, to AWS Redshift etc. So I think the issue could be related to missing ssl dependencies in my Alpine container, or missing certs or something along those lines.
You can establish DB connection without SSL encryption, like that:
db, err := sql.Open("postgres", "user=test password=test dbname=test sslmode=disable")
I figured this out, the connection string we were using had ssl=true
which worked for a library in nodejs, but in Go it should be sslmode=require
. I did a check for this, and a string replace.