I am using php FPM alpine container with nginx alpine container for my laravel application.
Here is my Dockerfile,
FROM php:7.4-fpm-alpine
WORKDIR /usr/src/app
# install composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php --install-dir=/usr/local/bin --filename=composer
RUN php -r "unlink('composer-setup.php');"
# copy files
COPY ./ /usr/src/app/
# install packages
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN composer install
Here is my docker-compose file,
version: "3.7"
services:
web:
image: nginx:1.19-alpine
ports:
- 80:80
volumes:
- ../api:/usr/src/app
- ./site.conf:/etc/nginx/conf.d/site.conf
depends_on:
- api
api:
build: ../api
volumes:
- ../api:/usr/src/app
When I run docker-compose up --build the container build process works as you can see in the attached screenshot but the vendor directory was never created by the composer!?
Is it a known issue while using PHP FPM Alpine containers?
Also, when I access into the container using this command
docker exec -it docker_api_1 /bin/ash
and run composer install manually then everything works. Any suggestions are appreciated.
This is the error message when i visit the site. It can't find the composer autoload.php file,
Related
Im startig my journal with docker.
I made docker-compose.yml that starts following services:
nginx
PHP 8.1
I setup site to display and read php files, everything is ok. But right now I don't know whats next. I want to install laravel with composer and NPM. How to run it together in that way I can user "composer install", "composer update" in every project.
This is my docker-compose.yml:
services:
nginx:
container_name: nginx_tst
image: nginx:latest
networks:
- php
ports:
- "8080:80"
volumes:
- "./nginx-conf:/etc/nginx/conf.d"
- "./:/usr/share/nginx/html"
php:
container_name: php_tst
image: php:8.1-fpm
networks:
- php
volumes:
- "./:/usr/share/nginx/html"
working_dir: /
networks:
php:
Edit:
I Switched to Laravel Sail, it makes everything by itself
Add command attribute to the php service. Using that you can execute compose install and update commands and etc...
Follow this link to know how to execute multiple commands
Docker Compose - How to execute multiple commands?
You can use something like this.
command: curl -s https://laravel.build/example-app | bash
You can go inside the container
docker exec -it php_tst bash
and then install & run composer
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
php composer.phar install
install & run nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
nvm install node
node -v
npm i
npm run dev
I want to copy all files during the installation process in docker-compose.yml file.
If I run:
$ git clone https://github.com/laravel/laravel.git laravel-app
$ cd laravel-app
$ docker run --rm -v $(pwd):/app composer install
It will copy all new files from container to host during the installation process in the docker container.
So I will see new vendor folder and composer.lock file in my laravel-app directory after installation.
But if I setup volume in docker-compose.yml:
version: '3'
services:
#PHP Service
app:
build:
context: .
dockerfile: Dockerfile
container_name: app
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- app-network
And then setup installation process in Dockerfile:
FROM php:7.4.4-fpm
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Copy existing application directory contents
COPY . /var/www
# Install composer.json dependencies
RUN composer install # <<-- !this one!
It will not copy vendor folder and composer.lock file back to my host.
Hot to make it happen?
how about add composer docker image to your docker compose, and run command install
version: '3'
services:
#PHP Service
#your php image
# composer
composer:
image: composer/composer
volumes:
- ./:/var/www
command: install
You copy all build context into your image /var/www
You run composer install from the image, so vendor and composer.lock only exist in the image, not on your host
You bind mount your current directory(which has composer.json but not vendor and composer.lock) to /var/www, so it replaces the image /var/www
You know your issue, the fix depends on what you want to do exactly, tell me in a comment.
Tip: You should use Docker multi-stage builds to install Composer into your image. It's much cleaner than the curl
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY . /var/www/
RUN composer install --no-scripts --no-suggest --optimize-autoloader
I am trying to run a webserver container with nginx and a php-fpm server running a Laravel application. The directory houses a frontend and backend directory so my paths are not off in the configuration files.
I setup a docker-compose.yml file
version: '2'
services:
webserver:
build:
context: ./
dockerfile: webserver.docker
volumes:
- /home/colesam/Documents/code/todo/backend:/var/www
ports:
- "8080:80"
links:
- backend
backend:
build:
context: ./
dockerfile: backend.docker
volumes:
- ./home/colesam/Documents/code/todo/backend:/var/www
And php-fpm Dockerfile (backend.docker)
FROM php:7.2-fpm
RUN apt-get update -y && apt-get install -y libmcrypt-dev openssl
RUN pecl install mcrypt-1.0.2
RUN docker-php-ext-enable mcrypt
RUN docker-php-ext-install pdo mbstring
RUN apt-get install -y apt-transport-https
RUN apt-get install -y curl
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN chown -R www-data:www-data /var/www
VOLUME ["/var/www"]
RUN ls -al /var/www
WORKDIR /var/www
RUN composer install
And the nginx webserver Dockerfile (webserver.docker)
FROM nginx:1.10
ADD ./vhost.conf /etc/nginx/conf.d/default.conf
WORKDIR /var/www
For some reason when I run docker-compose up -d --build I always fail at this step of the build process:
Step 13/13 : RUN composer install
---> Running in 65bb97f03004
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Composer could not find a composer.json file in /var/www
To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section
ERROR: Service 'backend' failed to build: The command '/bin/sh -c composer install' returned a non-zero code: 1
From the last line of the output it looks like it failed because /var/www/was empty and didn't have the files copied over like composer.json. I looked around a lot and this stackoverflow issue seemed to be the most related to what was happening but I think I'm already following everything the accepted answer suggests.
Do I need to include a COPY or ADD command even though I'm mounting the folder through a volume?
The build phase does not see any mounted volumes. The only thing that is available to "build" are the things defined in the backend.docker and in the compose section of build:
build:
context: ./
dockerfile: backend.docker
Do I need to include a COPY or ADD command even though I'm mounting the folder through a volume?
Yes, modify your backend.docker similar to this
...
WORKDIR /var/www
ADD composer.json .
RUN composer install
I try to build a docker-compose project for a php application beside a database, which is automatically deployed on a developer machine. It's not a problem, but where it's stuck is the composer-install.
I want to have a directory from the host computer which is bind into the container, so developer are able to change code and are able to see it immediately in the docker instance. That means
Deploy a container with PHP and a webserver
Deploy the database
Bind the local source directory into the PHP container
Execute a composer-install in that directory
The directory tree is like
/
-php
-- src
-- Dockerfile
-postgres
-- Dockerfile
docker-compose.yml
I attached snippets from my docker-compose.yml and the PHP Dockerfile, anyone has an idea why it fails or see the problem in the order or something else or even can me explain what I have to notice? That would be great!
Dockerfile:
FROM xy
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
COPY ./src /var/www/html
WORKDIR /var/www/html/
RUN composer install --prefer-source --no-interaction
Docker-compose file:
version: '3.4'
services:
php:
build: ./php
container_name: "php"
volumes:
- ./php/src:/var/www/html
postgres:
image: postgres:10.4-alpine
container_name: "postgres"
I want to be able to use composer install inside my php-fpm container. My current setup:
docker-compose.yml
version: '2'
services:
web:
image: nginx
ports:
- "80:80"
volumes:
- ./public:/var/www/html
- ./vhost.conf:/etc/nginx/conf.d/vhost.conf
fpm:
image: php:fpm
volumes:
- ./public:/var/www/html
expose:
- 9000
composer:
restart: 'no'
image: composer/composer
command: install --working-dir=/var/www/html
volumes_from:
- fpm
But obviously my command: install is happening in the composer container and doesnt have the required php extensions to complete the install.
And composer install inside php-fpm container says composer is not installed
Somehow google doesn't have an answer for this from what I have seen.
You just need to install composer inside your fpm container.
Something like
FROM php:5.6-fpm
...
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');"
A more sexy way yo add composer into your image :
# Install Composer
ADD https://getcomposer.org/installer /tmp/composer-setup.php
RUN php /tmp/composer-setup.php --install-dir /usr/local/bin/ --filename composer \
&& rm /tmp/composer-setup.php
Note that composer can be useful for development images (eg: For Continuous Integration or tests). A production image should not have composer inside... Only the generated vendors :)
Actually what I would suggest would be a separate lightweight php-cli container just to run composer (and other commands). It doesn't have to run a "persistent" way. If interested have a look how I did my image for running php tasks like composer or phpunit.
docker run -ti --rm -v /path/to/your/project:/app kmwrona/ci-stack /usr/bin/composer install --quiet
docker run -ti --rm -v /path/to/your/project:/app kmwrona/ci-stack /usr/bin/composer dump-autoload --optimize
docker run -ti -a STDOUT -v /path/to/your/project:/app kmwrona/ci-stack /usr/bin/phpunit --log-junit /app/junit.xml --testdox-html /app/unit-tests-html-report.html