Deploy Magento 2 Development Applications
In light of the new Magento version 2.2.0 , which was released , I decided to post my personal experience in deploying applications based on this platform. The article describes the deployment of the application specifically for the development of modules, and not for the operation of the store (as they say, techies from the techie).
Introduction
After quite a long evolution of automation scripts for the Magento deployment process, I developed the following set, which I designed as a sample project: flancer32 / sample_mage2_app . The project raises an application for developing the public module "flancer32 / mage2_ext_login_as " (posted on Packagist ) and the "private" module " flancer32 / sample_mage2_mod_repo " (available only from GitHub 'a).
Scripts were created and tested under Ubuntu 16.04 / PHP 7.0.22 / Composer 1.5.2. The programs used in the scripts (php, composer, mysql, patch, ...) must be installed globally.
Access via the Composer to the corresponding repositories ( Magento and Github file ~/.composer/auth.json
) should be configured :
{
"http-basic": {
"repo.magento.com": {
"username": "ab8303e79d1b86ac2676cda700bb93eb",
"password": "00037fe23c3501389f08c7eaaab0cfda"
}
},
"github-oauth": {
"github.com": "9cde8d93840271c509d95707db07a9e1ef374014"
}
}
Please create your own access parameters and not use the values from the example.
Application components
In the most general case, a Magento application consists of the following parts:
- Magento 2 platform (typical modules);
- Native web application modules (including theme);
- Database;
- Media data
- Configuration;
Deployment sequence
The composition of the application sets the sequence of routine actions, reduced in the general case, to the following:
- Deployment configuration
- Deployment of the Magento2 platform
- installation of web application modules;
- database initialization;
- initialization of media files;
- finalization (setting access rights to files, etc.);
Script types
All deployment is performed using shell scripts, which can be divided into three groups:
- head script (
deploy.sh
); - configuration (
cfg.work.sh
); - worker (performs a certain part of the deployment work);
The scripts are not written in the style of user friendly , but rather in the style of friendly user - checking the input parameters and the compatibility of the requested modes of operation with each other is minimized. It is assumed that the user running the deployment script with the parameters understands what they mean and how they are compatible with each other.
Head script
Its task is to determine the deployment mode of the application, load the deployment configuration and run working scripts in accordance with the specified mode. Startup Parameters deploy.sh
:
$ sh deploy.sh -h
Magento2 application deployment script.
Usage: sh deploy.sh -d [work|live] -h -m [developer|production] -E -S
Where:
-d: Web application deployment mode ([work|live], default: work);
-h: This output;
-m: Magento 2itself deployment mode ([developer|production], default: developer);
-E: Existing DB will be used in'work' mode);
-S: Skip database initialization (Web UI should be used to init DB);
Deploying an application without initializing the database (the database is initialized via the Web UI):
$ sh deploy.sh -S
Deploying the application while maintaining the existing database (during redeployment, for example):
$ sh deploy.sh -E
Deploying an application with the translation of Magento 2 into production mode (if we are developing an API, for example):
$ sh deploy.sh -m production
The deployment mode is live
intended when deploying the application for use as a store and is not considered in this example.
Configuration script
Application deployment parameters are specified in a regular shell script as environment variables. The template ( cfg.init.sh
) containing all available variables is manually copied to the configuration file corresponding to the deployment mode ( cfg.work.sh
or cfg.live.sh
), and filled in with the appropriate parameters.
#!/usr/bin/env bash
# filesystem permissions
LOCAL_OWNER="owner"
LOCAL_GROUP="www-data"# Magento 2 installation configuration# see http://devdocs.magento.com/guides/v2.0/install-gde/install/cli/install-cli-install.html#instgde-install-cli-magento
ADMIN_EMAIL="admin@store.com"
ADMIN_FIRSTNAME="Store"
ADMIN_LASTNAME="Admin"
ADMIN_PASSWORD="..."
ADMIN_USE_SECURITY_KEY="0"
ADMIN_USER="admin"
BACKEND_FRONTNAME="admin"
BASE_URL="http://mage2.host.org:8080/"
CURRENCY="USD"
DB_HOST="localhost"
DB_NAME="mage2"
DB_PASS="..."
DB_USER="www"
LANGUAGE="en_US"
SECURE_KEY="..."
SESSION_SAVE="files"
TIMEZONE="UTC"
USE_REWRITES="0"
USE_SECURE="0"
USE_SECURE_ADMIN="0"
Working script
Working scripts contain an almost identical header, allowing
# current directory wherefrom script was launched (toreturntoin the end)
DIR_CUR="$PWD"
# Root directory (relative to the current shell script, notto the execution point)
# http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
DIR_ROOT=${DIR_ROOT:=`cd "$( dirname "$0" )/../../" && pwd`}
and
MODE=${MODE}
IS_CHAINED="yes"# 'yes' - this script is launched in chain with other scripts, 'no'- standalone launch;if [ -z "$MODE" ]; then
MODE="work"
IS_CHAINED="no"fi# check configuration file exists and load deployment config (db connection, Magento installation opts, etc.).
FILE_CFG=${DIR_ROOT}/cfg.${MODE}.sh
if [ -f "${FILE_CFG}" ]; thenif [ "${IS_CHAINED}" = "no" ]; then# this is standalone launch, load deployment configuration;echo"There is deployment configuration in ${FILE_CFG}."
. ${FILE_CFG}fielseif [ "${IS_CHAINED}" = "no" ]; then# this is standalone launch w/o deployment configuration - exit;echo"There is no expected configuration in ${FILE_CFG}. Aborting..."cd${DIR_CUR}exit 255
fifi
Deployment Configuration
Everything is simple here - a configuration script is launched that sets the appropriate environment variables:
FILE_CFG=${DIR_ROOT}/cfg.${MODE}.sh
if [ -f "${FILE_CFG}" ]
thenecho"There is deployment configuration in ${FILE_CFG}."
. ${FILE_CFG}elseecho"There is no expected configuration in ${FILE_CFG}. Aborting..."cd${DIR_CUR}exit 255
fi
Magento2 platform deployments
deploy / bin / app / mage.sh :
By and large it all comes down to creating in the corresponding directory ( work
)
DIR_MAGE=${DIR_ROOT}/${MODE}# root folder for Magento application
...
# (re)create root folder for application deploymentif [ -d "${DIR_MAGE}" ]; thenif [ "${MODE}" = "${MODE_WORK}" ]; thenecho"Re-create '${DIR_MAGE}' folder."
rm -fr ${DIR_MAGE}# remove Magento root folder
mkdir -p ${DIR_MAGE}# ... then create itfielse
mkdir -p ${DIR_MAGE}# just create folder if not existfiecho"Magento will be installed into the '${DIR_MAGE}' folder."
applications through Composer:
composer create-project--repository-url=https://repo.magento.com/ magento/project-community-edition=2.2.0 ${DIR_MAGE}
Thus, the root directory for configuring the web server: ${DIR_ROOT}/work
Installing web application modules
deploy / bin / app / own / work.sh
This part of the process depends on the deployment mode. First, the deployment descriptor of the application is tuned ( work/composer.json
) - here it is important to pay attention to the version of Composer (for example, it does not work on older versions composer config minimum-stability
):
echo "Configure composer.json"
composer config minimum-stability dev
echo "Add custom repositories"
composer config repositories.local '{"type": "artifact", "url": "../deploy/repo/"}' # relative to root Mage dir
then the necessary versions of the necessary modules are installed:
echo "Add own modules"
# public module from Packagist
composer require flancer32/mage2_ext_login_as:dev-master
# add private/public GitHub repo & install module from this repo
composer config repositories.sample_repo vcs https://github.com/flancer32/sample_mage2_mod_repo
composer require flancer32/sample_mage2_mod_repo:dev-master
# add zipped module fromlocal repository (see deploy/repo/sample_mage2_mod_zip-0.1.0.zip)
composer require flancer32/sample_mage2_mod_zip
In this case, we connected two development modules to the application:
- flancer32 / mage2_ext_login_as
- flancer32 / sample_mage2_mod_repo
It remains to indicate to the IDE that these modules are under version control:
Optionally, you can apply patches both to third-party modules (as is the case with the flancer32/sample_mage2_mod_zip
one installed from the zip), and to the source code of Magento itself (recently, the Magento Team has significantly improved its work with edits, but it’s still necessary to apply the well-known “tablet”, which was not included in the latest release):
echo"Apply patches"
patch vendor/flancer32/sample_mage2_mod_zip/etc/module.xml ${DIR_DEPLOY}/patch/mod_sequence.patch
In this case, a third- party module is patchedflancer32/sample_mage2_mod_zip
into which the boot order is added :
<modulename="Flancer32_SampleZip"setup_version="0.1.0"><sequence><modulename="Flancer32_SampleRepo"/></sequence></module>
Database initialization
deploy / bin / app / db / work.sh
Also depends on the deployment mode and startup keys deploy.sh
. There is a possibility when you need to recreate the database:
echo "Drop DB '${DB_NAME}'."
mysqladmin -f -u"${DB_USER}" -p"${DB_PASS}" -h"${DB_HOST}" drop "${DB_NAME}"
echo "Create DB '${DB_NAME}'."
mysqladmin -f -u"${DB_USER}" -p"${DB_PASS}" -h"${DB_HOST}" create "${DB_NAME}"
echo "DB '${DB_NAME}' is created."# Full list of the available options:# http://devdocs.magento.com/guides/v2.0/install-gde/install/cli/install-cli-install.html#instgde-install-cli-magento
php ${DIR_MAGE}/bin/magento setup:install \
--admin-firstname="${ADMIN_FIRSTNAME}" \
--admin-lastname="${ADMIN_LASTNAME}" \
--admin-email="${ADMIN_EMAIL}" \
--admin-user="${ADMIN_USER}" \
--admin-password="${ADMIN_PASSWORD}" \
--base-url="${BASE_URL}" \
--backend-frontname="${BACKEND_FRONTNAME}" \
--key="${SECURE_KEY}" \
--language="${LANGUAGE}" \
--currency="${CURRENCY}" \
--timezone="${TIMEZONE}" \
--use-rewrites="${USE_REWRITES}" \
--use-secure="${USE_SECURE}" \
--use-secure-admin="${USE_SECURE_ADMIN}" \
--admin-use-security-key="${ADMIN_USE_SECURITY_KEY}" \
--session-save="${SESSION_SAVE}" \
--cleanup-database \
--db-host="${DB_HOST}" \
--db-name="${DB_NAME}" \
--db-user="${DB_USER}" \
--db-password="${DB_PASS}"
or just connect the application to an existing database:
php${DIR_MAGE}/bin/magento setup:install \
--admin-firstname="${ADMIN_FIRSTNAME}" \
--admin-lastname="${ADMIN_LASTNAME}" \
--admin-email="${ADMIN_EMAIL}" \
--admin-user="${ADMIN_USER}" \
--admin-password="${ADMIN_PASSWORD}" \
--backend-frontname="${BACKEND_FRONTNAME}" \
--key="${SECURE_KEY}" \
--session-save="${SESSION_SAVE}" \
--db-host="${DB_HOST}" \
--db-name="${DB_NAME}" \
--db-user="${DB_USER}" \
--db-password="${DB_PASS}"
After connecting the application to the database, you can configure the database. For example, like this:
echo"Additional DB setup."
MYSQL_EXEC="mysql -u ${DB_USER} --password=${DB_PASS} -D ${DB_NAME} -e "${MYSQL_EXEC}"REPLACE INTO core_config_data SET value = '1', path ='fl32_loginas/controls/customers_grid_action'"
In version 2.2.0, it is possible to register configuration parameters via the CLI, but directly in the database you can set not only these parameters, but also much more (for example, set tax rates).
Initializing Media Files
In general, when you deploy a store with a theme, you need to initialize media files (from backup or cloning from a reference server). When developing modules, you can skip this step. Skipping.
Finalization
The finalization can be divided into two parts: specific to the deployment mode and general.
deploy / bin / app / final / work.sh
Depending on the mode, you can translate the application into developer / production mode, enable / disable the cache, and compile the code:
if [ "${OPT_MAGE_RUN}" = "developer" ]; then
php ${DIR_MAGE}/bin/magento deploy:mode:set developer
php ${DIR_MAGE}/bin/magento cache:disable
php ${DIR_MAGE}/bin/magento setup:di:compile
else
php ${DIR_MAGE}/bin/magento deploy:mode:set production
fi
and run the commands of the installed modules:
if [ "${OPT_USE_EXIST_DB}" = "no" ]; then
php ${DIR_MAGE}/bin/magento fl32:init:catalog
php ${DIR_MAGE}/bin/magento fl32:init:customers
php ${DIR_MAGE}/bin/magento fl32:init:sales
fi
In the end, it is advisable to run cron at least once and perform reindexing (to reduce abuse in the admin panel):
php${DIR_MAGE}/bin/magento indexer:reindex
php ${DIR_MAGE}/bin/magento cron:run
General deployment finalization includes setting file permissions:
if [ -z "${LOCAL_OWNER}" ] || [ -z "${LOCAL_GROUP}" ] || [ -z "${DIR_MAGE}" ]; thenecho"Skip file system ownership and permissions setup."elseecho"Set file system ownership (${LOCAL_OWNER}:${LOCAL_GROUP}) and permissions to '${DIR_MAGE}'..."
chown -R ${LOCAL_OWNER}:${LOCAL_GROUP}${DIR_MAGE}
find ${DIR_MAGE} -type d -exec chmod 770 {} \;
find ${DIR_MAGE} -type f -exec chmod 660 {} \;
fi# setup permissions for critical files/folders
chmod u+x ${DIR_MAGE}/bin/magento
chmod -R go-w ${DIR_MAGE}/app/etc
Conclusion
The process of deploying an application based on Magento 2 described in the article is not universal and can be modified depending on the project.
As stated in ancient times, the next version of Windows can begin to be used after the release of the second service pack. All involved - with the release of Magento 2.2.0! And the Magento Team - perseverance and optimism in this hopelessly lost struggle with the insurmountable code complexity and treachery of requirements !!!