Home > Enterprise >  Using base Images for Services in docker-compose with different args
Using base Images for Services in docker-compose with different args

Time:01-21

My Setup: I have 3 Services defined in my docker-compose.yml: frontend backend and postgresql. postgresql is pulled from docker-hub.

frontend and backend are built from their own Dockerfiles, most of the Code of these Dockerfiles is the same and only EXPOSE ENTRPOINT CMD and ARG-Values differ from each other. That is why I wanted to create a 'base-Dockerfile' that these two Services can "include".
Sadly I found out I can not simply "include" a Dockerfile into another Dockerfile, I have to create an Image.
So I tried to create a base image for frontend and backend in my docker-compose.yml:

services:
  frontend_base:
    image: frontend_base_image
    build:
      context: ./
      dockerfile: base.dockerfile
      args:
        - WORKDIR=/app/frontend/
        - TOOLSDIR=${PWD}/docker/tools
        - LOCALDIR=${PWD}/app/frontend/client

  backend_base:
    image: backend_base_image
    build:
      context: ./
      dockerfile: base.dockerfile
      args:
        - WORKDIR=/app/backend/
        - TOOLSDIR=${PWD}/docker/tools
        - LOCALDIR=${PWD}/app/backend/api

  frontend:
    depends_on:
      - frontend_base
    # Some more stuff for the service
  backend:
    depends_on:
      - backend_base
    # Some more stuff for the service

My 'base-Dockerfile':

FROM node:18

# Set in docker-compose.yml-file
ARG WORKDIR
ARG TOOLSDIR
ARG LOCALDIR
ENV WORKDIR=${WORKDIR}

# Install dumb-init for the init system
RUN wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64
RUN chmod  x /usr/local/bin/dumb-init

WORKDIR ${WORKDIR}
RUN mkdir -p ${WORKDIR}

# Copy package.json to the current workdir (for npm install)
COPY ${LOCALDIR}/package*.json ${WORKDIR}

# Install all Packages (refereed from package.json)
RUN npm install

COPY ${TOOLSDIR}/start.sh /usr/local/bin/start.sh
COPY ${LOCALDIR}/ ${WORKDIR}

The Problem I am facing: My frontend and backend Dockerfiles try to pull the 'base-image' from docker.io

 => ERROR [docker-backend internal] load metadata for docker.io/library/backend_base_image:latest                                                                                 0.9s
 => ERROR [docker-frontend internal] load metadata for docker.io/library/frontend_base_image:latest                                                                               0.9s
 => CANCELED [frontend_base_image internal] load metadata for docker.io/library/node:18

My Research: I do not know if my approach is possible, I did not find much Resources about this (integrated with docker-compose) online, only Resources about building the Images via Shell and then using them in a Dockerfile. I also tried this and ran into some other issues, where I could not provide correct arguments to the base-Dockerfile. So I firstly wanted to find out if it is possible with docker-compose.

I am sorry if this is super obvious and my Question is dumb, I am relatively new to Docker.

CodePudding user response:

We could use the feature of a multistage containerfile to define all three images in a single containerfile:

FROM node:18 AS base

# Set in docker-compose.yml-file
ARG WORKDIR
ARG TOOLSDIR
ARG LOCALDIR
ENV WORKDIR=${WORKDIR}

# Install dumb-init for the init system
RUN wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64
RUN chmod  x /usr/local/bin/dumb-init

WORKDIR ${WORKDIR}
RUN mkdir -p ${WORKDIR}

# Copy package.json to the current workdir (for npm install)
COPY ${LOCALDIR}/package*.json ${WORKDIR}

# Install all Packages (refereed from package.json)
RUN npm install

COPY ${TOOLSDIR}/start.sh /usr/local/bin/start.sh
COPY ${LOCALDIR}/ ${WORKDIR}

FROM base AS frontend
...

FROM base AS backend
...

In our docker-compose.yml, we can then build a specific stage for the frontend- and backend-service:

  ...
  frontend:
    image: frontend
    build:
      context: ./
      target: frontend
      dockerfile: base.dockerfile
    ...
  backend:
    image: backend
    build:
      context: ./
      target: backend
      dockerfile: base.dockerfile
    ...
  • Related