Golang后端Docker容器API调用遇net::ERR_CONNECTION_REFUSED问题求助
问题:Golang API容器因数据库连接超时退出,前端请求被拒绝
前端报错信息
index-149c02ff.js:166 POST https://cihanbatasul.com:8081/register net::ERR_CONNECTION_REFUSED st @ index-149c02ff.js:166 (anonymous) @ index-149c02ff.js:166 await in (anonymous) (async) Nb @ index-149c02ff.js:37 Tb @ index-149c02ff.js:37 Ub @ index-149c02ff.js:37 nf @ index-149c02ff.js:37 se$2 @ index-149c02ff.js:37 (anonymous) @ index-149c02ff.js:37 Rk @ index-149c02ff.js:40 Jb @ index-149c02ff.js:37 hd @ index-149c02ff.js:37 fd @ index-149c02ff.js:37 ed @ index-149c02ff.js:37 index-149c02ff.js:166 TypeError: Failed to fetch at st (index-149c02ff.js:166:107788) at index-149c02ff.js:166:98541
后端main.go代码(已配置CORS)
package main import ( "crypto/rand" "crypto/tls" "database/sql" "encoding/base64" "flag" "fmt" "log" "net/http" "os" "github.com/cihanbatasul/bookapi/internal/models" "github.com/joho/godotenv" _ "github.com/lib/pq" "github.com/rs/cors" ) type application struct { error_log *log.Logger info_log *log.Logger books *models.BookServiceImplementation users *models.UserServiceImplementation user_helpers *models.UserHelperServiceImplementation ai *models.AiServiceImplementation } func openDB(dsn string) (*sql.DB, error) { db, err := sql.Open("postgres", dsn) if err != nil { return nil, err } if err = db.Ping(); err != nil { return nil, err } return db, nil } func generateRandomSecret(length int) (string, error) { secretBytes := make([]byte, length) _, err := rand.Read(secretBytes) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(secretBytes), nil } func main() { if err := godotenv.Load(".env"); err != nil { log.Fatalf("Fehler beim Laden der .env-Datei %v", err) } cors := cors.New(cors.Options{ AllowedOrigins: []string{"https://cihanbatasul.com", "http://localhost", "https://books.cihanbatasul.com"}, AllowedMethods: []string{"GET", "POST", "OPTIONS"}, AllowedHeaders: []string{"Content-Type"}, AllowCredentials: true, }) addr := flag.String("addr", ":8081", "HTTPS network address") flag.Parse() dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", os.Getenv("HOST"), os.Getenv("DB_PORT"), os.Getenv("USER_NAME"), os.Getenv("PASSWORD"), os.Getenv("DB_NAME")) info_log := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime) error_log := log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile) db, err := openDB(dsn) if err != nil { fmt.Printf("%s", dsn) error_log.Fatal(err) } defer db.Close() app := &application{ error_log: error_log, info_log: info_log, books: &models.BookServiceImplementation{}, users: &models.UserServiceImplementation{DB: db}, user_helpers: &models.UserHelperServiceImplementation{}, ai: &models.AiServiceImplementation{}, } handler := cors.Handler(app.Routes()) certPath := "certs/cert.pem" keyPath := "certs/privkey.pem" // Load TLS certificate and key cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { log.Fatal("Error loading certificate and key:", err) } // Create TLS config tlsConfig := &tls.Config{ Certificates: []tls.Certificate{cert}, } // Create HTTPS server srv := &http.Server{ Addr: *addr, ErrorLog: app.error_log, Handler: handler, TLSConfig: tlsConfig, } info_log.Println("Starting server on port ", *addr) // Start HTTPS server err = srv.ListenAndServeTLS("", "") if err != nil { app.error_log.Fatal(err) } }
容器状态
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ca807a67f67a booksbackend "./main" 14 minutes ago Exited (1) 4 minutes ago booksbackend_container 3516610db914 booksbackend_db "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp booksbackend_db_container 6a2f27202298 portfolio2023:latest "portfolio2023 -p 80…" 2 days ago Up 2 days 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp portfolio_backend
API容器Docker日志
intero@231:~$ sudo docker logs booksbackend_container ERROR 2024/06/12 18:13:55 main.go:75: dial tcp 92.205.28.231:5432: connect: connection timed out
补充配置信息
.env环境变量
PORT=8081 DB_DOCKER_CONTAINER=booksbackend_db_container DB_NAME=booksbackend_db USER_NAME=intero PASSWORD=thepassword HOST=cihanbatasul.com DB_PORT=5432 BINARY=bookapi
数据库Dockerfile
FROM postgres:12-alpine ENV POSTGRES_USER=intero ENV POSTGRES_PASSWORD=thepassword ENV POSTGRES_DB=booksbackend_db EXPOSE 5432 COPY migrations/000001_books_migrations.up.sql /docker-entrypoint-initdb.d/init.sql
应用Dockerfile
FROM golang:1.22.0-alpine3.19 AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o main ./cmd/web FROM alpine:latest WORKDIR /app COPY .env /app/ COPY --from=builder /app/main . RUN mkdir -p certs COPY certs/* certs/ EXPOSE 8081 CMD ["./main"]
解决步骤
- 修改数据库连接地址:将
.env中的HOST值从cihanbatasul.com改为数据库容器名booksbackend_db_container,Docker内部DNS会自动解析该名称到数据库容器的内部IP,避免通过公网IP连接超时。 - 统一Docker网络:确保API容器和数据库容器处于同一Docker网络。若未创建自定义网络,执行
docker network create books-net,启动两个容器时添加--network books-net参数。 - 重新构建并启动容器:修改
.env后,重新构建API镜像,再启动API容器和数据库容器,确保新配置生效。
内容的提问来源于stack exchange,提问作者intero
相关产品推荐
相关产品推荐

