Как собрать go + node.js в один контейнер в docker?

Для того чтобы собрать приложение, написанное на языках программирования Go и Node.js, в один контейнер в Docker, необходимо использовать множественный этап (multi-stage) сборки. Это позволяет создавать временные образы для сборки компонентов приложения на разных языках, а затем объединять результаты в один конечный образ.

Пример Dockerfile с использованием множественного этапа сборки выглядит следующим образом:

# Этап сборки Go
FROM golang:alpine as goBuilder

WORKDIR /app

# Скопировать исходные файлы Go в контейнер
COPY go.mod .
COPY go.sum .
RUN go mod download

COPY *.go .

# Собрать исполняемый файл Go
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .

# Этап сборки Node.js
FROM node:alpine as nodeBuilder

WORKDIR /app

# Скопировать исходные файлы Node.js в контейнер
COPY package*.json .

# Установить зависимости Node.js
RUN npm install

COPY . .

# Собрать статические файлы Node.js
RUN npm run build

# Этап конечного образа
FROM alpine

WORKDIR /app

# Скопировать исполняемый файл Go из этапа сборки Go
COPY --from=goBuilder /app/myapp .

# Скопировать статические файлы Node.js из этапа сборки Node.js
COPY --from=nodeBuilder /app/dist /app/dist

# Определить порт, на котором будет работать приложение
EXPOSE 8080

# Запустить приложение
CMD ["./myapp"]

В данном примере Dockerfile содержит три этапа сборки: первый для сборки исходного кода на Go, второй для сборки статических файлов Node.js, и третий, конечный этап, где объединяются результаты двух предыдущих этапов.

Сначала, на этапе сборки Go, мы используем образ golang:alpine в качестве основы для сборки кода на Go. Копируем файлы go.mod и go.sum для загрузки зависимостей Go. Затем копируем остальные исходные файлы Go и собираем исполняемый файл myapp.

На этапе сборки Node.js мы используем образ node:alpine для сборки статических файлов Node.js. Копируем файлы package*.json для установки зависимостей Node.js и затем копируем остальные исходные файлы. Запускаем сборку статических файлов Node.js с помощью npm run build.

На финальном этапе мы используем образ alpine (или другой подходящий образ) в качестве конечного образа. Копируем исполняемый файл Go из этапа сборки Go и статические файлы Node.js из этапа сборки Node.js. Определяем порт, на котором будет работать приложение, и запускаем его с помощью команды CMD.

После создания Dockerfile вам нужно выполнить команду docker build в директории с Dockerfile для создания контейнера. Например:

docker build -t myapp .

Таким образом, в результате выполнения данного Dockerfile вы получите контейнер, в котором будут находиться и исполняемый файл Go, и статические файлы Node.js, готовые для запуска вашего приложения в одном контейнере.