Magento 2.3 Apache Docker Image
Although we can install Docker and Docker Compose from the official Ubuntu repositories, they are several minor versions behind the latest release. So, we’ll install Docker following the official documentation page (https://docs.docker.com/install/linux/docker-ce/ubuntu/).
# Uninstall old versions
$ sudo apt-get remove docker docker-engine docker.io containerd runc
# Update the apt package index
$ sudo apt-get update
# Install packages to allow apt to use a repository over HTTPS:
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# Add Docker’s official GPG key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Use the following command to set up the stable repository.
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# Update the apt package index.
$ sudo apt-get update
# Install the latest version of Docker CE and containerd
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
Verify that Docker CE is installed correctly by running the hello-world image.
$ sudo docker run hello-world
This command downloads a test image and runs it in a container. When the container runs, it prints an informational message and exits.
Now Docker CE is installed and running.
Enable the docker system service to start docker when the system boots:
$ sudo systemctl enable docker
To disable this behavior, use disable instead.
$ sudo systemctl disable docker
By default, you need to use sudo to run Docker commands.
If you don’t want to use sudo when you use the docker command, create a Unix group called docker and add users to it.
Warning:
The docker group is root-equivalent; see Docker Daemon Attack Surface details and this blogpost on Why we don’t let non-root users run Docker in CentOS, Fedora, or RHEL.
To create the docker group and add your user:
1- Add the docker group if it doesn’t already exist
$ sudo groupadd docker
2- Add your user to the docker group.
$ sudo usermod -aG docker $USER
Other optional configuration steps: (https://docs.docker.com/install/linux/linux-postinstall/)
In order to manage and execute docker-compose files we need to install the Docker Compose package.
The command below is slightly different than the one you’ll find on the Releases page. By using the -o flag to specify the output file first rather than redirecting the output, this syntax avoids running into a permission denied error caused when using sudo.
Go to https://docs.docker.com/release-notes/docker-compose/ and look for the last release of docker-compose.
We’ll check the current release and if necessary, update it in the command below:
$ sudo curl -L https://github.com/docker/compose/releases/download/1.23.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
Next we’ll set the permissions:
sudo chmod +x /usr/local/bin/docker-compose
Then we’ll verify that the installation was successful by checking the version:
docker-compose --version
This will print out the version we installed:
Output
docker-compose version 1.23.0, build a133471
Create the following folder structure in our workspace folder.
# Recommended path: ~/workspace/{project_name}/
- data // mysql data, apache log files...
|-- apache
|-- elasticsearch
|-- mysql
|-- redis
- docker // Our magento2 docker project
- src // Magento 2 source code
$ mkdir -p data/apache data/elasticsearch data/mysql data/redis docker src
Clone the Docker project
$ git clone git@github.com:jcastellanos926/magento2-docker.git docker
Create the .env file from .env.sample and configure it.
$ cp .env.sample .env
$ gedit .env
Go to the docker folder and execute:
$ docker-compose build
$ docker-compose up -d
Install Magento 2 using composer.
$ docker exec -it web bash
$ composer create-project --repository=https://repo.magento.com/ magento/project-community-edition .
$ composer install
Change apache user as the file owner of our files and set the right permissions following the official Magento documentation
$ docker exec -it web bash
$ chown -R www-data:www-data .
$ find var generated vendor pub/static pub/media app/etc -type f -exec chmod u+w {} +
$ find var generated vendor pub/static pub/media app/etc -type d -exec chmod u+w {} +
$ chmod u+x bin/magento
Edit the /etc/hosts file in your local machine to point your custom domain names to localhost
# Magento 2 project
127.0.0.1 local-m2.com
127.0.0.1 db
127.0.0.1 redis
Copy .htaccess and .gitignore and files from the magento2 github repository to your project.
$ curl -O https://raw.githubusercontent.com/magento/magento2/2.3-develop/.htaccess
$ curl -O https://raw.githubusercontent.com/magento/magento2/2.3-develop/.gitignore
$ chown www-data:www-data .gitignore .htaccess
$ chmod 644 .gitignore .htaccess
Open your browser and go to your configured localhost domain
Follow the installation wizard. Use the previously configured database credentials.
Alternatively, we can install Magento using an installation script.
Open the file web/bin/install
and put your database and Admin User credentials.
Restart the Docker containers to be sure that your changes were applied successfully.
$ docker-compose restart
To execute, run:
$ docker exec -it web install
Look for your repo.magento.com credentials in the auth.json file and run:
$ docker exec -it web bash
$ magento sampledata:deploy
$ magento setup:upgrade
$ magento cache:clean
Follow 1-4 Creating a new Magento steps
Clone your Magento project into the src folder
$ docker exec -it web bash
$ git clone {your-project-repo} .
$ composer install
Change apache user as the file owner of our files and set the right permissions following the official Magento documentation
$ docker exec -it web bash
$ chown -R www-data:www-data .
$ find var generated vendor pub/static pub/media app/etc -type f -exec chmod u+w {} +
$ find var generated vendor pub/static pub/media app/etc -type d -exec chmod u+w {} +
$ chmod u+x bin/magento
Import the database of your project
mysql -umagento -hdb -p magento < yourdatabase.sql
Put the magento database credentials in your app/etc/env.php file. By default:
'db' => [
'table_prefix' => '',
'connection' => [
'default' => [
'host' => 'db',
'dbname' => 'magento',
'username' => 'magento',
'password' => 'magento',
'active' => '1'
]
]
]
Add the following lines to app/etc/env.php
'cache_types' => [
'config' => 1,
'layout' => 1,
'block_html' => 1,
'collections' => 1,
'reflection' => 1,
'db_ddl' => 1,
'compiled_config' => 1,
'eav' => 1,
'customer_notification' => 1,
'config_integration' => 1,
'config_integration_api' => 1,
'full_page' => 1,
'config_webservice' => 1,
'translate' => 1,
'vertex' => 1
],
Execute:
$ magento config:set --scope=default --scope-code=0 system/full_page_cache/caching_application 2
The following commands will edit the app/etc/env.php file to enable the Redis cache.
Configure Redis default caching
$ bin/magento setup:config:set --cache-backend=redis --cache-backend-redis-server=redis --cache-backend-redis-db=0
Configure Redis page caching
$ bin/magento setup:config:set --page-cache=redis --page-cache-redis-server=redis --page-cache-redis-db=1
Configure Magento to use Redis for session storage
$ bin/magento setup:config:set --session-save=redis --session-save-redis-host=redis --session-save-redis-log-level=3 --session-save-redis-db=2
Clean cache storage manually to apply changes
$ rm -rf var/cache/*
Links and verification instructions:
Remove the semicolons (;) from opcache.ini file and reload apache
service apache2 reload
Add the following to docker-compose.yml
varnish:
build:
context: ./varnish/
container_name: varnish
depends_on:
- web
volumes:
- ./varnish/default.vcl:/etc/varnish/default.vcl
- ./varnish/varnish:/etc/default/varnish
- ./varnish/supervisord.conf:/etc/supervisor/conf.d/supervisord.conf
ports:
- "80:80"
- "6082:6082"
networks:
- magento2
Change the port of the web docker service from 80:80
to 8080:8080
Sources:
In admin panel, go to Stores - Settings - Configuration - Catalog - Catalog Search
Configure:
Click on Test connection and Save Config.
Reindex catalog data.
$ magento indexer:reindex
$ magento cache:clean
Verify that Elasticsearch is working:
$ docker exec -it elasticsearch bash
$ curl http://localhost:9200/_cat/health?v&pretty
If correct, a message similar to the following will be displayed:
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks
1519701563 03:19:23 elasticsearch green 1 1 0 0 0 0 0 0
Sources:
Enable or disable Xdebug
# Enable
$ docker exec -it web xdebug-enable
# Disable
$ docker exec -it web xdebug-disable
Links:
To enable or disable the html profiler:
# enable
$ magento bin/magento dev:profiler:enable html
# disable
$ magento bin/magento dev:profiler:disable
# refresh varnish cache
$ docker restart varnish
To use the SQL profiler add the following code to the app/etc/env.php
'profiler' => [
'class' => '\Magento\Framework\DB\Profiler',
'enabled' => true,
],
# For example:
'db' => [
'table_prefix' => 'mlx_',
'connection' => [
'default' => [
'host' => 'db',
'dbname' => 'magento',
'username' => 'magento',
'password' => 'magento',
'model' => 'mysql4',
'engine' => 'innodb',
'initStatements' => 'SET NAMES utf8;',
'active' => '1',
'profiler' => [
'class' => '\Magento\Framework\DB\Profiler',
'enabled' => true,
],
]
]
],
Paste the following code in the index.php after $bootstrap->run($app)
;
/** @var \Magento\Framework\App\ResourceConnection $res */
$res = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Framework\App\ResourceConnection');
/** @var Magento\Framework\DB\Profiler $profiler */
$profiler = $res->getConnection('read')->getProfiler();
echo "<table cellpadding='0' cellspacing='0' border='1'>";
echo "<tr>";
echo "<th>Time <br/>[Total Time: ".$profiler->getTotalElapsedSecs()." secs]</th>";
echo "<th>SQL [Total: ".$profiler->getTotalNumQueries()." queries]</th>";
echo "<th>Query Params</th>";
echo "</tr>";
foreach ($profiler->getQueryProfiles() as $query) {
/** @var Zend_Db_Profiler_Query $query*/
echo '<tr>';
echo '<td>', number_format(1000 * $query->getElapsedSecs(), 2), 'ms', '</td>';
echo '<td>', $query->getQuery(), '</td>';
echo '<td>', json_encode($query->getQueryParams()), '</td>';
echo '</tr>';
}
echo "</table>";
Source:
$ php bin/magento deploy:mode:set developer