Build Dockerfile from YAML file

Hello,
A docker-compose.yaml file is as follows:

version: '3.9'
services:
  web:
    image: nginx:latest
    container_name: Nginx      
    ports:
      - '8080:80'
      - '443:443'
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - /var/www/html:/usr/share/nginx/html
    links:
      - php-fpm
  php-fpm:
    image: php:8-fpm
    container_name: PHP
    volumes:
       - /var/www/html:/usr/share/nginx/html/

I created a Dockerfile for the above file as follows:

FROM nginx:latest
WORKDIR /usr/share/nginx/html
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY /var/www/html .

FROM php:8-fpm
WORKDIR /usr/share/nginx/html
COPY /var/www/html .

Then I changed the YAML file as follows:

version: '3.9'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: Nginx      
    ports:
      - '8080:80'
      - '443:443'
    volumes:
      - /var/www/html:/usr/share/nginx/html
    links:
      - php-fpm
  php-fpm:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: PHP
    volumes:
       - /var/www/html:/usr/share/nginx/html/

Is it right?

Cheers.

It seems you want to use 2 different containers, so you need 2 different Dockerfiles. Either use different file names or place in different folders, using context.

1 Like

Hi,
Thank you so much for your reply.
How about:

FROM nginx:latest as Nginx
WORKDIR /usr/share/nginx/html
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY /var/www/html .

FROM php:8-fpm as PHP
WORKDIR /usr/share/nginx/html
COPY /var/www/html .

Then:

version: '3.9'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
      target: Nginx 
    container_name: Nginx         
    ports:
      - '8080:80'
      - '443:443'
    volumes:
      - /var/www/html:/usr/share/nginx/html
    links:
      - php-fpm
  php-fpm:
    build:
      context: .
      dockerfile: Dockerfile
      target: PHP
    container_name: PHP
       volumes:
       - /var/www/html:/usr/share/nginx/html/

Hello,
I created two Dockerfile files as follows:

FROM nginx:latest
WORKDIR /usr/share/nginx/html
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY /var/www/html .

And:

FROM php:8-fpm
WORKDIR /usr/share/nginx/html
COPY /var/www/html .

And I changed the YAML file as follows:

version: '3.9'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: Nginx
    ports:
      - '8080:80'
      - '443:443'
    volumes:
      - /var/www/html:/usr/share/nginx/html
    links:
      - php-fpm
  php-fpm:
    build:
      context: .
      dockerfile: Dockerfile2
    container_name: PHP
    volumes:
       - /var/www/html:/usr/share/nginx/html/

But I got the following error:

# docker compose up -d
[+] Building 0.8s (7/7) FINISHED                                                                                            docker:default
 => [php-fpm internal] load build definition from Dockerfile2                                                                         0.1s
 => => transferring dockerfile: 104B                                                                                                  0.0s
 => [php-fpm internal] load metadata for docker.io/library/php:8-fpm                                                                  0.0s
 => [php-fpm internal] load .dockerignore                                                                                             0.1s
 => => transferring context: 2B                                                                                                       0.0s
 => [php-fpm 1/3] FROM docker.io/library/php:8-fpm                                                                                    0.0s
 => CACHED [php-fpm 2/3] WORKDIR /usr/share/nginx/html                                                                                0.0s
 => [php-fpm internal] load build context                                                                                             0.1s
 => => transferring context: 2B                                                                                                       0.0s
 => ERROR [php-fpm 3/3] COPY /var/www/html .                                                                                          0.0s
------
 > [php-fpm 3/3] COPY /var/www/html .:
------
failed to solve: failed to compute cache key: failed to calculate checksum of ref 05bdcabe-9fee-48a5-80c5-5d701838afec::tci5qx6bge1f4iw080m5oyuhc: failed to walk /var/lib/docker/tmp/buildkit-mount167116853/var/www: lstat /var/lib/docker/tmp/buildkit-mount167116853/var/www: no such file or directory

