how to make container for multiple servers in one code base to deploy golang app with docker?

huangapple go评论90阅读模式
英文:

how to make container for multiple servers in one code base to deploy golang app with docker?

问题

我有一个包含多个服务器的代码库,结构如下:

// Golang Apps
- account = 端口 4001
- event = 端口 4002
- place = 端口 4003

// Node.js
- gateway = 端口 4000

我通常在本地使用以下脚本运行:

// script.sh
#!/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中应该使用的镜像,我没有头绪,因为代码库中有多个服务器运行,并且服务器的端口也是一个问题。

也许你们中的某个人曾经遇到过这种情况?了解如何解决这个问题将会很棒。

对于这个问题,我正在使用 GraphQL Federation(Go),所以我有多个服务和一个网关(Node.js)。

我想要将其部署到生产环境中。

英文:

I have a repo that has multiple servers gonna running. the structure like this

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

// Node js
- gateway = port 4000

I usually run in local using script like this

// 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

is that possible I create one Dockerfile for this case into Production? should I run the script.sh in the Dockerfile for this case? how about the image should I use in Dockerfile? I have no idea for this case using docker because the in one code base for multiple servers running , and the problem also port of servers running

maybe one of you ever has this case? it would be great to know how to solve this problem

I am using GraphQL Federation ( Go ) for this case, so I have multiple services and Gateway ( NodeJS )

I want to deploy this into Production for this question

答案1

得分: 1

你需要四个单独的Dockerfiles,以启动四个不同程序的容器。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/*包需要源目录中的其他包,比如./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
      # (由于Node应用程序无法重用Go代码,这也可以合理地使用`build: cmd/gateway`和`cmd/gateway/Dockerfile`)
    ports:
      - 3000:3000

只需运行docker-compose up即可在前台启动所有四个容器;一旦启动,按<kbd>Ctrl</kbd>+<kbd>C</kbd>将停止它们。你可以配置gateway使用其他容器的名称accountseventsplaces作为主机名;例如,http://accounts/graphql

你也可以按原样调整你的启动脚本。使用docker build而不是go build来构建镜像,使用docker run来启动容器(可能使用固定的--name),使用docker stop && docker rm来停止它们。你应该使用docker network create创建一个网络,并在它们上使用docker run --net,以便它们可以像Compose设置一样进行通信。

英文:

You need four separate Dockerfiles for this, to launch four separate containers with four different programs. The Go component Dockerfiles can be fairly straightforward:

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

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

(If the three images are really identical aside from the specific command directory being built, you could pass that in as an ARG as well. I'm assuming the ./cmd/server/* packages require packages elsewhere in your source directory like a ./pkg/support or whatever, which would require the Dockerfiles to be at the top level.)

Since your script is just running the four programs, I'd generally recommend using Docker Compose as a way to launch the four containers together. "Launch some containers with known options" is the only thing Compose does, but it would do everything your script does.

# docker-compose.yml
version: &#39;3.8&#39;
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&#39;t reuse Go code, this could also
      # reasonably be `build: cmd/gateway` using a
      # `cmd/gateway/Dockerfile`)
    ports:
      - 3000:3000

Just running docker-compose up will start all four containers in the foreground; once it's up, pressing <kbd>Ctrl</kbd>+<kbd>C</kbd> will stop them all. You can configure the gateway to use the other container names accounts, events, places as host names; http://accounts/graphql for example.

You could also adapt your launcher script as-is. Run docker build instead of go build to build images, docker run to start a container (probably with fixed --names), docker stop &amp;&amp; docker rm to stop them. You should docker network create a network and docker run --net all of the containers on them so they can communicate in the same way as the Compose setup.

huangapple
  • 本文由 发表于 2021年7月10日 10:04:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/68324147.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定