英文:
Go REST API not reachable using docker-compose
问题
我正在尝试使用Gin Gonic和MySQL以及PHPMyAdmin创建一个简单的Go Rest API,并使用Docker运行。
尽管PHPMyAdmin正常运行,但当我尝试访问我的Go API时,出现以下错误消息:localhost没有发送任何数据。ERR_EMPTY_RESPONSE
如果我在没有使用Docker的情况下运行main.go
文件,一切都按预期工作。
这是我的docker-compose
文件:
version: '3'
services:
app:
container_name: full_app
build: .
ports:
- 8080:8080
expose:
- 8080
restart: on-failure
environment:
- PMA_HOST=fullstack-mysql
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PORT}
volumes:
- .:/usr/src/app/
depends_on:
- fullstack-mysql
networks:
- fullstack
fullstack-mysql:
image: mysql:5.7
container_name: full_db_mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_HOST=${DB_HOST}
- MYSQL_USER=${DB_USER}
- MYSQL_ROOT_USER=${DB_ROOT_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_DATABASE=${DB_NAME}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
volumes:
- database_mysql:/var/lib/mysql
networks:
- fullstack
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin_container
depends_on:
- fullstack-mysql
environment:
- PMA_HOST=fullstack-mysql
- PMA_USER=${DB_USER}
- PMA_PORT=${DB_PORT}
- PMA_PASSWORD=${DB_PASSWORD}
ports:
- 9090:80
restart: always
networks:
- fullstack
volumes:
api:
database_mysql:
# Networks to be created to facilitate communication between containers
networks:
fullstack:
driver: bridge
这是我的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 8080
#Command to run the executable
CMD ["./main"]
这是我的Go main.go
文件(目前):
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
)
func main() {
router := gin.Default()
router.GET("/", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{"data": "Hello World !"})
})
router.Run("localhost:8080")
}
如果我访问http://localhost:9090
,PhpMyAdmin正在加载(正如我所期望的)。
如果我访问http://localhost:8080
,我会收到这个错误消息:localhost没有发送任何数据。ERR_EMPTY_RESPONSE
我使用docker-compose up --build
运行这个。
显然我做错了什么,但我不确定是什么。
英文:
I am trying to run a simple go Rest API created with Gin Gonic and MySQL and PHPMyAdmin with docker.
While the PHPMyAdmin is running fine, when I try to access my go API I get the following error message: localhost didn’t send any data. ERR_EMPTY_RESPONSE
If I run my main.go
file without docker, everything is working as expected
here is my docker-compose
file
version: '3'
services:
app:
container_name: full_app
build: .
ports:
- 8080:8080
expose:
- 8080
restart: on-failure
environment:
- PMA_HOST=fullstack-mysql
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PORT}
volumes:
- .:/usr/src/app/
depends_on:
- fullstack-mysql
networks:
- fullstack
fullstack-mysql:
image: mysql:5.7
container_name: full_db_mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_HOST=${DB_HOST}
- MYSQL_USER=${DB_USER}
- MYSQL_ROOT_USER=${DB_ROOT_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_DATABASE=${DB_NAME}
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
volumes:
- database_mysql:/var/lib/mysql
networks:
- fullstack
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin_container
depends_on:
- fullstack-mysql
environment:
- PMA_HOST=fullstack-mysql
- PMA_USER=${DB_USER}
- PMA_PORT=${DB_PORT}
- PMA_PASSWORD=${DB_PASSWORD}
ports:
- 9090:80
restart: always
networks:
- fullstack
volumes:
api:
database_mysql:
# Networks to be created to facilitate communication between containers
networks:
fullstack:
driver: bridge
Here is 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 8080
#Command to run the executable
CMD ["./main"]
And here is my go main.go
file (for now):
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
)
func main() {
router := gin.Default()
router.GET("/", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{"data": "Hello World !"})
})
router.Run("localhost:8080")
}
If I access http://localhost:9090
PhpMyAdmin is loading (exactly what I am expecting)
If I access http://localhost:8080
I get this error message: localhost didn’t send any data. ERR_EMPTY_RESPONSE
I run docker-compose up --build
for this.
I am obviously doing something wrong, but I am not sure what.
答案1
得分: 1
似乎问题出在你的Go代码和我指定API监听主机的方式上。在我的main.go
文件中,我当前将主机设置为"localhost:8080",但是当在Docker容器中运行应用程序时,我应该监听"0.0.0.0:8080"。这样可以使容器绑定到所有网络接口。
为了解决这个问题,我需要修改main.go
文件中的router.Run
行,如下所示:
router.Run("0.0.0.0:8080")
在进行了这个更改之后,我重新构建了Docker镜像,并使用docker-compose up --build
命令再次运行了容器。这样应该可以使我的Go REST API在Docker容器外部通过http://localhost:8080
访问。
注意:容器内部的localhost
指的是容器本身,而不是主机机器。通过使用"0.0.0.0",我指示容器绑定到所有可用的网络接口,从而允许我从主机机器访问API。
英文:
It seems that the issue lies in your Go code and the way I am specifying the host for my API to listen on. In my main.go
file, I am currently setting the host as "localhost:8080", but when running my application inside a Docker container, I should listen on "0.0.0.0:8080" instead. This allows the container to bind to all network interfaces.
To fix the issue, I had to modify the router.Run
line in my main.go
file as follows:
router.Run("0.0.0.0:8080")
After making this change, I rebuilt my Docker image and run my containers again using docker-compose up --build. This should allow my Go REST API to be accessible on http://localhost:8080
outside of the Docker container.
Note: The localhost
inside the container refers to the container itself, not the host machine. By using "0.0.0.0", I am instructing the container to bind to all available network interfaces, allowing me to access the API from my host machine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论