Search code examples
dockerbuild-processdocker-compose

Use Docker to run a build process


I'm using docker and docker-compose to set up a build pipeline. I've got a front-end that's written in javascript and needs to be built before being used. The backend is written in go.

To make this component integrate with the rest of our docker-compose setup, I want to do the building in a docker image as well.

This is the flow I'm going for:

  • during build do:
    • build the frontend stuff and put it in /output (that is bound to the
      output volume
    • build the backend server
  • when running do:
    • run the server, it has access to the build files in /output

I'm quite new to docker and docker-compose so I'm not sure if this is possible, or even the right thing to do.

For reference, here's my docker-compose.yml:

version: '2'
volumes:
  output:
    driver: local

services:
  frontend:
    build: .
    volumes:
      - output:/output
  backend:
    build: ./backend
    depends_on:
      - frontend
    volumes:
      - output:/output

and Dockerfile:

FROM node

# create working dir
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ADD package.json /usr/src/app/package.json

# install packages
RUN npm install
COPY . /usr/src/app

# build frontend files and place results in /output 
RUN npm build
RUN cp /usr/src/app/build/* /output

And backend/Dockerfile:

 FROM go

 # copy and build server
 COPY . /usr/src/backend
 WORKDIR /usr/src/backend
 RUN go build

 # run the server
 ENTRYPOINT ["/usr/src/backend/main"]

Something is wrong here, but I do not know what. It seems as though the output of the build step are not persisted in the output volume. What can I do to fix this?


Solution

  • You cannot attach a volume during docker build. The reason for this is that the goal of the docker build command is to build an image, and nothing else, it doesn't need to have volumes, as Dockerfile has ADD / COPY.

    To produce your output, you should create a script which mostly does the npm install ; npm build ; cp /usr/src/app/build/* /output from your current dockerfile and use this script as the entrypoint / cmd in your dockerfile.

    I'm not sure compose can run this, but in any case, I find it more clear wrapped in a shell script that first executes the frontend builder container, then executing the backend container with the output directory as a volume.