Access Go Api Размещено в Docker контейнере - PullRequest
0 голосов
/ 02 мая 2020

Я создал Go бэкэнд-сервер, который содержит API. Все работает хорошо при локальном запуске "go run server". Однако я столкнулся с проблемами при запуске его в docker. Поэтому я создал Dockerfile и запустил контейнер linux на хосте сетевого режима, но не могу получить доступ к API в браузере. Если он работает, я смогу увидеть ответ json от http://localhost: 8500 / status . Поэтому я думаю, что мне нужны разрешения или добавить флаги или больше сценариев, связанных с установкой. Я тестировал различные флаги и порты в 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 -составить:

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

Любая помощь приветствуется,

Приветствия!

1 Ответ

0 голосов
/ 04 мая 2020

Итак, я решил это сейчас:

Как уже упоминалось здесь: https://docs.docker.com/compose/networking/

Добавить в docker -составить:

networks:
  default:
    external:
      name: database_default

Как упомянуто здесь: Доступ к mysql контейнеру из другого контейнера

Я могу подключиться к базе данных как : 3306 в бэкэнде.

Для автоматизации процесс, который я создал. sh скрипт для обработки дополнительного шага настройки конфигурации при запуске контейнера. Тем не менее, из-за моей структуры в моем config.yml было сложно обновлять только с помощью команд «sed», поэтому я создал программу python для обновления всех данных конфигурации. Dockerfile, docker -компонентный файл, setup. sh и файл update_config.py показаны ниже.

setup. 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

update_config.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

Работает нормально! И мы избегаем использования ненужного режима сети хоста!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...