-
Create new laravel project
composer create-project --prefer-dist laravel/laravel laravel-docker
-
Create file
/docker/DockerfileFROM php:7.3-apache-stretch -
Run:
docker build -t laravel-docker -f docker/Dockerfile .-t laravel-docker: tag name-t-f docker/Dockerfile: file location-f.: build context (current directory)
-
Run:
docker run --rm -it laravel-docker /bin/bash
--rmremove container after running-itinteractive mode- Useful commands:
php --version: get php versionapachectl -S: debug your virtual host configurationVirtualHost configuration: *:80 172.17.0.2 (/etc/apache2/sites-enabled/000-default.conf:1) ServerRoot: "/etc/apache2" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/var/log/apache2/error.log" Mutex watchdog-callback: using_defaults Mutex default: dir="/var/run/apache2/" mechanism=default Mutex mpm-accept: using_defaults PidFile: "/var/run/apache2/apache2.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG User: name="www-data" id=33 Group: name="www-data" id=33
Apache with a Dockerfile
-
FROM php:7.2-apache COPY src/ /var/www/html/
Info
- To see how to copy files/folders between a container and the local filesystem :
docker cp --help
- Let's try to copy a file from our container to local dir
/docker
-
1 - run the container in detach mode
docker run --rm -d laravel-docker
-
2 - list running containers
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1ef089b57ad6 laravel-docker "docker-php-entrypoi…" 6 seconds ago Up 2 seconds 80/tcp happy_cray -
3 - SSH into container
docker exec -it 1e bash -
4 - Get file path we want to copy
apachectl -S
filepath:
/etc/apache2/sites-enabled/000-default.confand it's a symlink Get real filepath:root@1ef089b57ad6:/var/www/html# ls -la /etc/apache2/sites-enabled/000-default.conf lrwxrwxrwx 1 root root 35 Mar 31 19:09 /etc/apache2/sites-enabled/000-default.conf -> ../sites-available/000-default.conf -
5 - Copy the file:
docker cp 1e:/etc/apache2/sites-available/000-default.conf docker/vhost.conf
- Important:
1eis the CONTAINER_ID (docker ps)
- Important:
-
Run our application:
-
Setup our config:
FROM php:7.3-apache-stretch COPY . /var/www/html COPY /docker/vhost.conf /etc/apache2/sites-available/000-default.conf
- IMPORTANT: Build may takes few minutes because of
RUN chown -R www-data:www-data /var/www/html
- IMPORTANT: Build may takes few minutes because of
-
run command
docker build -t laravel-docker -f docker/Dockerfile . Sending build context to Docker daemon 46.19MB Step 1/3 : FROM php:7.3-apache-stretch ---> 2cef340dd582 Step 2/3 : COPY . /var/www/html ---> c105e8508c01 Step 3/3 : COPY /docker/vhost.conf /etc/apache2/sites-available/000-default.conf ---> 24df67826119 Successfully built 24df67826119 Successfully tagged laravel-docker:latest
-
run our container:
docker run --rm -p 8080:80 laravel-docker
-
http://localhost:8080Error!UnexpectedValueException The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied http://localhost:8080/
-
-
Enable mod_rewrite
-
SSH into our container:
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8184a8219ba8 laravel-docker "docker-php-entrypoi…" 4 seconds ago Up 1 second 0.0.0.0:8080->80/tcp stupefied_mclean docker exec -it 81 bash
-
List apache modules
a2enmod Your choices are: access_compat actions alias allowmethods asis auth_basic auth_digest auth_form authn_anon authn_core authn_dbd authn_dbm authn_file authn_socache authnz_fcgi authnz_ldap authz_core authz_dbd authz_dbm authz_groupfile authz_host authz_owner authz_user autoindex buffer cache cache_disk cache_socache cern_meta cgi cgid charset_lite data dav dav_fs dav_lock dbd deflate dialup dir dump_io echo env expires ext_filter file_cache filter headers heartbeat heartmonitor http2 ident imagemap include info lbmethod_bybusyness lbmethod_byrequests lbmethod_bytraffic lbmethod_heartbeat ldap log_debug log_forensic lua macro mime mime_magic mpm_event mpm_prefork mpm_worker negotiation php7 proxy proxy_ajp proxy_balancer proxy_connect proxy_express proxy_fcgi proxy_fdpass proxy_ftp proxy_hcheck proxy_html proxy_http proxy_http2 proxy_scgi proxy_wstunnel ratelimit reflector remoteip reqtimeout request rewrite sed session session_cookie session_crypto session_dbd setenvif slotmem_plain slotmem_shm socache_dbm socache_memcache socache_shmcb speling ssl status substitute suexec unique_id userdir usertrack vhost_alias xml2enc Which module(s) do you want to enable (wildcards ok)?
-
Enable
rewritemodule$ a2enmod rewrite Enabling module rewrite. To activate the new configuration, you need to run: service apache2 restart
-
Add
a2enmod rewriteto our '/docker/Dockerfile' -
We can disable
.htaccessand move its content tovhostconfiguration indocker/Dockerfile/vhost
-
-
Now we will translate command
docker run --rm -p 8080:80 laravel-dockertodocker-composefile! -
Create
docker-compose.yamlversion: "3" services: app: image: laravel-www container_name: laravel-www build: context: . dockerfile: docker/Dockerfile ports: - 8080:80
-
After creating the file rebuild and run the container in detached mode:
docker-compose up --build -d
-
Now we can SSH into container using the service name
appdocker-compose exec app /bin/bash
-
-
FIX AN ISSUE
- Dockerfile - Speed Up The Setting of Permissions
The
COPYdocker command supports--chownwhich removes the need to do this as a separateRUNstep- Change this:
COPY . /var/www/html RUN chown -R www-data:www-data /var/www/html
- To this:
COPY --chown=www-data:www-data . /var/www/html
- Change this:
- Dockerfile - Speed Up The Setting of Permissions
The
-
Create
.dockerignorefile/.idea /.git /node_modules- Before the docker CLI sends the context to the docker daemon, it looks for a file named
.dockerignorein the root directory of the context. If this file exists, the CLI modifies the context to exclude files and directories that match patterns in it
- Before the docker CLI sends the context to the docker daemon, it looks for a file named
version: "3"
services:
app:
image: laravel-www
container_name: laravel-www
build:
context: .
dockerfile: docker/Dockerfile
ports:
- 8080:80
mysql:
container_name: laravel-mysql
image: mysql:5.7
environment:
MYSQL_DATABASE: homestead
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: homestead
MYSQL_PASSWORD: secret
ports:
- 13306:3306-
Install pdo_extension
- file
/docker/DockerfileRUN docker-php-ext-install pdo_mysql - TO check that it's installed, SSH into our container and run:
php -m | grep mysql
- file
-
Build app, SSH into container and run migration!
docker-compose up --build -d docker-compose exec app bash php artisan migrate -
Connect to mysql server:
docker-compose exec mysql bashmysql -u homestead -p
-
Add volume for mysql Now mysql data won't be lost when we run
docker-compose down!version: "3" services: app: image: laravel-www container_name: laravel-www build: context: . dockerfile: docker/Dockerfile ports: - 8080:80 mysql: container_name: laravel-mysql image: mysql:5.7 volumes: - mysql:/var/lib/mysql environment: MYSQL_DATABASE: homestead MYSQL_ROOT_PASSWORD: root MYSQL_USER: homestead MYSQL_PASSWORD: secret ports: - 13306:3306 volumes: mysql: driver: "local"
-
It's important to read Laravel documentation:
- Before using Redis with Laravel, we encourage you to install and use the
PhpRedis PHP extensionviaPECL. The extension is more complex to install but may yield better performance for applications that make heavy use of Redis. - Alternatively, you can install the
predis/predispackage via Composer:
composer require predis/predis
- Don't forget to add
REDIS_CLIENT=predisto your.env
- Before using Redis with Laravel, we encourage you to install and use the
-
version: "3" services: app: depends_on: - mysql - redis image: laravel-www container_name: laravel-www build: context: . dockerfile: docker/Dockerfile ports: - 8080:80 mysql: container_name: laravel-mysql image: mysql:5.7 volumes: - mysql:/var/lib/mysql environment: MYSQL_DATABASE: homestead MYSQL_ROOT_PASSWORD: root MYSQL_USER: homestead MYSQL_PASSWORD: secret ports: - 13306:3306 redis: container_name: laravel-redis image: redis:4-alpine ports: - 16379:6379 volumes: - redis:/data volumes: mysql: driver: "local" redis: driver: "local"
-
To test redis on our application:
- SSH into our app
docker-compose exec app bash php artisan tinker Redis::set('name', 'adam'); Redis::get('name');