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?
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 Dockerfile
s, 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.