Dissecting Docker for Laravel: Your first command.

Docker was one of those tools that I kept putting off but wish I started using way earlier. In Dissecting Docker I will share bite size chunks of how I approached learning Docker.

Why I wanted to learn Docker.

After spending hours helping new team members getting set up with Virtual Machines (VMs); Shipping code that worked perfectly locally only to have things go sideways in production; and having to run multiple resource hungry VMs for different projects. Docker seemed like the next logical step. The idea of packaging everything up and shipping them across multiple environments (development, staging, and production) sounded pretty intriguing to me too.

What is Docker?

There are number of resources out there that do a great job of explaining what Docker is. So instead here are some resource you might find useful:

Installing Docker

Here are the instructions for installing Docker on:


Running your first docker command

When I first installed Docker I asked myself well what is the simplest thing I can do with Docker right now? The first thing that came mind was can I install Laravel with Composer running in a container?

Yes my friend you sure can!

Initially I thought I would have to build my own PHP image that included Composer but luckily this wasn’t the case. A quick search on https://hub.docker.com for “composer” and the first result I found was the official Composer repository.

After reading the instructions and a bit of trial and error I ran my first successful Docker command.

docker run --rm --interactive --tty \
--volume /home/alex/.composer:/composer \
--volume $PWD:/app \
--user $(id -u):$(id -g) \
composer create-project --prefer-dist laravel/laravel blog
Note: if you following along make sure to replace /home/alex/.composer with the path to your own composer home directory.

If you thinking “Whoa that was a lot of typing!” don’t worry I will show you how to shorten it ;) But let first explain what this command actually does.

  • docker run: run the command in new container using the image specified (composer).
  • --rm : as soon as the command has been executed delete the container.
  • --interactive --tty: both these flags together will start an interactive shell on the container.
  • --volume /home/alex/.composer:/composer : mount the local composer home directory /home/alex/.composer(replace this with your own) to the /composer directory inside the container. This is done to share caching between our local composer and the composer running in our container.
  • --volume $PWD:/app: mount the current working directory to the /app directory inside the container. If you type echo $PWD or just pwd inside your console this will print your current working directory.
  • --user $(id -u):$(id -g): by default commands are executed as root. This means if you don’t specify a user when composer creates the blog folder with all the Laravel files they will be owned by root. So you need to set the user to your current user_id:group_id where id -u prints your user id and id -g prints your group id. Again running echo $(id -u) or id -u inside the console will yield the same result.
  • composer create-project --prefer-dist laravel/laravel blog: I now how composer works so no explanation needed. Now hold your horses tiger there is some trickery happening here. Firstly composer here isn’t referring to the actual command itself but rather the image used to spin up the container. Hence on the first run you should see a message Unable to find image 'composer:latest' locally. At which point Docker will go ahead and pull the image in. The command you actually executing is create-project --prefer-dist laravel/laravel blog. So how does this actually work then? Well if you take a look at the Dockerfile used to build the Composer image. On the last line right at the bottom you will see CMD["composer"]. What this does is set the default command to composer when the container executes. So essentially composer will get prefixed to the command create-project --prefer-dist laravel/laravel.

The biggest take away here is after Docker has pulled in the image. It only takes a few seconds (precisely 8 seconds on my set up) to spin up a container, install Laravel and delete the container like it never existed in first the place. How long would it take to spin up a VM and execute the same command?

Hate installing crap on your system just play with a new shiny toy you probably never going to use again, Docker has your back!

Want to try out a new version of PHP or Node.js? Just grab the image off of Docker Hub and spin up a container. Also if you like me and hate installing crap on your system just play with a new shiny toy you probably never going to use again, Docker has you back!

Don’t run random Docker images on your system.
Daniel J Walsh

With all that said don’t go running random images on your system from third-parties you don’t trust. This would be the equivalent of running random commands in your console without having a clue as to what they do. You wouldn’t do that would you? I sure as heck hope you don’t! Security is something we will cover in more detail as we move forward.

Now before I forget here is the less verbose version of the command:

docker run --rm -it \
-v $COMPOSER_HOME/composer \
-v $PWD:/app \
-u $(id -u):$(id -g) \
composer create-project --prefer-dist laravel/laravel blog

If you haven’t already you will need to export COMPOSER_HOME by adding the below to your .bashrc or .zshrc file.

export COMPOSER_HOME=/path/to/composer/home 

Enjoyed this article…

If you enjoyed this article, hit that heart button below ❤ it lets me know you want to see more like this.

Also if learning how to build secure single page applications is something that sparks your interest. I am currently working on Looking at the Vue with Laravel.

Until next time, happy containerizing and thanks for reading!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.