What I'm trying to do
I'm trying to dockerize this php application builded on CodeIgniter 4. This app have the following dependencies which are normally installed via composer:
"require": {
"php": "^7.3 || ^8.0",
"myth/auth": "dev-develop",
"codeigniter4/framework": "^4.1",
"codeigniter4/translations" : "^4.0"
},
The project structure is organized as follows:
docker
database
nginx
php-fpm
docker-compose.yml
src
... app files ...
tests
composer.json
inside the docker-compose.yml
I have a service called php-fpm
which copies all the app files to /var/www/html
that is the nginx
public directory:
php-fpm:
container_name: boilerplate_app
build:
context: ./php-fpm
volumes:
- ../src:/var/www/html
What I need to do is install the application dependencies using composer.
What I tried
Initially, I though to do this inside the Dockerfile
available in php-fpm
folder:
FROM php:8.0.2-fpm-alpine
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli
# Install Composer
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN composer require --working-dir=../../ app/boilerplate
COPY ./config/php.ini /usr/local/etc/php/
CMD ["php-fpm"]
EXPOSE 9000
Essentially I have installed composer
in the container and then I tried to install all the dependencies from the composer.json
file available in the root of the project.
The issue
Unfortunately, when I run the command docker-compose up --build
this error is raised:
No composer.json present in the current directory (./composer.json), this may be the cause of the following exception.
seems that the container cannot access to the composer.json
file or I'm doing something bad with the path parameter working-dir
.
So, I though to another solution, define another container inside docker-compose.yml
which have the composer instance separated:
composer:
image: composer:2.0.9
command: ["composer", "require", "app/boilerplate"]
volumes:
- /var/www/html
This should read the composer.json
file from the root and then should install all the dependencies through the command composer require app/boilerplate
, but again, the same error is raised:
Composer could not find a
composer.json
file in/app
.
This is the full docker-compose.yml
:
version: '3'
services:
php-fpm:
container_name: boilerplate_app
build:
context: ./php-fpm
volumes:
- ../src:/var/www/html
nginx:
container_name: boilerplate_nginx
build:
context: ./nginx
volumes:
- ../src:/var/www/html
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/sites/:/etc/nginx/sites-available
- ./nginx/conf.d/:/etc/nginx/conf.d
ports:
- "8881:80"
- "8882:443"
depends_on:
- php-fpm
database:
container_name: boilerplate_db
build:
context: ./database
environment:
- MYSQL_DATABASE=boilerplate_db
- MYSQL_ROOT_PASSWORD=test
- MYSQL_USER=foo
- MYSQL_PASSWORD=test
volumes:
- ./database/data.sql:/docker-entrypoint-initdb.d/data.sql
composer:
image: composer:2.0.9
command: ["composer", "require", "app/boilerplate"]
volumes:
- /var/www/html
and this is the composer.json
file:
{
"name": "app/boilerplate",
"description": "CodeIgniter4 Boilerplate based on AdminLTE 3 with user management, roles, permissions, ...",
"require": {
"php": "^7.3 || ^8.0",
"myth/auth": "dev-develop",
"codeigniter4/framework": "^4.1",
"codeigniter4/translations" : "^4.0"
},
"require-dev": {
"phpunit/phpunit": "^9.1",
"fakerphp/faker": "^1.13"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"app\\boilerplate\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-update-cmd": [
"@composer dump-autoload"
],
"test": "phpunit --colors=always -vvv"
}
}
what I can do for fix the problem?
Folder structure image preview:
Seems you have a couple of problems.
First, you are relying on bind mounts. But those are available at run-time , but not at build-time .
So you need to copy the composer.*
files to your docker image before you run composer install
.
And then, you'll have trouble doing so because you moved the build context to a subdirectory of your project, which would make copying files from parent directories problematic.
To begin with, change the build context, and simply reference the Dockerfile
you need to build your project:
services:
php-fpm:
container_name: boilerplate_app
build:
dockerfile: ./php-fpm/Dockerfile
context: .
volumes:
- ./src:/var/www/html
# the rest of your docker-compose.yml
After you do this, you need to adjust your Dockerfile
to account that now its build context is one directory up, and add the required COPY
statements.
I've also updated the dockerfile to take advantage of Docker multi-stage process
FROM composer:2 as composer_stage
RUN rm -rf /var/www && mkdir -p /var/www/html
WORKDIR /var/www/html
COPY composer.json composer.lock ./
# This are production settings, I'm running with 'no-dev', adjust accordingly
# if you need it
RUN composer install --ignore-platform-reqs --prefer-dist --no-scripts --no-progress --no-interaction --no-dev --no-autoloader
RUN composer dump-autoload --optimize --apcu --no-dev
FROM php:8.0.2-fpm-alpine
WORKDIR /var/www/html
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli
COPY php-fpm/config/php.ini /usr/local/etc/php/
COPY --from=composer_stage /var/www/html /var/www/html
COPY src src/
CMD ["php-fpm"]
EXPOSE 9000
I've also added a COPY
statement to copy your projects src
dir, because otherwise the image you are building has your composer dependencies, and nothing else. This way your application is a properly self-contained container (no pun intended).
You should also make sure src
mountpoints. Since those do not really pertain to image building , but are only used when you are actually running the container, I didn't review them very carefully.
Dockerize/containerize an application is first and foremost about building the correct image, then you'll need to create the appropriate usage documentation
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.