簡體   English   中英

訪問 Go Api 托管在 Docker 容器中

[英]Access Go Api Hosted in Docker container

我創建了一個 Go 后端服務器,其中包含一個 api。 在本地運行“運行服務器”時一切正常。 然而,我在 docker 中運行它時確實遇到了問題。 所以我創建了一個 Dockerfile 並在網絡模式主機中運行 linux 容器,但無法在瀏覽器中訪問 api。 如果它正常工作,我應該能夠看到來自http://localhost:8500/status的 json 響應。 所以我想我需要權限或添加標志或更多與安裝相關的腳本。 我一直在測試 docker 中的不同標志和端口,但無法確定問題所在。 請參閱代碼 dockerfile 和下面的命令。

注意:當我在 windows 本地運行程序時,會彈出一個安全警告,也許這與問題有關?

我正在運行 docker 桌面社區 v 2.2.0.5 穩定版。

Api 代碼:

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"]

Docker-compose:

version : '3'

services:
  react:
    build: ./ReactFrontend/
    container_name: ReactFrontend
    tty: true
    ports:
    - 4000:3000

  backend:
    network_mode: host
    build: ./GoBackend/
    container_name: goserver
    ports:
    - 8500:8500
    - 8600:8600

Docker 命令:

docker run --net=host goserver

任何幫助表示贊賞,

干杯!

所以我現在通過以下方式解決了它:

如此處所述: https://docs.docker.com/compose/networking/

添加到 docker-compose:

networks:
  default:
    external:
      name: database_default

如此處所述: 從其他容器訪問 mysql 容器

我可以在后端以 < db_container_name >:3306 的形式連接到數據庫。

為了自動化這個過程,我創建了一個 a.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 run
python3 update_config.py

# Start program
go run server

Dockerfile:

# Start from the latest golang base image
FROM golang:latest

WORKDIR /go/src/server

COPY ./src/server .

# Install python3 and yml compability
RUN apt-get update && apt-get install -y python3-pip
RUN python3 --version
RUN pip3 install PyYAML

# Download packages
RUN go get . 

# Compile code
#RUN go build -o server
RUN go install server

# Expose ports
EXPOSE 8500
EXPOSE 8600

# ENV
 ENV DB_HOST "mysql:3306"

#CHMOD setup
RUN chmod +x setup.sh

CMD ["./setup.sh"]

Docker-compose

version : '3'

services:
  react:
    build: ./ReactFrontend/
    container_name: ReactFrontend
    tty: true
    ports:
    - 4000:3000

  backend:
    build: ./GoBackend/
    container_name: GoBackend
    environment:
      DB_HOST: mysql:3306 # Name or IP of DB container!
    ports:
    - 8500:8500
    - 8600:8600

networks:
  default:
    external:
      name: database_default

更新配置.py:

import yaml
import os

"""
DONT REMOVE
This 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:
    data["database"]["ip"] = os.environ['DB_HOST']


# Updated data print
print("Updated Data", data)

# Write changes to config
stream = open(fname, 'w')
yaml.dump(data, stream)
stream.close()

如果我們只希望容器運行,現在可以使用示例 docker 命令:

docker run -p 8500:8500 -p 8600:8600 --net database_default goserver

它工作正常! 我們正在避免使用不必要的主機網絡模式!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM