I'm trying to Dockerize my laravel app. The app is already built and in git, but I .gitignore my vendor folder. I've added a Dockerfile, which looks like this:
FROM php:7.1-fpm-alpine
RUN apk update && apk add curl && \
curl -sS https://getcomposer.org/installer | php \
&& chmod +x composer.phar && mv composer.phar /usr/local/bin/composer
RUN apk --no-cache add --virtual .build-deps $PHPIZE_DEPS \
&& apk --no-cache add --virtual .ext-deps libmcrypt-dev freetype-dev \
libjpeg-turbo-dev libpng-dev libxml2-dev msmtp bash openssl-dev pkgconfig \
&& docker-php-source extract \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ \
--with-png-dir=/usr/include/ \
--with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install gd mcrypt mysqli pdo pdo_mysql zip opcache \
&& pecl install mongodb redis xdebug \
&& docker-php-ext-enable mongodb \
&& docker-php-ext-enable redis \
&& docker-php-ext-enable xdebug \
&& docker-php-source delete \
&& apk del .build-deps
WORKDIR /var/www/html
COPY composer.json composer.lock ./
RUN composer install --no-scripts --no-autoloader
COPY . .
RUN chmod +x artisan
RUN composer dump-autoload --optimize && composer run-script post-install-cmd
CMD php artisan serve --host 0.0.0.0 --port 5001
When I build, this seems to work great. I see the dependencies getting downloaded, I see the autoload file being generated in the output. However, once the build is complete, the vendor folder is not actually there. I'm guessing it was all done in an intermediate container which was then removed? So when I run docker-compose up, I get: Fatal error: require(): Failed opening required '/var/www/html/bootstrap/../vendor/autoload.php'
This thread seems to point to the issue - possibly - but doesn't really provide a solution: Composer install doesn't install packages when running in Dockerfile
If you installed Docker Desktop/Toolbox for either Windows or Mac, you already have Docker Compose! Play-with-Docker instances already have Docker Compose installed as well. If you are on a Linux machine, you will need to install Docker Compose.
A Dockerfile is a simple text file that contains the commands a user could call to assemble an image whereas Docker Compose is a tool for defining and running multi-container Docker applications. Docker Compose define the services that make up your app in docker-compose.
In fact, they should not be. You don't need testing dependencies or direct access. They should be as similar as possible, differing only in the environment variables provided to each. Automated tests are executed on staging, but they should not require the setup to be different from production.
For example, you can install composer to /usr/local/bin on a desktop by running the following curl command as root. To install it in a custom Docker image just prepend "RUN" and stick it into a Dockerfile:
Create a file called docker-compose.yml in your project directory and paste the following: This Compose file defines two services: web and redis. The web service uses an image that’s built from the Dockerfile in the current directory.
Also, you can only have one CMD, which is the command that needs to execute when the container starts. In order to execute other commands when building the container, you need to use the RUN command. So your Dockerfile can look like this: Thanks for contributing an answer to Stack Overflow!
Copy the current directory . in the project to the workdir . in the image. Set the default command for the container to flask run. For more information on how to write Dockerfiles, see the Docker user guide and the Dockerfile reference. Create a file called docker-compose.yml in your project directory and paste the following:
This took a lot of digging for someone new to Docker :) Thanks to @iurii-drozdov for pointing me in the right direction with the comment about the docker-compose.yml.
In my docker-compose.yml, I was mounting my host working dir into /var/www/html. This happened after the build. So composer ran the install, installed all the dependencies correctly on build, and then, when running docker-compose up, I was mounting my host dir into the container and wiping all those changes out.
The solution was to run composer install after mounting the volume. It's straight forward enough to do this by simply exec'ing into the container after bringing it up - running composer and any other package managers - then finally running the web server.
However, I found a neater solution. I changed my final CMD in the Dockerfile to:
CMD bash -c "composer install && php artisan serve --host 0.0.0.0 --port 5001"
This will run composer install and bring up the web server as a final part of the docker-compose up.
Credit for the solution here: Docker - Execute command after mounting a volume
You can also use the official dockerhub composer image.
This is an example of a multi-stage build with composer running first in a separate container. The resulting /app/vendor
is copied to wherever you want in your final image.
FROM composer as builder
WORKDIR /app/
COPY composer.* ./
RUN composer install
...
FROM php:7.1-fpm-alpine
...
COPY --from=builder /app/vendor /var/www/vendor
If you don't want to have the command in the Dockerfile, we found that the simplest way was to add this to our docker-compose file:
composer_installation:
container_name: composer_installation
image: composer
volumes:
- ./:/app
command: composer install --ignore-platform-reqs
The update is a bit slow, probably because it is syncing with the PHP container.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With