英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论