If you are here, you must be finding the answer for “How to upgrade to Magento 2.3?”. In addition, you are ready to move from your 2.2.x store and upgrade to Magento 2.3. Found in this article a stronger & proven “why” for 2.3 upgrade: Why you need Magento 2.3.
As Magento 2.3 is the hottest trend these days, learning Magento 2.3 upgrade is necessary to make a fresh start for your web store. Soon, you will all need to switch to Magento 2.3 because the latest version always provide better supports and features.
In a hurry? There are 4 popular ways to upgrade to Magento 2.3:
- Upgrade Magento 2.3 with System Upgrade utility.
- Upgrade Magento 2.3 manually.
- Command-line upgrade.
- Upgrade via changing pre_composer_update_2.3.php script.
If you are wondering where to download Magento 2.3, Magestore also provide a huge resource to download any Magento versions.
Magento 2.3 Upgrade Requirements
You must meet the requirements to install/upgrade Magento 2.3.
1, Operating systems, Web servers, Database and php
To install Magento 2.3, you need a Linux-based operating system (Linux x86-64), such as RedHat Enterprise Linux (RHEL), CentOS, Ubuntu, Debian, and similar.
Also, the Web servers for Magento 2.3 is either Apache 2.2/2.4 or nginx 1.x.
For the Database, Magento 2.3 is compatible with MySQL 5.6 or 5.7, MySQL NDB Cluster 7.4.*, MariaDB 10.0, 10.1, 10.2, Percona 5.7, and other binary-compatible MySQL technologies.
Magento 2.3 only support php 7.1.3 and later, or php 7.2.
If you are reading how to upgrade to Magento 2.3 from Magento 2.2.x version, you can safely pass this step.
2, Version requirement to upgrade
To upgrade to Magento 2.3, you need current version of Magento to be 2.1.4 and later. If you are running a 2.1.3 and earlier version, you must upgrade to version 2.1.4 or later before you continue.
Prerequisites for Magento 2.3 Upgrade
Before running any System upgrade (which includes Magento 2.3 Upgrade), you must complete the task:
1, Set up cron for upgrade
To upgrade your system, you must have two cron jobs. Each cron job should run every minute.
The Magento crontab is inside #~ MAGENTO START and #~ MAGENTO END comments in your crontab.
To create the Magento crontab:
- Log in as, or switch to, the Magento file system owner.
- Change to your Magento installation directory.
- Enter the following command:
php bin/magento cron:install [--force]
Use –force to rewrite an existing Magento crontab.
After all, you can view the crontab via command:
crontab -l
2, Set ulimit for the web server user
Magento requires you to set the ulimit for the Magento file system user to a value of 65536 or more.
Why you need to set ulimit? Because a rollback to a previous backup can silently fail, resulting in incomplete data being written to the file system or database.
To set ulimit, you only need to follow this:
- Open in a text editor:
/home/<username>/.bashrc
- Add the following line:
ulimit -s 65536
- Save your changes to .bashrc and exit the text editor.
3, Set a value for DATA_CONVERTER_BATCH_SIZE
Magento 2.3 is the unique version with security enhancements that needs converting data from serialized format to JSON encoded format. If you have a large amount of data, you can improve performance by setting the value of an environment variable, DATA_CONVERTER_BATCH_SIZE. By default, it’s set to a value of 50,000.
You can set value for DATA_CONVERTER_BATCH_SIZE in a bash shell prompt:
$ export DATA_CONVERTER_BATCH_SIZE <value>
The value depends on you, we suggest you to set to 10000.
After upgrading to Magento 2.3, you can change back the variable as follows:
$ unset DATA_CONVERTER_BATCH_SIZE
Upgrade Magento 2.3 with System Upgrade utility
To run System Upgrade utility:
Step 1Log in to the Magento Admin as administrator.
Step 2Navigate System > Tools > Web Setup Wizard.
Source: Magento.com
Step 3Click System Configuration.
Check your authentication keys in the provided fields if possible. Below is an example if you have already entered your keys.
Source: Magento.com
Step 4Click Save Config.
Step 5Click System Upgrade.
Then, you need Magento to check the readiness. If you want to add other components, simply click Yes.
Source: Magento.com
After that, you are ready to upgrade to Magento 2.3.
Step 6Select versions to upgrade.
Source: Magento.com
Upgrade Magento 2.3 manually
If you use Magento Open Source and install the Magento Open Source GitHub repository via git clone, you are a contributing developer and can upgrade Magento 2.3 manually. Follow these steps to upgrade Magento 2.3 manually.
Step 1 Log in to your Magento server.
Step 2Save a backup for composer.json because the following steps will overwrite it. The commands are as below:
cd <your Magento install dir> cp composer.json composer.json.old
Step 3Update your local repository:
git pull origin develop
Step 4Merge both composer.json.old and composer.json
Step 5Use command:
composer update
Step 6Update the Magento database with this command:
php <your Magento install dir>/bin/magento setup:upgrade
Command-line upgrade
Also, you can upgrade Magento 2.3 with a command line.
Step 1Backup the existing composer.json file in the Magento installation directory.
Step 2Remove any unnecessary packages before upgrading to Magento 2.3.
$ composer remove --dev sjparkinson/static-review fabpot/php-cs-fixer --no-update
Step 3Then you need to deactivate the Magento Open Source update.
$ composer remove magento/product-community-edition --no-update
Step 4Indicate to Magento 2.3
1, For Magento Open Source
$ composer require magento/product-community-edition=2.3.0 --no-update
2, For Magento Commerce
$ composer require magento/product-enterprise-edition=2.3.0 --no-update
Specify additional packages
$ composer require --dev phpunit/phpunit:~6.2.0 friendsofphp/php-cs-fixer:~2.10.1 lusitanian/oauth:~0.8.10 pdepend/pdepend:2.5.2 sebastian/phpcpd:~3.0.0 squizlabs/php_codesniffer:3.2.2 --no-update
Step 5Open composer.json and edit the “autoload”
"autoload": { "psr-4": { "Magento\\Framework\\": "lib/internal/Magento/Framework/", "Magento\\Setup\\": "setup/src/Magento/Setup/", "Magento\\": "app/code/Magento/", "Zend\\Mvc\\Controller\\": "setup/src/Zend/Mvc/Controller/" }, ... }
Step 6Modify the Magento updater
You need to modify the Magento updater if it is installed (which located in <Magento install dir>/update). First, you need to backup and remove the old updater. Then, create a Composer project.
1, For Magento Open Source
$ composer create-project --repository=https://repo.magento.com magento/project-community-edition=2.3.0 temp_dir --no-install
2, For Magento Commerce
$ composer create-project --repository=https://repo.magento.com magento/project-enterprise-edition=2.3.0 temp_dir --no-install
Finally, move the new project to <Magento install dir>/update directory:
$ mkdir update $ mv temp_dir/update <Magento install dir>/update $ rm -rf temp_dir
Step 7Check metadata in “name“, “version“, and “description” fields in the <Magento install dir>/composer.json file. If everything is okay, apply update.
$ composer update
Step8Clear caches and generated content
$ rm -rf <Magento install dir>/var/cache/* $ rm -rf <Magento install dir>/var/page_cache/* $ rm -rf <Magento install dir>/generated/code/*
Step 9Update the database schema and data
$ php bin/magento setup:upgrade
Step 10Disable maintenance mode
$ php bin/magento maintenance:disable
Step 11Restart Varnish
$ service varnish restart
Upgrade via changing pre_composer_update_2.3.php script
This is the easiest and quickest way to upgrade to Magento 2.3. We all thanks other Magento developers (including Webkul) to share the upgrade. You can download, or copy, the script file from the magento/magento2 repo:
<a href="https://raw.githubusercontent.com/magento/magento2/2.3.0/dev/tools/UpgradeScripts/pre_composer_update_2.3.php" target="_blank" rel="noopener noreferrer">/dev/tools/UpgradeScripts/pre_composer_update_2.3.php</a>
Or simply change pre_composer_update_2.3.php to:
#!/usr/bin/php <?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); $_scriptName = basename(__FILE__); define( 'SYNOPSIS', <<<SYNOPSIS Updates Magento with 2.3 requirements that can't be done by `composer update` or `bin/magento setup:upgrade`. Run this script after upgrading to PHP 7.1/7.2 and before running `composer update` or `bin/magento setup:upgrade`. Steps included: - Require new version of the metapackage - Update "require-dev" section - Add "Zend\\Mvc\\Controller\\": "setup/src/Zend/Mvc/Controller/" to composer.json "autoload":"psr-4" section - Update Magento/Updater if it's installed - Update name, version, and description fields in the root composer.json Usage: php -f $_scriptName -- --root='</path/to/magento/root/>' [--composer='</path/to/composer/executable>'] [--edition='<community|enterprise>'] [--repo='<composer_repo_url>'] [--version='<version_constraint>'] [--help] Required: --root='</path/to/magento/root/>' Path to the Magento installation root directory Optional: --composer='</path/to/composer/executable>' Path to the composer executable - Default: The composer found in the system PATH --edition='<community|enterprise>' Target Magento edition for the update. Open Source = 'community', Commerce = 'enterprise' - Default: The edition currently required in composer.json --repo='<composer_repo_url>' The Magento repository url to use to pull the new packages - Default: The Magento repository configured in composer.json --version='<version_constraint>' A composer version constraint for allowable 2.3 packages. Versions other than 2.3 are not handled by this script See https://getcomposer.org/doc/articles/versions.md#writing-version-constraints for more information. - Default: The latest 2.3 version available in the Magento repository --help Display this message SYNOPSIS ); $opts = getopt('', [ 'root:', 'composer:', 'edition:', 'repo:', 'version:', 'help' ]); // Log levels available for use with output() function define('INFO', 0); define('WARN', 1); define('ERROR', 2); if (isset($opts['help'])) { output(SYNOPSIS); exit(0); } try { if (version_compare(PHP_VERSION, '7.1', '<') || version_compare(PHP_VERSION, '7.3', '>=')) { preg_match('/^\d+\.\d+\.\d+/',PHP_VERSION, $matches); $phpVersion = $matches[0]; throw new Exception("Invalid PHP version '$phpVersion'. Magento 2.3 requires PHP 7.1 or 7.2"); } /**** Populate and Validate Settings ****/ if (empty($opts['root']) || !is_dir($opts['root'])) { throw new BadMethodCallException('Existing Magento root directory must be supplied with --root'); } $rootDir = $opts['root']; $composerFile = "$rootDir/composer.json"; if (!file_exists($composerFile)) { throw new InvalidArgumentException("Supplied Magento root directory '$rootDir' does not contain composer.json"); } $composerData = json_decode(file_get_contents($composerFile), true); $metapackageMatcher = '/^magento\/product\-(?<edition>community|enterprise)\-edition$/'; foreach (array_keys($composerData['require']) as $requiredPackage) { if (preg_match($metapackageMatcher, $requiredPackage, $matches)) { $edition = $matches['edition']; break; } } if (empty($edition)) { throw new InvalidArgumentException("No Magento metapackage found in $composerFile"); } // Override composer.json edition if one is passed to the script if (!empty($opts['edition'])) { $edition = $opts['edition']; } $edition = strtolower($edition); if ($edition !== 'community' && $edition !== 'enterprise') { throw new InvalidArgumentException("Only 'community' and 'enterprise' editions allowed; '$edition' given"); } $composerExec = (!empty($opts['composer']) ? $opts['composer'] : 'composer'); if (basename($composerExec, '.phar') != 'composer') { throw new InvalidArgumentException("'$composerExec' is not a composer executable"); } // Use 'command -v' to check if composer is executable exec("command -v $composerExec", $out, $composerFailed); if ($composerFailed) { if ($composerExec == 'composer') { $message = 'Composer executable is not available in the system PATH'; } else { $message = "Invalid composer executable '$composerExec'"; } throw new InvalidArgumentException($message); } // The composer command uses the Magento root as the working directory so this script can be run from anywhere $composerExec = "$composerExec --working-dir='$rootDir'"; // Set the version constraint to any 2.3 package if not specified $constraint = !empty($opts['version']) ? $opts['version'] : '2.3.0-beta8'; // Composer package names $project = "magento/project-$edition-edition"; $metapackage = "magento/product-$edition-edition"; // Get the list of potential Magento repositories to search for the update package $mageUrls = []; $authFailed = []; if (!empty($opts['repo'])) { $mageUrls[] = $opts['repo']; } else { print_r($composerData['repositories']); foreach ($composerData['repositories'] as $label => $repo) { output($label); output(strpos($repo['url'], '.mage')); if (strpos(strtolower((string)$label), 'mage') !== false || strpos($repo['url'], '.mage') !== false) { $mageUrls[] = $repo['url']; } } if (count($mageUrls) == 0) { throw new InvalidArgumentException('No Magento repository urls found in composer.json'); } } $tempDir = findUnusedFilename($rootDir, 'temp_project'); $projectConstraint = "$project='$constraint'"; $version = null; $description = null; output("**** Searching for a matching version of $project ****"); // Try to retrieve a 2.3 package from each Magento repository until one is found foreach ($mageUrls as $repoUrl) { try { output("\\nChecking $repoUrl"); deleteFilepath($tempDir); output("create-project --repository=$repoUrl $projectConstraint $tempDir --no-install"); runComposer("create-project --repository=$repoUrl $projectConstraint $tempDir --no-install"); // Make sure the downloaded package is 2.3 $newComposer = json_decode(file_get_contents("$tempDir/composer.json"), true); $version = $newComposer['version']; $description = $newComposer['description']; if (strpos($version, '2.3.') !== 0) { throw new InvalidArgumentException("Bad 2.3 version constraint '$constraint'; version $version found"); } // If no errors occurred, set this as the correct repo, forget errors from previous repos, and move forward output("\\n**** Found compatible $project version: $version ****"); $repo = $repoUrl; unset($exception); break; } catch (Exception $e) { // If this repository doesn't have a valid package, save the error but continue checking any others output("Failed to find a valid 2.3 $project package on $repoUrl", WARN); $exception = $e; } } // If a valid project package hasn't been found, throw the last error if (isset($exception)) { throw $exception; } output("\\n**** Executing Updates ****"); $composerBackup = findUnusedFilename($rootDir, 'composer.json.bak'); output("\\nBacking up $composerFile to $composerBackup"); copy($composerFile, $composerBackup); // Add the repository to composer.json if needed without overwriting any existing ones $repoUrls = array_map(function ($r) { return $r['url']; }, $composerData['repositories']); if (!in_array($repo, $repoUrls)) { $repoLabels = array_map('strtolower',array_keys($composerData['repositories'])); $newLabel = 'magento'; if (in_array($newLabel, $repoLabels)) { $count = count($repoLabels); for ($i = 1; $i <= $count; $i++) { if (!in_array("$newLabel-$i", $repoLabels)) { $newLabel = "$newLabel-$i"; break; } } } output("\\nAdding $repo to composer repositories under label '$newLabel'"); runComposer("config repositories.$newLabel composer $repo"); } output("\\nUpdating Magento metapackage requirement to $metapackage=$version"); if ($edition == 'enterprise') { // Community -> Enterprise upgrades need to remove the community edition metapackage runComposer('remove magento/product-community-edition --no-update'); output(''); } runComposer("require $metapackage=$version --no-update"); output('\nUpdating "require-dev" section of composer.json'); runComposer('require --dev ' . 'phpunit/phpunit:~6.2.0 ' . 'friendsofphp/php-cs-fixer:~2.10.1 ' . 'lusitanian/oauth:~0.8.10 ' . 'pdepend/pdepend:2.5.2 ' . 'sebastian/phpcpd:~3.0.0 ' . 'squizlabs/php_codesniffer:3.2.2 --no-update'); output(''); runComposer('remove --dev sjparkinson/static-review fabpot/php-cs-fixer --no-update'); output('\nAdding "Zend\\\\Mvc\\\\Controller\\\\": "setup/src/Zend/Mvc/Controller/" to "autoload": "psr-4"'); $composerData['autoload']['psr-4']['Zend\\Mvc\\Controller\\'] = 'setup/src/Zend/Mvc/Controller/'; if (preg_match('/^magento\/project\-(community|enterprise)\-edition$/', $composerData['name'])) { output('\nUpdating project name, version, and description'); $composerData['name'] = $project; $composerData['version'] = $version; $composerData['description'] = $description; } file_put_contents($composerFile, json_encode($composerData, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT)); // Update Magento/Updater if it's installed $updateDir = "$rootDir/update"; if (file_exists($updateDir)) { $updateBackup = findUnusedFilename($rootDir, 'update.bak'); output("\\nBacking up Magento/Updater directory $updateDir to $updateBackup"); rename($updateDir, $updateBackup); output('\nUpdating Magento/Updater'); rename("$tempDir/update", $updateDir); } // Remove temp project directory that was used for repo/version validation and new source for Magento/Updater deleteFilepath($tempDir); output("\\n**** Script Complete! $composerFile updated to Magento version $version ****"); if (count($authFailed) > 0) { output('Repository authentication failures occurred!', WARN); output(' * Failed authentication could result in incorrect package versions', WARN); output(' * To resolve, add credentials for the repositories to auth.json', WARN); output(' * URL(s) failing authentication: ' . join(', ', array_keys($authFailed)), WARN); } } catch (Exception $e) { if ($e->getPrevious()) { $e = $e->getPrevious(); } try { output($e->getMessage(), ERROR, get_class($e)); output('Script failed! See usage information with --help', ERROR); if (isset($composerBackup) && file_exists($composerBackup)) { output("Resetting $composerFile backup"); deleteFilepath($composerFile); rename($composerBackup, $composerFile); } if (isset($updateBackup) && file_exists($updateBackup)) { output("Resetting $updateDir backup"); deleteFilepath($updateDir); rename($updateBackup, $updateDir); } if (isset($tempDir) && file_exists($tempDir)) { output('Removing temporary project directory'); deleteFilepath($tempDir); } } catch (Exception $e2) { output($e2->getMessage(), ERROR, get_class($e2)); output('Backup restoration or directory cleanup failed', ERROR); } exit($e->getCode() == 0 ? 1 : $e->getCode()); } /** * Gets a variant of a filename that doesn't already exist so we don't overwrite anything * * @param string $dir * @param string $filename * @return string */ function findUnusedFilename($dir, $filename) { $unique = "$dir/$filename"; if (file_exists($unique)) { $unique = tempnam($dir, "$filename."); unlink($unique); } return $unique; } /** * Execute a composer command, reload $composerData afterwards, and check for repo authentication warnings * * @param string $command * @return array Command output split by lines * @throws RuntimeException */ function runComposer($command) { global $composerExec, $composerData, $composerFile, $authFailed; $command = "$composerExec $command --no-interaction"; output(" Running command:\\n $command"); exec("$command 2>&1", $lines, $exitCode); $output = ' ' . join('\n ', $lines); // Reload composer object from the updated composer.json $composerData = json_decode(file_get_contents($composerFile), true); if (0 !== $exitCode) { $output = "Error encountered running command:\\n $command\\n$output"; throw new RuntimeException($output, $exitCode); } output($output); if (strpos($output, 'URL required authentication.') !== false) { preg_match("/'(https?:\/\/)?(?<url>[^\/']+)(\/[^']*)?' URL required authentication/", $output, $matches); $authUrl = $matches['url']; $authFailed[$authUrl] = 1; output("Repository authentication failed; make sure '$authUrl' exists in auth.json", WARN); } return $lines; } /** * Deletes a file or a directory and all its contents * * @param string $path * @throws Exception */ function deleteFilepath($path) { if (!file_exists($path)) { return; } if (is_dir($path)) { $files = array_diff(scandir($path), array('..', '.')); foreach ($files as $file) { deleteFilepath("$path/$file"); } rmdir($path); } else { unlink($path); } if (file_exists($path)) { throw new Exception("Failed to delete $path"); } } /** * Logs the given text with \n newline replacement and log level formatting * * @param string $string Text to log * @param int $level One of INFO, WARN, or ERROR * @param string $label Optional message label; defaults to WARNING for $level = WARN and ERROR for $level = ERROR */ function output($string, $level = INFO, $label = '') { $string = str_replace('\n', PHP_EOL, $string); if (!empty($label)) { $label = "$label: "; } else if ($level == WARN) { $label = 'WARNING: '; } else if ($level == ERROR) { $label = 'ERROR: '; } $string = "$label$string"; if ($level == WARN) { error_log($string); } elseif ($level == ERROR) { error_log(PHP_EOL . $string); } else { echo $string . PHP_EOL; } }
Also, you need to update composer.json like this.
{ "name": "magento/project-community-edition", "description": "eCommerce Platform for Growth (Community Edition)", "type": "project", "version": "2.3.0-beta8", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { "magento/product-community-edition": "2.3.0-beta8", "composer/composer": "@alpha" }, "require-dev": { "phpunit/phpunit": "~6.2.0", "squizlabs/php_codesniffer": "3.2.2", "phpmd/phpmd": "@stable", "pdepend/pdepend": "2.5.2", "friendsofphp/php-cs-fixer": "~2.10.1", "lusitanian/oauth": "~0.8.10", "sebastian/phpcpd": "~3.0.0" }, "autoload": { "psr-4": { "Magento\\Framework\\": "lib/internal/Magento/Framework/", "Magento\\Setup\\": "setup/src/Magento/Setup/", "Magento\\": "app/code/Magento/", "Zend\\Mvc\\Controller\\": "setup/src/Zend/Mvc/Controller/" }, "psr-0": { "": [ "app/code/", "generated/code/" ] }, "files": [ "app/etc/NonComposerComponentRegistration.php" ], "exclude-from-classmap": [ "**/dev/**", "**/update/**", "**/Test/**" ] }, "autoload-dev": { "psr-4": { "Magento\\Sniffs\\": "dev/tests/static/framework/Magento/Sniffs/", "Magento\\Tools\\": "dev/tools/Magento/Tools/", "Magento\\Tools\\Sanity\\": "dev/build/publication/sanity/Magento/Tools/Sanity/", "Magento\\TestFramework\\Inspection\\": "dev/tests/static/framework/Magento/TestFramework/Inspection/", "Magento\\TestFramework\\Utility\\": "dev/tests/static/framework/Magento/TestFramework/Utility/" } }, "minimum-stability": "beta", "repositories": [ { "type": "composer", "url": "https://repo.magento.com/" } ], "extra": { "magento-force": "override" } }
3 Comments
Great. But What about Your Omnichanell extension? Where can I expect support for Magento 2.3 ???
Hi Kris,
You’ll get the same support you’ve had for Omnichannel Solution, as well as all other products of Magestore. So no worries at all 🙂
For Magento 2.3, we are developing a specialized POS that makes a perfect combo for online-to-offline businesses. You can explore more info about our upcoming POS for magento 2.3 here For any other questions, please feel free to contact us We’ll be happy to clarify your concerns 🙂
Thank you for the steps. Very helpful. One observation The DATA_CONVERTER_BATCH_SIZE value should be 100000.
https://magento-devdocs.github.io/devdocs-for-tests/guides/v2.2/comp-mgr/cli/cli-upgrade.html
In ubuntu, the export command is below
export DATA_CONVERTER_BATCH_SIZE=100000