Файл докера для проекта Go из двух исполняемых файлов с общими пакетами

# #docker #go #dockerfile

Вопрос:

У меня есть проект, который включает в себя клиент-сервер с несколькими общими файлами. Я пытаюсь создать образы докеров для клиента и сервера и борюсь с написанием файла докеров. Я просмотрел онлайн-источники, которые в основном включают очень простые проекты или проекты, которые слишком велики и не помогли в этом вопросе.

Структура моего проекта соответствует стандартному макету проекта:

 Project
    -api
        -api.go
    -cmd
        -client
            -client.go
        -server
            -server.go
    -configs
        -configuration.yaml
    -internal
        -client_int
            -client_logic.go
        -server_int
            -server_logic.go
        -shared_int
            -shared_logic.go
    -Dockerfile
    -go.mod
 

Не мог бы кто-нибудь, пожалуйста, посоветовать/прокомментировать структуру проекта или иметь аналогичный файл dockerfile в качестве примера?

Спасибо.

*Я просмотрел множество руководств, которые появляются в Google или с помощью простых ключевых слов github.

Комментарии:

1. неясно, в чем ваша проблема, и вы не поделились содержимым файла dockerfile. Сталкиваетесь ли вы с ошибкой докера ? Или вам неудобно использовать полученный контейнер ? В любом случае, похоже, что вы могли бы использовать многоступенчатую возможность для создания целевого объекта для сервера и другого для клиента.

2. Почему бы не 2 изображения, одно для клиента и одно для сервера? Просто храните Dockerfile s в отдельных каталогах и скопируйте весь проект в оба.

3. @супер это то, что я пытаюсь сделать.

Ответ №1:

В этом (очень обычном) макете проекта есть две важные детали:

  1. При создании образа контекстный каталог (параметр Compose build: { context: } или аргумент docker build directory) должен быть Project каталогом верхнего уровня.
  2. Где бы ни находился файл Dockerfile физически, левая сторона любых COPY инструкций должна быть относительно Project каталога (контекстного каталога из предыдущего пункта).

Есть несколько вариантов того, как из этого создавать образы докеров. Вы можете создать один образ как с клиентом, так и с сервером, или отдельный образ для каждого, и вы можете поместить файлы Dockerfile(ы) в верхний каталог или в соответствующий cmd подкаталог; для такого проекта, как этот, я не думаю, что существует стандартный способ сделать это.

Чтобы выбрать подход (ни в коем случае не «лучший», но тот, который будет работать), предположим, мы создадим отдельные изображения для каждой части; но, поскольку общий доступ к большому количеству кода, вам в основном нужно скопировать все исходное дерево, чтобы выполнить сборку изображения.

 # cmd/server/Dockerfile
# Build-time stage:
FROM golang:alpine AS build
WORKDIR /build

# First install library dependencies
# (These are expensive to download and change rarely;
# doing this once up front saves time on rebuilds)
COPY go.mod go.sum .
RUN go mod install

# Copy the whole application tree in
COPY . .

# Build the specific component we want to run
RUN go build -o server ./cmd/server

# Final runtime image:
FROM alpine
# Get the built binary
COPY --from=build /build/server /usr/bin
# And set it as the main container command
CMD ["server"]
 

И, может быть, вы запускаете это через Docker Compose:

 version: '3.8'
services:
  server:
    build:
      context: .
      dockerfile: cmd/server/Dockerfile
    ports:
      - 8000:8000
  client:
    build:
      context: .
      dockerfile: cmd/client/Dockerfile
    environment:
      SERVER_URL: 'http://server:8000'
 

Обратите внимание , что оба изображения указывают корневой каталог проекта в качестве сборки context: , но затем указывают другой dockerfile: для каждого.

Комментарии:

1. Я изучал его много времени, прежде чем спросить, так что большое вам спасибо, небольшая модификация, и это может быть то, что я искал.