英文:
how to solve this error on Golang running with MySQL in Docker connection refused
问题
我已经搜索并使用了这种方法,但它仍然不起作用,连接无法建立。
我的Dockerfile:
# 从golang基础镜像开始
FROM golang:alpine as builder
# 安装git
# git是用于获取依赖项的必需品
RUN apk update && apk add --no-cache git
# 在容器内设置当前工作目录
WORKDIR /app
# 复制go mod和sum文件
COPY go.mod go.sum ./
# 下载所有依赖项。如果go.mod和go.sum文件没有更改,依赖项将被缓存
RUN go mod download
# 将源代码从当前目录复制到容器内的工作目录
COPY . .
# 构建Go应用程序
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# 从头开始启动一个新的阶段
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# 从上一个阶段复制预构建的二进制文件。注意我们还复制了.env文件
COPY --from=builder /app/main .
COPY --from=builder /app/.env .
# 将端口8080暴露给外部世界
EXPOSE 2345
# 运行可执行文件的命令
CMD ["./main"]
我的Docker-compose.yml:
version: '3.9'
services:
  app:
    container_name: golang_api_container
    build: .
    ports:
      - 5000:2345
    restart: on-failure
    volumes:
      - api:/usr/src/app/
    depends_on:
      - golang-mysql
    networks:
      - fullstack
  golang-mysql:
    image: mysql:5.7
    container_name: db_mysql_container
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 12345
    ports:
      - 3306:3306
    volumes:
      - database_mysql:/var/lib/mysql
    networks:
      - fullstack
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin_container
    depends_on:
      - golang-mysql
    environment:
      - PMA_HOST=golang-mysql
      - PMA_ARBITRARY=1
    ports:
      - 3001:80
    restart: always
    networks:
      - fullstack
volumes:
  api:
  database_mysql:
networks:
  fullstack:
    driver: bridge
我的.db文件:
# Mysql Live
DB_HOST=db_mysql_container
DB_DRIVER=mysql
API_SECRET=sipil_api2022
DB_USER=root
DB_PASSWORD=12345
DB_NAME=macan
DB_PORT=3306
# Mysql Test
TEST_DB_HOST=db_mysql_container
TEST_DB_DRIVER=mysql
TEST_API_SECRET=sipil_api2022
TEST_DB_USER=root
TEST_DB_PASSWORD=12345
TEST_DB_NAME=macan_test
TEST_DB_PORT=3306
我的db-config.go文件:
func SetupDBConnection() *gorm.DB {
	errEnv := godotenv.Load()
	if errEnv != nil {
		panic("Failed to load env file")
	}
	dbUser := os.Getenv("DB_USER")
	dbPass := os.Getenv("DB_PASSWORD")
	dbHost := os.Getenv("DB_HOST")
	dbName := os.Getenv("DB_NAME")
	dsn := fmt.Sprintf("%s:%s@tcp(%s:3306)/%s?charset=utf8&parseTime=True&loc=Local", dbUser, dbPass, dbHost, dbName)
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Println("Failed to create a connection to DB")
	} else {
		log.Println("Connection Established to DB")
	}
	return db
}
仍然出现错误。我已将DB_HOST调整为DB_HOST=db_mysql_container,因为它与mysql的docker容器名称匹配,但仍然无法连接,连接被拒绝。
英文:
I've searched and used this method but it still doesn't work, the connection doesn't work
https://stackoverflow.com/questions/62436736/golang-mysql-docker-connection-refused
my Dockerfile
# Start from golang base image
FROM golang:alpine as builder
# ENV GO111MODULE=on
# Install git.
# Git is required for fetching the dependencies.
RUN apk update && apk add --no-cache git
# Set the current working directory inside the container 
WORKDIR /app
# Copy go mod and sum files 
COPY go.mod go.sum ./
# Download all dependencies. Dependencies will be cached if the go.mod and the go.sum files are not changed 
RUN go mod download 
# Copy the source from the current directory to the working Directory inside the container 
COPY . .
# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# Start a new stage from scratch
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# Copy the Pre-built binary file from the previous stage. Observe we also copied the .env file
COPY --from=builder /app/main .
COPY --from=builder /app/.env .       
# Expose port 8080 to the outside world
EXPOSE 2345
#Command to run the executable
CMD ["./main"]
Docker-compose.yml
version: '3.9'
services:
  app:
    container_name: golang_api_container
    build: .
    ports: 
      - 5000:2345 
    restart: on-failure
    volumes:
      - api:/usr/src/app/
    depends_on:
      - golang-mysql          
    networks:
      - fullstack
  golang-mysql:
    image: mysql:5.7
    container_name: db_mysql_container
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 12345
    ports: 
      - 3306:3306 
    volumes:
      - database_mysql:/var/lib/mysql
    networks:
      - fullstack
  
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin_container
    depends_on:
      - golang-mysql
    environment:
      - PMA_HOST=golang-mysql # Note the "golang-mysql". Must be the name of the what you used as the mysql service.
      # - PMA_USER=root
      # - PMA_PORT=${DB_PORT}
      # - PMA_PASSWORD=
      - PMA_ARBITRARY=1
    ports:
      - 3001:80
    restart: always
    networks:
      - fullstack
volumes:
  api:
  database_mysql:                  
# Networks to be created to facilitate communication between containers
networks:
  fullstack:
    driver: bridge
.env file
# Mysql Live
DB_HOST=db_mysql_container                      
# DB_HOST=127.0.0.1                           # when running the app without docker 
DB_DRIVER=mysql 
API_SECRET=sipil_api2022                          # Used for creating a JWT. Can be anything 
DB_USER=root
DB_PASSWORD=12345
DB_NAME=macan
DB_PORT=3306
# DB_PASSWORD_ROOT=root
# Mysql Test
TEST_DB_HOST=db_mysql_container                        
# TEST_DB_HOST=127.0.0.1                       # when running the app without docker 
TEST_DB_DRIVER=mysql
TEST_API_SECRET=sipil_api2022
TEST_DB_USER=root
TEST_DB_PASSWORD=12345
TEST_DB_NAME=macan_test
TEST_DB_PORT=3306
# DB_PASSWORD_ROOT=root
my db-config.go
func SetupDBConnection() *gorm.DB { 
	errEnv := godotenv.Load() 
	if errEnv != nil {
		panic("Failed to load env file")
	}
	dbUser := os.Getenv("DB_USER")     
	dbPass := os.Getenv("DB_PASSWORD") 
	dbHost := os.Getenv("DB_HOST")     
	dbName := os.Getenv("DB_NAME")     
	dsn := fmt.Sprintf("%s:%s@tcp(%s:3306)/%s?charset=utf8&parseTime=True&loc=Local", dbUser, dbPass, dbHost, dbName) 
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})                                                             
	if err != nil {
		log.Println("Failed to create a connection to DB")
	} else {
		log.Println("Connection Established to DB")
	}
	return db
}
Still error
I've adjusted the DB_HOST to DB_HOST=db_mysql_container, because it matches the name on the docker container for mysql, but it still doesn't connect and the connection is refused.
答案1
得分: 1
当您部署一个堆栈/组合时,应该使用服务名称而不是容器名称进行通信。
因此,您的DB_HOST应该只是golang-mysql。此外,在生产环境中,您不希望将端口3306:3306映射到主机上。
英文:
When you are deploying a stack/compose, then you should communicate over the services name and not the container name
So your DB_HOST should be just golang-mysql. Also in production, you don't want to map the port 3306:3306 to the host.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论