0

I would to create a docker image using docker-compose and push it into the gitlab container registry. The docker-compose file has some build.args so during compile compile I pass the env file using the --env-file flag. The Dockerfile image is a two step: base and production and this is the contents:

FROM node:17.0-alpine AS base

ARG GITLAB_ACCESS_TOKEN

WORKDIR /usr/src/app

COPY .npmrc ./
COPY package*.json ./

RUN npm i

COPY . .

FROM base AS production

RUN npm run build

This is the docker-compose.yml:

version: '3.8'
services: 
  aaa-bbb:
    container_name: ccc
    environment:
      - GITLAB_ACCESS_TOKEN=${GITLAB_ACCESS_TOKEN}
    build:
      context: .
      dockerfile: Dockerfile
      target: base
      args:
        GITLAB_ACCESS_TOKEN: ${GITLAB_ACCESS_TOKEN}
        PORT: ${PORT}
    image: aaa-bbb/ccc:${TAG_VERSION}
    restart: always
    ports:
      - 80:${PORT}
    command: yarn start:dev

and this one is the docker-compose.prod.yml:

version: '3.8'
services: 
  aaa-bbb:
    container_name: ccc
    environment:
      - GITLAB_ACCESS_TOKEN=${GITLAB_ACCESS_TOKEN}
    build:
      context: .
      dockerfile: Dockerfile
      target: production
      args:
        GITLAB_ACCESS_TOKEN: ${GITLAB_ACCESS_TOKEN}
        PORT: ${PORT}
    image: aaa-bbb/ccc:${TAG_VERSION}
    restart: always
    ports:
      - 80:${PORT}
    command: yarn start:prd

To build the image I use this command: docker-compose --env-file ./config/.production.env -f docker-compose.yml -f docker-compose.prod.yml build --no-cache

This is the gitlab pipeline step to build and store into the container regristry the docker image:

create_image:
  image: docker
  stage: create-image
  services:
    - docker:dind
  before_script:
    - TAG_VERSION=$(awk -F= '$1 == "TAG_VERSION" { print $2 }' ./config/.production.env)
    - apk add --no-cache docker-compose
    - docker image prune -f
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - echo " Image creation started..."
    - docker-compose --env-file ./config/.production.env -f docker-compose.yml -f docker-compose.prod.yml build --no-cache
    - docker-compose --env-file ./config/.production.env push aaa-bbb/ccc:${TAG_VERSION}
    - echo " Image created successfully!"

This is the output of the pipeline:

Removing intermediate container 1187fec9a21e
 ---> b0c14918a07b
[Warning] One or more build-args [PORT] were not consumed
Successfully built b0c14918a07b
Successfully tagged aaa-bbb/ccc:1.0.0
$ docker-compose --env-file ./config/.production.env push aaa-bbb/ccc:${TAG_VERSION}
No such service: aaa-bbb/ccc:1.0.0
Cleaning up project directory and file based variables 00:00
ERROR: Job failed: exit code 1

As you can see, there is this warning: [Warning] One or more build-args [PORT] were not consumed that during my test in local it doesn't appear and second I have a service tagged as aaa-bbb/ccc:1.0.0 but I can't push it because there isn't the service.

How can I fix this problems?

th3g3ntl3man
  • 1,926
  • 5
  • 29
  • 50

1 Answers1

2

your first issue is that in your docker-compose.yml you defined a build arg named PORT, but that is not present in your Dockerfile. Hence docker warns about it being defined but not used.

You can fix that by adding

ARG PORT
EXPOSE ${PORT}

to the end of the Dockerfile. If you want to set a default value (for example HTTP port 80) for as the port you can use this form: ARG PORT=80.

If you need any more information about Dockerfiles, you can read more about it in its reference documentation at https://docs.docker.com/engine/reference/builder/

But that does not lead to the error. When pushing with docker-compose you use the service name instead of the image. So in your case the correct command would be

docker-compose --env-file ./config/.production.env push aaa-bbb

Also, you need to add the full URL for the image name in docker-compose.yml. I.e.:

services: 
  aaa-bbb:
    [redacted]
    image: your.gitlab.instance/perhapssomegroup/aaa-bbb/ccc:${TAG_VERSION}
    [redacted]

You can read more about docker-compose at https://docs.docker.com/compose/reference/ and about its yml file at https://docs.docker.com/compose/compose-file/compose-file-v3/

I suggest to have all the documentation links I posted on speed-dial (also called bookmark) as you might need them a lot.

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 09 '21 at 14:16
  • Thank you for your detailed answare but, despite having done the login to the `container register` when the `docker-compose push` is executed it try to `push` on `docker.io` instead of gitlab container registry – th3g3ntl3man Nov 10 '21 at 08:11
  • 1
    right. You need to set the image: key with a full URL pointing to your own registry. I added this to the answer. – Phillip -Zyan K Lee- Stockmann Nov 10 '21 at 08:46
  • Note that `PORT` is syntactically incorrect. Do you mean `EXPOSE`? – th3g3ntl3man Nov 10 '21 at 12:56
  • You are right @th3g3ntl3man . Thanks for pointing it out. I fixed the answer accordingly. – Phillip -Zyan K Lee- Stockmann Nov 10 '21 at 18:08