Skip to content
Advertisement

From which Dockerfile should composer install be called from

I need to call composer install and unsure from which Dockerfile to call it from – Dockerfile-apache or Dockerfile-php-fpm?

Should I install composer in Dockerfile-apache (and PHP CLI?) and run it from there?

Running composer install from Dockerfile-php-fpm gives me this: Composer could not find a composer.json file in /var/www/html

Docker-php-fpm

# Do we target a specific version? ie. 7.4.25?
FROM php:7.4-fpm

# Need to add zip and other extensions
RUN buildDeps=" 
        libonig-dev 
        libzip-dev 
        libxml2-dev  
    "  
&& apt-get -y update 
&& apt-get install -y $buildDeps zip libicu-dev  
&& docker-php-ext-configure intl 
&& docker-php-ext-install intl mbstring json mysqli opcache pdo pdo_mysql xml  
&& apt-get purge -y --auto-remove $buildDeps 
&& rm -r /var/lib/apt/lists/*

# Copying of base conf files
COPY docker/php-fpm/conf/php-fpm.conf /usr/local/etc
COPY docker/php-fpm/conf/php.ini-development /usr/local/etc/php/php.ini
COPY docker/php-fpm/conf/www.conf /usr/local/etc/php-fpm.d

# Install Composer.
RUN curl -sS https://getcomposer.org/installer | php 
        && mv composer.phar /usr/local/bin/ 
        && ln -s /usr/local/bin/composer.phar /usr/local/bin/composer

EXPOSE 9000

Docker-apache:

FROM httpd:2.4

# Copy config files
COPY docker/apache/conf/httpd.conf /usr/local/apache2/conf
COPY docker/apache/conf/httpd-vhosts.conf /usr/local/apache2/conf/extra

# Do something about log rotate?

# Create vhost directory
WORKDIR /var/www/html

#Set our application folder as an environment variable
ENV APP_HOME /var/www/html

#copy files
COPY bin ${APP_HOME}/bin
COPY config ${APP_HOME}/config
COPY plugins ${APP_HOME}/plugins
COPY src ${APP_HOME}/src
COPY webroot ${APP_HOME}/webroot
COPY .htaccess ${APP_HOME}
COPY index.php ${APP_HOME}
COPY composer.json ${APP_HOME}
COPY composer.lock ${APP_HOME}

Edit #1

docker-compose.yml

version: "3.2"
services:
  php-fpm:
    container_name: php-fpm
    build:
      context: .
      dockerfile: Dockerfile-php-fpm
    networks:
      - backend
    ports:
      - "9000:9000"
  apache:
    container_name: httpd
    build:
      context: .
      dockerfile: Dockerfile-apache
    depends_on:
      - php
    networks:
      - frontend
      - backend
    ports:
      - "80:80"
      - "443:443"
networks:
  frontend:
  backend:

Edit #2

This docker-compose file enables the communication via a common volume. I just need to compile, build and copy the files in Apache at this point.

version: "3.9"
services:
  php-fpm:
    container_name: php-fpm
    build:
      context: .
      dockerfile: Dockerfile-php-fpm
    volumes:
      - mydata:/var/www/html:rw
    networks:
      - backend
    ports:
      - "9000:9000"
  apache:
    container_name: httpd
    build:
      context: .
      dockerfile: Dockerfile-apache
    depends_on:
      - php
    volumes:
      - mydata:/var/www/html:rw
    networks:
      - frontend
      - backend
    ports:
      - "80:80"
      - "443:443"
networks:
  frontend:
  backend:
volumes:
  mydata:

Advertisement

Answer

I would go with neither of the above; instead, run composer install locally and copy the resulting vendor directory as part of your application.

Fetching dependencies is fundamentally part of building an application, not part of running it, so Composer shouldn’t even be installed on a production host or container. If you were writing a C application which needed to be compiled with gcc, you would run that as an earlier step, and then copy the binary into the container; composer install can be treated the same way.

So for instance, you might have a build script (to run manually, or in a CI server like Jenkins, Github Actions, Azure DevOps, etc) that went through the following steps:

  1. Clone the repo from a git repository
  2. Check out the latest tag
  3. Run composer install
  4. Run a script to minify the client-side JS
  5. Run docker-composer, copying the source code, minified JS, and vendor directory

The software inside the Docker container therefore only needs to be able to run the application, not build it.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement