首页 > 解决方案 > 如何在一个代码库中为多个服务器制作容器以使用 docker 部署 golang 应用程序?

问题描述

我有一个要运行多个服务器的存储库。像这样的结构

// Golang Apps
- account = port 4001 
- event = port 4002
- place = port 4003

// Node js
- gateway = port 4000

我通常使用这样的脚本在本地运行

// script.sh here:
#!/bin/bash

EnvAPP="${ENV_APP:-dev}"

function cleanup {
    kill "$ACCOUNTS_PID"
    kill "$EVENTS_PID"
    kill "$PLACES_PID"
}
trap cleanup EXIT

go build -tags $EnvAPP -o ./tmp/srv-accounts ./cmd/server/accounts
go build -tags $EnvAPP -o ./tmp/srv-events ./cmd/server/events
go build -tags $EnvAPP -o ./tmp/srv-places ./cmd/server/places

./tmp/srv-accounts &
ACCOUNTS_PID=$!

./tmp/srv-events &
EVENTS_PID=$!

./tmp/srv-places &
PLACES_PID=$!

sleep 1

node ./cmd/gateway/index.js

我可以为这种情况创建一个 Dockerfile 到生产中吗?对于这种情况,我应该在 Dockerfile 中运行 script.sh 吗?我应该在 Dockerfile 中使用图像怎么样?我不知道使用 docker 的这种情况,因为在一个代码库中运行多个服务器,而且问题还在于运行的服务器端口

也许你们中的一个人有过这种情况?很高兴知道如何解决这个问题

我在这种情况下使用 GraphQL Federation ( Go ),所以我有多个服务和网关 ( NodeJS )

我想为这个问题将它部署到生产中

标签: node.jsbashdockergographql

解决方案


为此,您需要四个单独的 Dockerfile,以启动具有四个不同程序的四个独立容器。Go 组件 Dockerfiles 可以相当简单:

# Dockerfile.accounts
FROM golang:1.16 AS build
WORKDIR /app
COPY . .
ARG ENV_APP=dev
RUN go build -tags "$ENV_APP" -o /accounts ./cmd/server/accounts

FROM ubuntu:20.04
COPY --from=build /accounts /usr/local/bin
CMD accounts

(如果除了正在构建的特定命令目录之外,这三个图像确实相同,那么您也可以将其传递进去ARG。我假设这些./cmd/server/*包需要源目录中其他位置的包,例如 a./pkg/support或其他什么,这将需要 Dockerfiles处于最高水平。)

由于您的脚本只是运行这四个程序,我通常建议使用Docker Compose作为一起启动四个容器的一种方式。“启动一些具有已知选项的容器”是 Compose 唯一能做的事情,但它会完成你的脚本所做的一切。

# docker-compose.yml
version: '3.8'
services:
  accounts:
    build:
      context: .
      dockerfile: Dockerfile.accounts
  events:
    build:
      context: .
      dockerfile: Dockerfile.events
  places:
    build:
      context: .
      dockerfile: Dockerfile.places
  gateway:
    build:
      context: .
      dockerfile: Dockerfile.gateway
      # (Since a Node app can't reuse Go code, this could also
      # reasonably be `build: cmd/gateway` using a
      # `cmd/gateway/Dockerfile`)
    ports:
      - 3000:3000

只要运行docker-compose up就会在前台启动所有四个容器;一旦它启动,按Ctrl+C将停止它们。您可以将网关配置为使用其他容器名称accounts, events,places作为主机名;http://accounts/graphql例如。

您也可以按原样调整您的启动器脚本。运行docker build而不是go build构建图像,docker run启动容器(可能带有固定--name的 s),docker stop && docker rm停止它们。您应该docker network create有一个网络和docker run --net它们上的所有容器,以便它们可以以与 Compose 设置相同的方式进行通信。


推荐阅读