2

I'm building my app for local development using docker-compose.yaml, using the two Dockerfiles - one for app (WordPress), and another for nginx. Since this is a specific app, that is built using Jenkins pipeline, I cannot change the Dockerfiles, but I would like to be able to have the same environment to test on locally as I have on the staging and production servers.

The php part works but nginx fails. The Dockerfile for nginx looks like this:

FROM nginx:latest

COPY scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY ./config/nginx.conf /opt/nginx.conf
COPY ./config/nginx.conf.prd /opt/nginx.conf.prd

COPY --from=DOCKER_IMAGE_NAME_PHP /var/www/html/ /var/www/html/

CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]

The DOCKER_IMAGE_NAME_PHP part fails with

ERROR: Service 'nginx' failed to build: invalid from flag value DOCKER_IMAGE_NAME_PHP: invalid reference format: repository name must be lowercase

In my docker-compose.yaml for the nginx part I have

nginx:
    build:
      context: .
      dockerfile: Dockerfile.static
    container_name: web-service
    working_dir: /var/www
    volumes:
      - .:/var/www
    environment:
      - "DOCKER_IMAGE_NAME_PHP=app-admin"
      - "DOCKER_IMAGE_NAME_NGINX=web-service"
    depends_on:
      - app
    ports:
      - 8090:80

I thought that setting the environment in the compose file would be enough, and that this will be used (the app-admin is the container_name of the php part with WordPress).

In my Jenkins pipeline scripts, these names are used to build the app and static images manually (using docker build -t DOCKER_IMAGE_NAME_PHP -f Dockerfile.php), and then the names are set to env like

echo -e "DOCKER_IMAGE_NAME_PHP=$DOCKER_IMAGE_NAME_PHP" >>env

EDIT

Like the answer suggested I've tried with adding args under build key

build:
  context: .
  dockerfile: Dockerfile.static
  args:
    - "DOCKER_IMAGE_NAME_PHP=app-admin"

Then in my Dockerfile I've added

FROM nginx:latest

COPY scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY ./config/nginx.conf /opt/nginx.conf
COPY ./config/nginx.conf.prd /opt/nginx.conf.prd

ARG DOCKER_IMAGE_NAME_PHP

COPY --from=$DOCKER_IMAGE_NAME_PHP /var/www/html/ /var/www/html/

CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]

But I still get the error. I've tried with ${DOCKER_IMAGE_NAME_PHP}, but that doesn't help.

The odd thing is that adding RUN echo $DOCKER_IMAGE_NAME_PHP, when I run this, I can see

Step 6/8 : RUN echo $DOCKER_IMAGE_NAME_PHP
 ---> Running in 0801fcd5b77f
app-admin

But it's not recognized in the COPY command. How come?

EDIT 2

So it turns out I cannot do this:

https://github.com/moby/moby/issues/34482

Because the --from expects the image name (which I'm trying to pass to it from the previously build service but in my case it's dynamic). This works in the Jenkins since I'm doing a docker build command, and the variables are available in the bash script...

2 Answers 2

2

COPY --from does not support variables, but FROM does.

the following example uses multi-stage build, to help you extract whatever you need from the first image.

ARG DOCKER_IMAGE_NAME_PHP=php:7.3
FROM ${DOCKER_IMAGE_NAME_PHP} as php-image
FROM nginx:latest

COPY scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY ./config/nginx.conf /opt/nginx.conf
COPY ./config/nginx.conf.prd /opt/nginx.conf.prd

COPY --from=php-image /var/www/html/ /var/www/html/

CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]

an almost similar example sits in the docs

Sign up to request clarification or add additional context in comments.

2 Comments

This seems to provide the image name correctly, I don't think that the previous stage was set, so I'll need to look into this a bit more. Thanks!
your image is built from the last base image you specified in the multistage dockerfile, in this case - only from the nginx image. the previous stages are only there so you can COPY --from them, as we did. thanx and good luck!
0

For that, you must use ARG in the Dockerfile.

https://docs.docker.com/engine/reference/builder/#arg

environment in docker-compose.yml is not available when you're building.

https://docs.docker.com/compose/compose-file/#environment

You can use arg in the docker-compose.yml too:

https://docs.docker.com/compose/compose-file/#args

2 Comments

I've added it as args under build key in the compose file, and I've added ARG DOCKER_IMAGE_NAME_PHP after FROM in my Dockerfile. When I do RUN echo ${DOCKER_IMAGE_NAME_PHP} I can see the desired output app-admin, but I still get an error when I have COPY --from=${DOCKER_IMAGE_NAME_PHP} /var/www/html/ /var/www/html/ (tried also without {} still get the same result). Any clues as to what I'm doing wrong?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.