Switching to Production Mode
What deploy:mode:set production really does, the files it writes, and why it is not a command you run on a live store.
bin/magento deploy:mode:set {developer|production} [-s|--skip-compilation]Magento runs in one of three application modes. In developer mode it writes generated classes and static view files as pages ask for them, and prints exceptions in the browser. default is the mode the installer leaves behind: the same runtime generation, with errors hidden. In production mode nothing is generated at runtime. The dependency injection classes under generated/ and the asset files under pub/static/ must already exist, and an uncaught exception becomes a file in var/report/ with a reference number on screen.
What the command does
bin/magento deploy:mode:set production first puts the site into maintenance mode itself, then records the mode in app/etc/env.php under the MAGE_MODE key — the write happens before any generation, so that the minified assets are produced — and only then deletes var/cache, generated/code, generated/metadata, var/view_preprocessed and pub/static (keeping only .htaccess files and deployed_version.txt) and runs setup:di:compile and setup:static-content:deploy as child commands, flushing the cache before each. bin/magento deploy:mode:show prints the current mode.
Why not on a live box
The store answers 503 for the whole switch, which is minutes at best. You get no control over that work: the static deploy it runs covers every theme, uses only the locales already in use, and takes no --jobs. If the compile fails, Magento puts the mode back and turns maintenance off again while pub/static and generated/ are still empty.
Switch the mode once, while the server is still out of the load balancer. After that, releases never touch it.
Example
# Magento root, run as the file system owner
bin/magento deploy:mode:show
# Current application mode: default. (Note: Environment variables may override this value.)
bin/magento deploy:mode:set production
# Enabling maintenance mode
# Starting compilation
# ...
# Compilation complete
# Starting deployment of static content
# ...
# Deployment of static content complete
# Disabling maintenance mode
# Enabled production mode.
bin/magento deploy:mode:show
# Current application mode: production. (Note: Environment variables may override this value.)When to use it
- Preparing a freshly built server before it takes its first real traffic.
- Reproducing a production-only bug, such as a missing static file, on a staging box.
- Checking which mode a server is in before you trust a template edit to appear.
- Moving a hand-built install off default mode without letting it compile unsupervised.
More examples
Set the mode, then do the slow work yourself
With --skip-compilation the command only writes MAGE_MODE to env.php; nothing is deleted and nothing is rebuilt. This is how most teams switch a box, because the bundled compile and static deploy accept no theme list and no job count. Run the two commands yourself immediately afterwards, or the box is in production mode with no generated code and every request fails.
# -s is the short form of --skip-compilation; they are the same option
bin/magento deploy:mode:set production -s
# now you choose the themes, locales, areas and parallelism
bin/magento setup:di:compile
bin/magento setup:static-content:deploy en_US de_DE \
--theme Vendor/storefront \
--theme Magento/backend \
--jobs 4
bin/magento cache:flushWhere the mode is recorded
Read this key when you need the mode and the CLI will not bootstrap. Because env.php is per machine, staging can sit in developer mode while production is in production mode from the same commit. Do not hand-edit the key to production: writing it does not compile anything, so the box ends up in production mode with empty generated/ and pub/static directories. deploy:mode:show also warns that an environment variable can override the file.
<?php
// app/etc/env.php (abbreviated) - this file is per machine and not in source control
return [
'MAGE_MODE' => 'production',
// 'db', 'crypt', 'cache_types', 'queue' and the rest of the file follow
];A release on a box that is already in production mode
Nothing here changes the mode. --keep-generated tells setup:upgrade not to clear the compiled code you just shipped; without it, a production box prints 'Please re-run Magento compile command. Use the command "setup:di:compile"' and you are down until you do. Adobe documents --keep-generated as production-only, so never use it in developer mode.
# the compile and static deploy already happened on the build machine
bin/magento maintenance:enable --ip=203.0.113.4
bin/magento setup:upgrade --keep-generated
bin/magento cache:flush
bin/magento maintenance:disable
Discussion