It is not my golang script, but i should to use them in this task: package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
"log"
"net/http"
"github.com/caarlos0/env"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
type config struct {
PostgresUri string `env:"POSTGRES_URI" envDefault:"postgres://root:[email protected]/postgres"`
ListenAddress string `env:"LISTEN_ADDRESS" envDefault:":5432"`
}
var (
db *sql.DB
errorsCount = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "gocalc_errors_count",
Help: "Gocalc Errors Count Per Type",
},
[]string{"type"},
)
requestsCount = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "gocalc_requests_count",
Help: "Gocalc Requests Count",
})
)
func main() {
var err error
// Initing prometheus
prometheus.MustRegister(errorsCount)
prometheus.MustRegister(requestsCount)
// Getting env
cfg := config{}
if err = env.Parse(&cfg); err != nil {
fmt.Printf("% v\n", err)
}
// Connecting to database
db, err = sql.Open("postgres", cfg.PostgresUri)
if err != nil {
log.Fatalf("Can't connect to postgresql: %v", err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatalf("Can't ping database: %v", err)
}
http.HandleFunc("/", handler)
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(cfg.ListenAddress, nil))
}
func handler(w http.ResponseWriter, r *http.Request) {
requestsCount.Inc()
keys, ok := r.URL.Query()["q"]
if !ok || len(keys[0]) < 1 {
errorsCount.WithLabelValues("missing").Inc()
log.Println("Url Param 'q' is missing")
http.Error(w, "Bad Request", 400)
return
}
q := keys[0]
log.Println("Got query: ", q)
var result string
sqlStatement := fmt.Sprintf("SELECT (%s)::numeric", q)
row := db.QueryRow(sqlStatement)
err := row.Scan(&result)
if err != nil {
log.Println("Error from db: %s", err)
errorsCount.WithLabelValues("db").Inc()
http.Error(w, "Internal Server Error", 500)
return
}
fmt.Fprintf(w, "query %s; result %s", q, result)
}
It is my docker-compose:
version: "3"
services:
db:
image: postgres:10
environment:
- POSTGRES_PASSWORD=pass
- POSTGRES_USER=root
expose:
- 5432
backend:
image: dkr-14-gocalc:latest
environment:
- POSTGRES_URI=postgres://root:pass@db/postgres
- LISTEN_ADDRESS=7000
depends_on:
- postgres
proxy:
image: nginx
volumes:
- type: bind
source: ./nginx.conf
target: /etc/nginx/conf.d/default.conf
ports:
- 8000:80
depends_on:
- backend
And it is dkr14-gocalc image:
FROM golang:1.19.1-alpine AS builder
ENV GO111MODULE=auto
WORKDIR /go/src/
RUN apk add --no-cache git
COPY main.go ./
#init is initializing and writting new go.mod in current dir.
RUN go mod init main.go
RUN go get -d -v github.com/caarlos0/env \
&& go get -d -v github.com/prometheus/client_golang/prometheus \
&& go get -d -v github.com/prometheus/client_golang/prometheus/promhttp \
&& go get -d -v github.com/lib/pq \
&& go get -d -v database/sql \
&& go get -d -v fmt \
&& go get -d -v log \
&& go get -d -v net/http
RUN go build -o app .
FROM alpine:3.10.3
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/app ./
CMD ["./app"]
I should to make docker compose environment with 3 services GO POSTGRES NGINX. The main idea of task is to learn about environment. Database should have password and golalc should to connect to this database. But what have i done incorrect?
It is my log:
backend_1 | 2022/11/07 23:27:33 Can't ping database: dial tcp 127.0.0.1:5432: connect: connection refused
postgres_1 | The files belonging to this database system will be owned by user "postgres".
postgres_1 | This user must also own the server process.
postgres_1 |
proxy_1 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
proxy_1 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
postgres_1 | The database cluster will be initialized with locale "en_US.utf8".
postgres_1 | The default database encoding has accordingly been set to "UTF8".
postgres_1 | The default text search configuration will be set to "english".
postgres_1 |
postgres_1 | Data page checksums are disabled.
proxy_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
proxy_1 | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
postgres_1 |
task14_backend_1 exited with code 1
proxy_1 | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
postgres_1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
postgres_1 | creating subdirectories ... ok
proxy_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
postgres_1 | selecting default max_connections ... 100
proxy_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
postgres_1 | selecting default shared_buffers ... 128MB
postgres_1 | selecting default timezone ... Etc/UTC
postgres_1 | selecting dynamic shared memory implementation ... posix
proxy_1 | /docker-entrypoint.sh: Configuration complete; ready for start up
postgres_1 | creating configuration files ... ok
postgres_1 | running bootstrap script ... ok
postgres_1 | performing post-bootstrap initialization ... ok
postgres_1 | syncing data to disk ... ok
postgres_1 |
postgres_1 | Success. You can now start the database server using:
postgres_1 |
postgres_1 | pg_ctl -D /var/lib/postgresql/data -l logfile start
postgres_1 |
postgres_1 |
postgres_1 | WARNING: enabling "trust" authentication for local connections
postgres_1 | You can change this by editing pg_hba.conf or using the option -A, or
postgres_1 | --auth-local and --auth-host, the next time you run initdb.
proxy_1 | 2022/11/07 23:27:33 [emerg] 1#1: host not found in upstream "backend" in /etc/nginx/conf.d/default.conf:5
proxy_1 | nginx: [emerg] host not found in upstream "backend" in /etc/nginx/conf.d/default.conf:5
postgres_1 | waiting for server to start....2022-11-07 23:27:33.704 UTC [48] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1 | 2022-11-07 23:27:33.722 UTC [49] LOG: database system was shut down at 2022-11-07 23:27:33 UTC
postgres_1 | 2022-11-07 23:27:33.729 UTC [48] LOG: database system is ready to accept connections
postgres_1 | done
postgres_1 | server started
task14_proxy_1 exited with code 1
postgres_1 | CREATE DATABASE
postgres_1 |
postgres_1 |
postgres_1 | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
postgres_1 |
postgres_1 | 2022-11-07 23:27:34.130 UTC [48] LOG: received fast shutdown request
postgres_1 | waiting for server to shut down....2022-11-07 23:27:34.133 UTC [48] LOG: aborting any active transactions
postgres_1 | 2022-11-07 23:27:34.135 UTC [48] LOG: worker process: logical replication launcher (PID 55) exited with exit code 1
postgres_1 | 2022-11-07 23:27:34.135 UTC [50] LOG: shutting down
postgres_1 | 2022-11-07 23:27:34.157 UTC [48] LOG: database system is shut down
postgres_1 | done
postgres_1 | server stopped
postgres_1 |
postgres_1 | PostgreSQL init process complete; ready for start up.
postgres_1 |
postgres_1 | 2022-11-07 23:27:34.254 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_1 | 2022-11-07 23:27:34.254 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_1 | 2022-11-07 23:27:34.259 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1 | 2022-11-07 23:27:34.283 UTC [76] LOG: database system was shut down at 2022-11-07 23:27:34 UTC
postgres_1 | 2022-11-07 23:27:34.294 UTC [1] LOG: database system is ready to accept connections
CodePudding user response:
The issue could be in how you're exposing your database container in the docker-compose.yaml
file. "connection refused" is a typical error in this scenario. Usually, I export the ports in a different way (in this code I reported only the relevant parts):
docker-compose.yaml
version: "3"
services:
db:
image: postgres
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
ports:
- "5432:5432"
main.go
package main
import (
"database/sql"
"log"
_ "github.com/lib/pq"
)
func main() {
// Connecting to database
db, err := sql.Open("postgres", "host=127.0.0.1 user=postgres password=postgres dbname=postgres port=5432 sslmode=disable")
if err != nil {
log.Fatalf("Can't connect to postgresql: %v", err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatalf("Can't ping database: %v", err)
}
}
With this solution, I was able to successfully ping the Postgres database directly from the code. Let me know if that helps.
Edit
There is a little difference in the way you interact with db instance:
- If you're trying to contact the db directly from your host machine (like in the
main.go
file), you've to refer to it with the IP address of your machine (e.g.,127.0.0.1
). - If you're trying to contact the db from your web container, you've to use something like
postgres://db:5432
withdb
as the hostname.
Let me know if this clarifies a little bit.