0

I'm having a problem installing laravel through a dockerfile. I'm using docker-compose that pulls a dockerfile where I basically have this:

FROM php:7.3-apache-stretch

*some apt-get and install composer*

WORKDIR /var/www

RUN composer create-project --prefer-dist laravel/laravel app

CMD apachectl -D FOREGROUND

but when I access the container and I will see the files that should have been created with the composer I see that it is empty even though I have seen the command executed in the container build.

The container is working perfectly and even I can access it ... only files that do not even appear.

If I run the composer command manually after the container is created the files appear.

2
  • Can you share the exact command you are running and the actual dockerfile script and maybe what the terminal is showing when it runs your composer command Commented Mar 28, 2019 at 14:00
  • the terminal output is gigantic ... I omitted the previous output to install the composer because it did not issue an error... gist.github.com/miguelsmuller/c4d5af821683547f77618274b0473352 Commented Mar 28, 2019 at 14:47

1 Answer 1

2

In your Dockerfile, you used WORKDIR /var/www and then RUN composer create-project ... which makes composer create files under /var/www on the container file system.

In your docker-compose.yml file you used to start your container:

version: '3.7'

services:
  app:
    container_name: "app"
    build:
      context: ./docker
      dockerfile: Dockerfile-app
    ports:
      - "80"
      - "443"
    restart: always
    depends_on:
      - db
    volumes:
      - ".:/var/www"

You are declaring a volume that will be mounted on that same location /var/www in your container.

What happens is that the volume content will take the place of whatever you had on /var/www in the container file system.

I suggest you read carefully the documentation regarding docker volumes, and more specifically the part titled Populate a volume using a container.


Now to move on, ask yourself why you needed that volume in the first place. Is it necessary to change files at run time ?

If not, just add your files at build time:

FROM php:7.3-apache-stretch

*some apt-get and install composer*

WORKDIR /var/www

RUN composer create-project --prefer-dist laravel/laravel app
COPY . /var/www

CMD apachectl -D FOREGROUND

and remove the volume for /var/www.


EDIT

Developing with the help of a Docker container

During development, you change php files on your docker host (assumed to be you development computer) and need to frequently test the result by testing your app served by the webserver from the docker container.

It would be cumbersome to have to rebuild a Docker image every time you need to test your app. The solution is to mount a volume so that the container can serve the files from your development computer:

FROM php:7.3-apache-stretch

*some apt-get and install composer*

WORKDIR /var/www
CMD apachectl -D FOREGROUND

and start it with:

version: '3.7'

services:
  app:
    container_name: "app"
    build:
      context: ./docker
      dockerfile: Dockerfile-app
    ports:
      - "80"
      - "443"
    restart: always
    depends_on:
      - db
    volumes:
      - ".:/var/www"
...

When you need to run some commands within that container, just use docker exec:

docker-compose exec app composer create-project --prefer-dist laravel/laravel app

Producing project artifacts

Since what you will be deploying is not a zip/tar archive containing your source code and configurations but a docker image, you need to build the docker image you will use at deployment time.

Dockerfile for production

For production use, you want to have a Docker image which holds all required files and does not need any docker volume, excepted for holding data produced by users (uploaded files, database files, etc)

FROM php:7.3-apache-stretch

*some apt-get and install composer*

WORKDIR /var/www

COPY . /var/www

CMD apachectl -D FOREGROUND

Notice that there is no RUN composer create-project --prefer-dist laravel/laravel app in this Dockerfile. This is because this command is to initialise your project and this is a development time task, not a deployment time task.

You will also need a place to host your docker images (a Docker registry). You can deploy your own registry as a Docker container using the official registry image, or use the one provided by companies:

So you need to build a docker image, and then push that image on your registry. Best practice is to automate those tasks with the help of continuous integration tools such as Jenkins, Gitlab CI, Travis CI, Circle CI, Google Cloud Build ...

Your CI job will run the following commands:

git clone <url of you git repo> my_app
cd my_app
git checkout <some git tag>
docker build -t <registry>/<my_app>:<version>
docker login <registry> --user=<registry user> --password=<registry password>
docker push <registry>/<my_app>:<version>

Deploying your Docker image

Start you container with:

version: '3.7'

services:
  app:
    container_name: "app"
    image: <registry>/<my_app>:<version>
    ports:
      - "80"
      - "443"
    restart: always
    depends_on:
      - db
...

Notice here that the docker-compose file does not build any image. For production it is a better practice to refer to an already built docker image (which has been deployed earlier on a staging environment for validation).

Sign up to request clarification or add additional context in comments.

5 Comments

Ok ... I understood ... I'll see the best solution then ... with regard to volume the justification is that the edition I make of my files is done through the host. any suggestion?
are you using this docker image for development or for running your app in production?
development...but an idea is to play in production without problems ...
In that case, I would make use of a volume on /var/www, remove RUN composer create-project --prefer-dist laravel/laravel app and COPY . /var/www from the Dockerfile. Start the container, then run docker exec <container_name> composer create-project --prefer-dist laravel/laravel app
I've edited my answer with guidelines for going to production with docker

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.