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).


    image


    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

    deploy.sh


    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 liveintended when deploying the application for use as a store and is not considered in this example.


    Configuration script

    cfg.init.sh


    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.shor cfg.live.sh), and filled in with the appropriate parameters.


    Configuration template
    #!/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


    fix the place of the script in the hierarchy of other scripts
    # 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


    determine the script is run separately / in the package and load the config, if necessary
    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:


    image


    Optionally, you can apply patches both to third-party modules (as is the case with the flancer32/sample_mage2_mod_zipone 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

    deploy / bin / final.sh


    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 !!!


    Also popular now: