Несколько Dockerfiles повторно используют общую библиотеку в проекте - PullRequest
2 голосов
/ 20 января 2020

У меня есть следующая структура кода, и я пытаюсь структурировать свои Dockerfile (ы), чтобы максимизировать кэширование и тому подобное.

serverfoo/
    Dockerfile
    main.go

serverbar/
    Dockerfile
    main.go

proto/
    Dockerfile
    sharedproto.proto // Generates a sharedproto.pb.go file to be imported.

И serverfoo, и serverbar импортируют скомпилированный файл sharedproto.pb.go, который я вручную восстанавливаю на своей рабочей станции. Это работает нормально, но сейчас я пытаюсь контейнировать два моих сервера.

Dockerfiles с папками на моем сервере не может (по умолчанию) копировать proto/ содержимое. В идеале я предварительно скомпилирую protobufs в sharedproto.pb.go, затем импортирую кэшированную версию этого файла в два сервера Dockerfiles . Цель состоит в том, чтобы кэшировать скомпилированные протобуфы до тех пор, пока не будут изменены базовые прототипы.

Я новичок в Docker и мне нужна лучшая практика для такого рода вещей. Я хочу избежать root Dockerfile в каталоге моего проекта, в котором есть код для компиляции миллиарда различных серверов.

Я открыт для некоторой степени реструктуризации своего проекта.

1 Ответ

0 голосов
/ 21 января 2020

ПРИМЕЧАНИЕ : Полагаю, ваша цель состоит в том, чтобы на указанном c сервере-контейнере имелся скомпилированный файл go (из спецификаций c main. go файл) и скомпилированный буферный файл протокола (из общего sharedproto.proto файла).

Предполагая, что ваши файлы организованы на рабочей станции следующим образом:

serverfoo/
   Dockerfile
   main.go

serverbar/
   Dockerfile
   main.go

proto/
   Dockerfile
   sharedproto.proto

Вы можете структурировать указанный * Dockerfile сервера c, используя многоступенчатую сборку, как описано ниже (например, Dockerfile сервера):

#####
# The serverbar Dockerfile
#####

#----
# Compile proto stage
#----
FROM moul/protoc-gen-gotemplate AS protostage
WORKDIR /workspace
# Copy .proto file
COPY proto/sharedproto.proto .
# Compile .pb.go
RUN protoc -I=. --go_out=. sharedproto.proto

#----
# Build stage
#----
FROM golang:1.12.4-alpine3.9 as buildstage
WORKDIR /workspace
COPY serverbar/main.go .
RUN GOOS=linux GOARCH=amd64 go build -o serverbar main.go

#----
# Final stage
#----
FROM alpine:3.7
WORKDIR /home
COPY --from=buildstage workspace/serverbar .
COPY --from=protostage workspace/sharedproto.pb.go .
CMD ["./serverbar"]

Используя этот подход, вы в основном имеете следующие 3 этапа:

  1. этап подготовки : В контейнере, созданном на этом этапе, необходимо скомпилировать исходный файл буфера общего протокола в sharedproto.pb. go затем он будет включен в третий заключительный этап. Поэтому здесь вам необходимо установить на контейнер компилятор proto c и соответствующий плагин Go. Однако, как обычно с Docker, вы найдете docker изображение, которое уже содержит ваши необходимые инструменты. Для этого мы можем начать с изображения moul / proto c -gen-gotemplate docker. В частности, следующая инструкция Dockerfile создает workspace / sharedproto.pb. go:

      RUN protoc -I=. --go_out=. sharedproto.proto
    
  2. этап сборки : здесь вам нужно скомпилировать исходный файл сервера в исполняемый файл. Также это будет включено в третий заключительный этап. Чтобы избежать установки Golang, мы можем начать с образа golang: 1.12.4-alpine3.9 docker, который уже содержит все необходимые инструменты. В частности, следующая инструкция Dockerfile создает рабочее пространство / серверная панель исполняемый файл:

      RUN GOOS=linux GOARCH=amd64 go build -o serverbar main.go
    
  3. конечная стадия : это серверный контейнер, который мы Затем мы загрузим в наш Docker реестр для тестирования или производства, куда мы скопируем файлы, скомпилированные на двух предыдущих этапах, с помощью следующих команд:

      COPY --from=buildstage workspace/serverbar .
      COPY --from=protostage workspace/sharedproto.pb.go .
    

One Преимущество этого решения заключается в том, что для каждой сборки сервера вы можете кэшировать скомпилированные протобуфы до тех пор, пока базовые прототипы не будут изменены.

Пример: Первое построение serverbar * Контейнер 1060 *. Отметим, что компиляция .proto выполняется на новом контейнере с идентификатором 92ae211bd27d :

> docker build -f serverbar/Dockerfile .
Sending build context to Docker daemon  10.24kB
Step 1/13 : FROM moul/protoc-gen-gotemplate AS protostage
 ---> 635345fde953
Step 2/13 : WORKDIR /workspace
 ---> Using cache
 ---> de8890a5e775
Step 3/13 : COPY proto/sharedproto.proto .
 ---> 1253fa0576aa
Step 4/13 : RUN protoc -I=. --go_out=. sharedproto.proto
 ---> Running in 8426f5810b98 
Removing intermediate container 8426f5810b98
 ---> 92ae211bd27d <=========================================
Step 5/13 : FROM golang:1.12.4-alpine3.9 as buildstage
 ---> b97a72b8e97d
Step 6/13 : WORKDIR /workspace

....

. Сборка выполняется второй раз без изменения файла sharedproto.proto. контейнер с идентификатором 92ae211bd27d повторно используется из кэша.

> docker build -f serverbar/Dockerfile .
Sending build context to Docker daemon  10.24kB
Step 1/13 : FROM moul/protoc-gen-gotemplate AS protostage
 ---> 635345fde953
Step 2/13 : WORKDIR /workspace
 ---> Using cache
 ---> de8890a5e775
Step 3/13 : COPY proto/sharedproto.proto .
 ---> Using cache
 ---> 1253fa0576aa
Step 4/13 : RUN protoc -I=. --go_out=. sharedproto.proto
 ---> Using cache <=========================================
 ---> 92ae211bd27d
Step 5/13 : FROM golang:1.12.4-alpine3.9 as buildstage
 ---> b97a72b8e97d

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