What is wrong?

Which user do you use to build? root? If not, might be a permission problem.

Hello,
Thank you so much for your reply.
I executed that command (docker compose up -d) under the root user.

Any symlinks in /var/www/html?

Nothing. Only the following files:
index.html index.php

Does a local /var/www/html exist on host?

Why do you copy html files into nginx and php-fpm container?

Why do you use folder /usr/share/nginx/html/ in php-fpm container?

Why do you copy files in Dockerfile and bind mount files again in compose file?

Hi,
Thanks again.
1- Yes:

# ls /var/www/html/
index.html  index.php

2- Because I want to run those files through the web server.

3- To be able to run PHP files.

4- I don’t know if this is necessary or not.

I modified the YAML file as follows:

version: '3.9'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: Nginx
    ports:
      - '8080:80'
      - '443:443'
#    volumes:
#      - /var/www/html:/usr/share/nginx/html
    links:
      - php-fpm
  php-fpm:
    build:
      context: .
      dockerfile: Dockerfile2
    container_name: PHP
#    volumes:
#       - /var/www/html:/usr/share/nginx/html/

Then:

# docker compose up -d
 [+] Building 1.0s (7/7) FINISHED                                 docker:default => [php-fpm internal] load build definition from Dockerfile2              0.2s
 => => transferring dockerfile: 104B                                       0.0s
 => [php-fpm internal] load metadata for docker.io/library/php:8-fpm       0.0s
 => [php-fpm internal] load .dockerignore                                  0.1s
 => => transferring context: 2B                                            0.0s
 => [php-fpm 1/3] FROM docker.io/library/php:8-fpm                         0.0s
 => [php-fpm internal] load build context                                  0.1s
 => => transferring context: 2B                                            0.0s
 => CACHED [php-fpm 2/3] WORKDIR /usr/share/nginx/html                     0.0s
 => ERROR [php-fpm 3/3] COPY /var/www/html .                               0.0s
------
 > [php-fpm 3/3] COPY /var/www/html .:
------
failed to solve: failed to compute cache key: failed to calculate checksum of ref 05bdcabe-9fee-48a5-80c5-5d701838afec::gi3qmv9beu2l4vpa2vg57tebc: "/var/www/html": not found

Hello,
The problem is not related to volumes, and by the way, these should be active. I created a directory called www next to the docker-compose.yaml file and copied the files from the /var/www/html directory into it. I restored the YAML file to the previous state:

version: '3.9'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: Nginx
    ports:
      - '8080:80'
      - '443:443'
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - /var/www/html:/usr/share/nginx/html
    links:
      - php-fpm
  php-fpm:
    build:
      context: .
      dockerfile: Dockerfile2
    container_name: PHP
    volumes:
       - /var/www/html:/usr/share/nginx/html/

Then I modified the Dockerfiles as follows:

FROM nginx:latest
WORKDIR /usr/share/nginx/html
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY ../www/ .

And:

FROM php:8-fpm
WORKDIR /usr/share/nginx/html
COPY ../www/ .

The containers ran.

What is wrong with the /var/www/html directory?

Maybe docker compose and build doesn’t like to go out of context ., probably for security reasons.

I highly doubt that this will work:

The PHP image will never use a “nginx” folder by default. Check the docs.

And again: copy in Dockerfile and then you bind mount the same target again with volumes: in compose. That’s odd.

Hi,
Thanks again.
So why docker compose works easily with /var/www/html directory without using Dockerfile?

I have connected Nginx to PHP through the following lines and it works:

links:
      - php-fpm

If you use COPY in Dockerfile and do not use volumes in YAML file, then it will not work properly. You can try.

If you want to reduce complexity, just use PHP image with Apache included (php:<version>-apache, link), then you don’t need an additional web server.

1 Like

Hi,
Thanks again.
Why does this problem occur with Dockerfile?