Laravel + Docker Using Alpine
There are already a lot of images built for Laravel to run using Alpine image. This time I tried to make my own docker container for Laravel using Alpine.
Step 1 — Laravel Installation
I’m using the usual way to install Laravel.
composer create-project laravel/laravel docker-alpine
That would create a docker-alpine
directory of Laravel latest release with dependencies installed.
Step 2 — Create docker-compose.yml file
First, go to docker-alpine
directory and create docker-compose.yml
file, start it with:
version: '2'services:
# our services goes here...
I will separate this into 3 services:
app
container to run and execute PHP script,web
container to run NGINX,database
container to handle our database.
App Service
Add this lines below services:
Notes:
dockerfile: app.dockerfile
Dockerfile used to build ourapp
service.working_dir: /var/www/html
set default working directory inside container../:/var/www/html
mount current directory, in this case all ofdocker-alpine
content, to/var/www/html/
inside the container.- Set
environment
to match database container that will be added later.
Now create app.dockerfile
forapp
container.
Notes:
php:7-fpm-alpine
is used here.- The rest is used to compile all php extension needed, and remove the apk cache to reduce container size.
- For line 31, we need to copy
supervisord-app.conf
to/etc/supervisord.conf
. It will be used bysupervisor
for its configuration. It will later createsupervisord.log
in root directory. - Update, there is an issue when installing
mcrypt
usingphp 7.2
because it is not provided with thephp 7.2
source. Usepecl install mcrypt-1.0.1
then enabled it withdocker-php-ext-enable mcrypt.
NGINX-Alpine
The next container is web
container to handle serving static files, and pass-through request that will be handled by Laravel.
Notes:
- It is the same as
app
container before, butweb.dockerfile
will be used instead. app
will be used forvolumes_from
becauseweb
container will inherit/var/www/html
directory fromapp
container.- map port
8080
on the host to80
in the container so we can use0.0.0.0:8080
orlocalhost:8080
to access the container.
Next, create web.dockerfile
.
Notes:
nginx-alpine
will be used here.supervisor
will be installed here to lognginx
activity.- On line 5 add new user and group to because
nginx:alpine
doesn’t come with default user. - Add
nginx.conf
to configure server. - The rest is the same like
app.dockerfile
Below is supervisord-web.conf
file.
And createnginx.conf
.
Notes:
- On
events
you can add anyevents
configuration or you can leave it blank inside. I’ve tried adding and leaving it blank andnginx
still working fine. - At line 15 and 19 I add some
location
to add header for.css
and.js
files because in my case,nginx
read it as plain text files. - And the rest is just standard
nginx
configuration.
MYSQL
Now, create database
container to handle our data. We create a new volume so our files created in the container persist and allowing us to stop or restart our service without losing our data.
Notes:
- In the bottom, make new volume. In this case I create
dbdata
. This volume will be used later to mount directory/var/lib/mysql
which defined atdatabase
volumes. - Image used here is
mysql:5.7
. In this test I am using Laravel 5.5 and I encountered an error when doingartisan migrate
command. Explanation in this link - Set required environment variables, and make sure that your Larave
.env
database configuration to follow this environment configuration later. - Set port mapping
33061
on the host to3306
of the container. This will allow external tools to access the database.
Final docker-compose.yml file will looks like this:
Starting Services
From the first step to mysql part, make sure that all of these file is exist inside root directory:
docker-compose.yml
app.dockerfile
andweb.dockerfile
supervisord-app.conf
andsupervisord-web.conf
nginx.conf
Then run docker-compose -f docker-compose.yml up
. It will take some time for all of the service to download all of the package it need to set the container up.
Final Step, Laravel Setup
This steps below is automatically done if you grab Laravel source code using composer create-project
or if you already did composer install
inside your working directory.
- Copy
.env.example
=>.env
. - Run
php artisan key:generate
this can be done inside the container usingdocker exec -it app sh
whereapp
is our Laravel php container or by usingdocker exec app php artisan key:generate
. - Run
php artisan optimize
this can be done just like above.
After that you can tried to test your Laravel installation by going to http://0.0.0.0:8080
or http://localhost:8080
.
Important things in development
- If you always using
artisan
you can use that command inside your container by usingdocker exec -it <your-container-name> sh
or by usingdocker exec <your-container-name> php artisan <artisan-command>
. Using-it
means it will execute your given command interactively inside container. - Running
composer
inside your container is possible if you add `COPY --from=composer:1.5 /usr/bin/composer /usr/bin/composer
inside yourapp.dockerfile
, but you will encounter with permission issue. You can usecomposer
image to do this.
Last but not least, thanks to Shane Osbourne for this awesome guide!
Happy Coding