猿问

访问托管在 Docker 容器中的 Go Api

我创建了一个包含 api 的 Go 后端服务器。在本地运行“运行服务器”时一切正常。然而,我在 docker 中运行它时确实遇到了问题。所以我创建了一个 Dockerfile 并在 networkmode 主机中运行 linux 容器,但无法在浏览器中访问 api。如果它工作正常,我应该能够看到来自http://localhost:8500/status的 json 响应。所以我想我需要权限或添加标志或更多与安装相关的脚本。我一直在 docker 中测试不同的标志和端口,但无法识别问题。请参阅下面的代码、dockerfile 和命令。


注意:当我在 Windows 上本地运行程序时,会弹出一个安全警告,也许这与问题有关?


我正在运行 docker desktop community v 2.2.0.5 stable。


接口代码:


import (

    "log"

    "net/http"

    conf "server/conf"


    "github.com/gorilla/mux"

    "github.com/jinzhu/gorm"

    _ "github.com/jinzhu/gorm/dialects/mysql"

)

var db *gorm.DB


// Middleware used to add correct permissions for all requests

func middleware(next http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        w.Header().Set("Content-Type", "application/json")

        w.Header().Set("Access-Control-Allow-Origin", "*")

        w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

        next.ServeHTTP(w, r)

    })

}


func StartApi(config conf.Config, _db *gorm.DB) {


log.Println("Start Api")

    db = _db


    router := mux.NewRouter()

    // Create 

    router.HandleFunc("/login", login).Methods("POST", "OPTIONS")

    router.HandleFunc("/network", createNetwork).Methods("POST", "OPTIONS")


    // Read 

    router.HandleFunc("/users/{networkName}", getUsers).Methods("GET", "OPTIONS")

    router.HandleFunc("/streams/{networkName}", getStreams).Methods("GET", "OPTIONS")

    router.HandleFunc("/status", showStatus).Methods("GET", "OPTIONS")


    log.Println("API started at port " + config.Backend.Api_port) // api port is stored in config

    log.Println(http.ListenAndServe(":"+config.Backend.Api_port, middleware(router)))


    log.Println("Api done!")  }

Dockerfile:


# Start from the latest golang base image

FROM golang:latest


WORKDIR /go/src/server


COPY ./src/server .


# Download packages

RUN go get . 


# Compile code

#RUN go build -o server

RUN go install server


# Expose ports

EXPOSE 8500

EXPOSE 8600


#ENTRYPOINT ./server

CMD ["go", "run", "server"]


潇潇雨雨
浏览 144回答 1
1回答

凤凰求蛊

所以我现在通过以下方式解决了它:如此处所述:&nbsp;https ://docs.docker.com/compose/networking/添加到 docker-compose:networks: &nbsp;&nbsp;default: &nbsp;&nbsp;&nbsp;&nbsp;external: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name:&nbsp;database_default我可以在后端以 < db_container_name >:3306 的形式连接到数据库。为了自动化这个过程,我创建了一个 .sh 脚本来处理容器启动时的额外设置配置步骤。但是,由于我在 config.yml 中的结构,仅使用“sed”命令很难更新,因此我创建了一个 python 程序来更新所有配置数据。Dockerfile、docker-compose 文件、setup.sh 和 update_config.py 文件如下所示。设置.sh:#!/bin/bash# Don't remove this!# This file is used by dockerfile to replace configs# Replace config on runpython3 update_config.py# Start programgo run serverDockerfile:# Start from the latest golang base imageFROM golang:latestWORKDIR /go/src/serverCOPY ./src/server .# Install python3 and yml compabilityRUN apt-get update && apt-get install -y python3-pipRUN python3 --versionRUN pip3 install PyYAML# Download packagesRUN go get .&nbsp;# Compile code#RUN go build -o serverRUN go install server# Expose portsEXPOSE 8500EXPOSE 8600# ENV&nbsp;ENV DB_HOST "mysql:3306"#CHMOD setupRUN chmod +x setup.shCMD ["./setup.sh"]码头工人组成version : '3'services:&nbsp; react:&nbsp; &nbsp; build: ./ReactFrontend/&nbsp; &nbsp; container_name: ReactFrontend&nbsp; &nbsp; tty: true&nbsp; &nbsp; ports:&nbsp; &nbsp; - 4000:3000&nbsp; backend:&nbsp; &nbsp; build: ./GoBackend/&nbsp; &nbsp; container_name: GoBackend&nbsp; &nbsp; environment:&nbsp; &nbsp; &nbsp; DB_HOST: mysql:3306 # Name or IP of DB container!&nbsp; &nbsp; ports:&nbsp; &nbsp; - 8500:8500&nbsp; &nbsp; - 8600:8600networks:&nbsp; default:&nbsp; &nbsp; external:&nbsp; &nbsp; &nbsp; name: database_default更新配置.py:import yamlimport os"""DONT REMOVEThis file is used in the dockerfile!"""fname = "/go/src/server/config.yml"stream = open(fname, 'r')data = yaml.safe_load(stream)stream.close()# Add more updates here!if os.environ.get('DB_HOST') is not None:&nbsp; &nbsp; data["database"]["ip"] = os.environ['DB_HOST']# Updated data printprint("Updated Data", data)# Write changes to configstream = open(fname, 'w')yaml.dump(data, stream)stream.close()如果我们只希望容器运行,现在可以使用的示例 docker 命令:docker run -p 8500:8500 -p 8600:8600 --net database_default goserver它工作正常!我们正在避免使用不必要的主机网络模式!
随时随地看视频慕课网APP

相关分类

Go
我要回答