Operate Magento
synsmarts builds Magento from your Composer project and deploys the resulting immutable application image. MySQL, Redis, OpenSearch, Nginx, PHP, scheduled jobs, and optional Varnish are managed services around that image.
Prepare the source
Section titled “Prepare the source”A Magento deploy must contain:
composer.jsonat the selected source root;bin/magento;- application modules, themes, patches, and configuration required by the release.
Include composer.lock for a reproducible dependency set and commit it when
using Git. A build can proceed without it, but dependency resolution can change
between otherwise identical deploys.
A Workspace transfer may include the production vendor/ tree. synsmarts
reuses it only when it passes four checks:
- Composer’s installed metadata exactly matches every production package in
composer.lock; - the autoloader and package install paths exist inside the source;
- Composer validates manifest/lock consistency;
- the selected PHP runtime satisfies the installed requirements.
Symlinked metadata, or an incomplete or mismatched vendor tree, is discarded
and rebuilt with Composer. When the tree passes validation, synsmarts includes vendor/ in the
image build even if the source .dockerignore excludes it. Use .deployignore
to omit vendor/ from the Workspace snapshot when you want Composer to rebuild
dependencies instead.
When the selected source doesn’t contain a validated complete vendor/, store
your Adobe Commerce Marketplace credentials as the COMPOSER_AUTH build secret
under Vars and secrets. Its value is the complete
Composer authentication JSON, including the repo.magento.com http-basic
public and private keys. A validated complete vendor build doesn’t read or
mount Composer credentials.
Understand the build
Section titled “Understand the build”The platform-managed Magento build performs the production preparation steps, including:
- exact production lock/package/install-path validation and
composer check-platform-reqs --no-devwhen a completevendor/is supplied, or authenticatedcomposer install --no-devwhen dependencies must be rebuilt; - module enablement when
app/etc/config.phpis absent, with admin two-factor authentication and sample-data modules disabled. A committedconfig.phpis kept as your module list, including its two-factor setting, and the build fails if it omits a module that exists in your code (MAGENTO_CONFIG_PHP_MODULES_MISSINGnames the modules). If your committed file enables two-factor authentication while your store currently runs with it disabled, the first deploy after this change re-enables it; make sure an admin has an authenticator configured before you deploy; - optimized Composer autoload generation;
- dependency-injection compilation;
- static-content deployment for every theme, in
en_USplus each locale set at the default, website, or store view scope and each admin user’s interface locale. The deploy reads those locales from your database before the build and adds the locales committed inapp/etc/config.php. If the database can’t be read, the build deploysen_USand theconfig.phplocales only.
Don’t add a second production compilation sequence after deployment. Changes to Composer dependencies, generated code, or static assets belong in the next selected source and build.
Apart from merged CSS and JavaScript, which Magento writes to
pub/static/_cache on request, the storefront serves only the static files
your last build produced. A locale you set on a store view or admin user after that deploy has no
stylesheets or scripts until the next deploy, so pages in that locale render
unstyled. Deploy after changing a locale. The CSS and JavaScript minification
settings under Stores > Configuration > Advanced > Developer
behave the same way: set in the admin, they make pages link .min files the
build didn’t produce. Commit them to app/etc/config.php with
bin/magento config:set --lock-config so the build produces those files.
The web server runs your release on a read-only filesystem. At request time
it can write to your shared paths, to the
rest of var/, and to /tmp. Outside the shared paths, var/ and /tmp
start empty on each pod and aren’t shared between pods. A module that writes
anywhere else while serving a request fails with Read-only file system;
point it at var/ or make its directory a shared path.
Choose the source for each release
Section titled “Choose the source for each release”Each release explicitly uses Git or Workspace:
- Choose Git when the intended Magento project is a branch, tag, or commit in the connected repository.
- Choose Workspace when the intended project is the current server-side file tree prepared through SSH or another deployment tool.
When a repository is connected, both sources remain available. A Workspace deploy doesn’t commit its files to Git. A later successful Git deploy refreshes non-preserved Workspace code from the built release on a best-effort, non-gating basis and can remove changes that exist only in Workspace. A refresh failure leaves the Git release live and can leave older Workspace code. Make the equivalent repository change when it must survive future Git releases.
Use an exact Git commit SHA when you need a reproducible Git release.
Deploy a release
Section titled “Deploy a release”- Update the source intended for the release and
composer.lock. - Confirm either the source contains the complete production
vendor/tree orCOMPOSER_AUTHis configured and current. - Run Magento tests, static analysis, and dependency checks.
- Deploy the selected Git revision or prepared Workspace.
- Follow build, migration classification, migration, rollout, and verification in the deploy detail.
- Test storefront, admin, checkout, customer login, search, media, cache, and scheduled work.
How Magento database changes are detected
Section titled “How Magento database changes are detected”The deploy first decides whether the selected source changed a migration-bearing path.
- A Git deploy compares the currently serving commit with the resolved candidate commit.
- A Workspace deploy compares its Workspace schema fingerprint with the serving Git commit when that baseline is available.
- A Workspace snapshot containing
.deployignorecan’t produce a trustworthy schema fingerprint because ignored paths could hide migration files. It is treated as unknown rather than code-only.
Migration-bearing paths include composer.json, composer.lock,
db_schema.xml, db_schema_whitelist.json, module.xml, app/etc/,
Setup/, Patch/, theme.xml, a theme’s registration.php, queue*.xml,
communication.xml, indexer.xml, and mview.xml. A change limited to theme
files or those four declarations takes the additive path with no schema change
to apply.
When a migration-bearing path changed, synsmarts builds the new image and
compares its post-build schema inventory with the serving image. The
inventory records the schema declaration Magento resolves from the enabled
modules at build, so the comparison includes Composer-installed modules under
vendor/.
Changes limited to added tables, a nullable or defaulted column, non-unique
indexes, or a varchar widened without crossing 255 bytes in the table’s
character set can be additive. Any column data-type change, such as int to
bigint or a varchar growing past 255 bytes, uses breaking treatment, as do
drops, renames, other existing-column changes, constraint changes,
whitelist-only changes, or changed Setup or Patch PHP. Additive DDL on an
existing table estimated above 1,000,000 rows
also uses maintenance. Any unavailable or ambiguous static evidence becomes a
breaking or unknown candidate. The status probe then decides whether
that candidate needs a maintenance window.
For example, this declaration can be additive when the target table is below the live-DDL threshold and the rest of the inventory remains compatible:
<?xml version="1.0"?><schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <table name="acme_order"> <column xsi:type="varchar" name="external_reference" nullable="true" length="64" comment="External reference"/> </table></schema>Every Magento deploy, code-only included, runs a release Job on the new image
before traffic moves. The Job refuses a database whose schema is newer than the
release’s code. It imports the release’s committed configuration with
bin/magento app:config:import, runs setup:upgrade when the deploy path
requires it, and registers themes. It then requests each store’s home page,
one product page, and one category page from the new release; an error status
or Magento’s error page fails the deploy, and the previous release keeps
serving.
A code-only deploy takes no backup and no maintenance window. It uses the
maintenance-window path instead when the database still has pending changes
from an earlier failed release, or when the committed config.php would delete
or rename an existing store or website.
Additive, breaking, and unknown deploys take a pre-migration backup before the migration Job runs. Additive deploys take it first, then pause scheduled work and run the managed migration Job while the previous release keeps serving.
Breaking and unknown candidates first run a separate status probe from the new image. The probe runs before customer notification, the maintenance page, scheduled-work pause, or the real migration Job. A clean schema promotes with no maintenance window or notification. When migration is required or the probe is unavailable, synsmarts pauses scheduled work, including queue consumers, sends the notification, enters maintenance, waits until visitors receive the maintenance page, takes the pre-migration backup, and runs the managed migration Job:
bin/magento setup:db:statusIf the database isn’t current, the Job runs
bin/magento setup:upgrade --keep-generated from the new image and verifies
database status again.
The Job reads app/etc/config.php from the release image, so modules and
themes added in this release are installed and registered by this deploy. A
deploy that adds only a theme also runs the Job and registers the theme. Before
its first database change the Job writes and deletes one test object in media
storage; if that fails, the deploy stops before any database change. The Job
needs the store’s cloud identity; a store whose identity is missing fails the
deploy before any change, and support restores it.
- Additive: the old release keeps serving with no planned interruption. If
the migration fails, synsmarts doesn’t restore the backup because that would
discard live writes. Schema changes and data patches that completed stay
applied and are listed in deploy details; deploy the same source again to
finish, and don’t expect a rollback of that deploy. When the deploy details
say the applied changes are unknown, contact support before deploying again.
Before changing anything, the Job asks Magento what
setup:upgradewould change in the live database. If that includes anything beyond the additive changes above, such as dropping the tables of a module you disabled or a column another module marksdisabled="true", the deploy uses the maintenance-window path instead. If the database still has pending changes from an earlier failed release, the deploy uses the maintenance-window path too, with a fresh backup taken once the maintenance page is up. When the only failure is a brief lock wait on Magento’s indexer triggers, the Job runssetup:upgradeonce more; a second wait moves the deploy to the maintenance-window path. - Breaking or unknown: a clean status probe promotes without a maintenance window, notification, or real migration Job. A migration-required result or unavailable probe falls through to the notified maintenance window. If that migration fails before promotion, synsmarts keeps a copy of the failed database, restores the pre-migration backup, and returns the previous release to service. The backup was taken after the maintenance page went up, so no order or update the store accepted is lost.
- Restore failed: maintenance stays on and support intervention is required.
Before promotion, the new release’s home page and one product page must each end at HTTP 200 within 45 seconds through the preview route. The check follows up to five redirects to your app’s own domains, so a home page that redirects to your www base URL passes. Any other status, such as a 401, or a redirect to another host fails the check, stops the deploy, and the previous release keeps serving.
See How deploys move from code to traffic for the complete classifier and rollback model.
Use the Magento CLI
Section titled “Use the Magento CLI”The managed SSH shell can run Magento commands from the application directory. Start with read-only checks:
bin/magento --versionbin/magento setup:db:statusbin/magento indexer:statusbin/magento cache:statusThe shell reads app/etc from the Workspace. After each successful deploy,
from Git or the Workspace, synsmarts copies the built release’s app/etc into
the Workspace, except env.php, so these commands reach the same database
version check as the store. The copy finishes a few minutes after the deploy
completes; until then the shell can show the previous release’s app/etc.
The managed shell also includes n98-magerun2. Inspect the installation with
n98-magerun2 sys:info. For a database console, run site-mysql; it supplies
the App’s connection through a private temporary defaults file and removes
that file when the client exits.
The bundled magerun refuses db:console (including mysql-client), db:dump,
db:import, db:info, and db:query, including abbreviated names. Those
upstream commands put the database password in process arguments, where a
process listing can expose it. Use site-mysql -e 'SELECT 1' for a query;
contact support for database dump or import assistance.
Use mutating commands only when the action is intended to affect runtime state, not to replace the selected release source or managed migration. In particular:
- change modules, themes, Composer packages, and DI inputs in the source intended for the next release;
- let the deploy build compile generated code and static content;
- let the deploy workflow apply database schema and data patches;
- use the portal’s Varnish purge action for full-page cache invalidation.
Manage scheduled work
Section titled “Manage scheduled work”Magento depends on scheduled execution for indexing, email, catalog rules,
consumers, and other application work. New Magento Apps include a Scheduled Job
named magento-cron. It runs magento-cron-runner every minute with Forbid
concurrency.
The seeded job is an ordinary customer-owned Scheduled Job. It is visible, editable, pausable, and deletable; counts toward the 50-job limit; and isn’t recreated after deletion. Keep it unless another scheduler fully replaces the same Magento work.
While magento-cron is active and runs every minute, synsmarts raises an alert
in Diagnostics when it records no run for
more than five minutes; a skipped run doesn’t count as a run. The check stops while the job is paused, deleted, or on
another schedule, and while scheduled work is suspended, such as during a
deploy, a database or cache change, or an App suspension. A missing run record
doesn’t by itself prove that Magento’s cron stopped, so check the job’s history
and the scheduler’s status.
A second alert appears in Diagnostics when magento-cron hasn’t completed a
run successfully for more than 10 minutes. On a migrated store, the alert
watches the one job whose command runs bin/magento cron:run, whatever its
name; keep exactly one such job. It keeps watching while the job is
paused or deleted, while every run fails, and while one run is still holding
the job. Only an App suspension stops it.
Magento runs some cron groups, such as index, consumers and analytics, in
their own processes. synsmarts runs each of them as its own line of
magento-cron and starts it every minute, as Magento does. A long reindex or a
busy queue consumer then holds only its own Magento job: email, sales and the
group’s other jobs keep running. Their runs appear in the job history as
magento-cron.index, magento-cron.consumers and so on, each reported complete
only when its group’s processes end. When a Magento index job is still running
after 15 minutes, Diagnostics shows an alert: catalog, price and stock changes
that job handles reach search and listings once it ends. A category move or a
large import can queue every product for reindexing on a big catalog.
Magento runs each job at most once per cron:run, one scheduled minute at a
time. After scheduled work pauses, for example during a deploy, every job that
runs each minute would stay late by the length of the pause. synsmarts adds a
magento-cron.catchup run every minute. It removes each job’s older overdue
entries from Magento’s cron schedule, so the job runs once and is on time
again. On a migrated store it does the same for the job that runs
bin/magento cron:run.
Your own Scheduled Jobs never hold up magento-cron: the limit of two of your
jobs running at once doesn’t count it or its group lines.
Magento’s queue consumers, including the one that builds an admin export
(System → Data Transfer → Export), run in magento-cron.consumers.
With remote storage, Magento writes the whole export file to temporary storage
before uploading it; the scheduled-job runner has 4 GiB for those files, enough
for a full export of about one million products.
Don’t replace magento-cron-runner with a bare bin/magento cron:run
Scheduled Job: it loses that split and the completion reporting.
Keep other durable commands and schedules in Scheduled Jobs, then verify the next run and its output after a release.
Useful checks include:
bin/magento cron:runbin/magento indexer:statusbin/magento queue:consumers:listRun cron:run manually only for controlled verification. Avoid defining the
same recurring command in more than one scheduler.
Manage caches and search
Section titled “Manage caches and search”- Use Magento cache commands for Magento application cache types.
- Use Purge cache on the Varnish service card to invalidate the managed full-page cache.
- Expect a cold cache after each deploy. After every promotion, synsmarts
flushes the configuration cache, runs
bin/magento cache:clean, purges Varnish when it’s enabled, and warms the storefront for up to a minute. The deploy shows Complete without waiting for that work. - Varnish keeps Magento’s “page not found” answer for up to 5 minutes, so a URL you create can show the 404 page for that long. Use Purge cache to serve it at once.
- Varnish ignores common ad click ids (Google, Meta, Microsoft, TikTok, X,
LinkedIn, Pinterest, Reddit, Yandex, Snapchat) and
utm_*tags when it looks up a page, so a tagged ad click is served from cache. Your analytics still read them from the browser’s address. - Review Redis settings before changing cache eviction behavior.
- Review OpenSearch version compatibility before selecting a different offered version.
- After catalog or search changes, verify indexer status and a representative storefront search.
See Configure services and Service configuration fields.
Update Magento safely
Section titled “Update Magento safely”- Confirm the target Magento release supports the offered PHP, MySQL, OpenSearch, and Composer dependency versions.
- Update
composer.json,composer.lock, modules, themes, and patches together. - Test compilation, static content, schema changes, checkout, admin, cron, indexing, and search outside production.
- Verify a recent database backup.
- Deploy one exact Git revision or reviewed Workspace snapshot and review its migration classification.
- Verify the customer journeys and scheduled work after promotion.
synsmarts updates the managed runtime and services. Magento core, extensions, themes, patches, and their compatibility remain your responsibility.
Troubleshoot a release
Section titled “Troubleshoot a release”- Missing
composer.jsonorbin/magentomeans the source isn’t a complete Magento project. - Missing Marketplace credentials means dependency reconstruction was required
and
COMPOSER_AUTHis absent or doesn’t contain validrepo.magento.comcredentials. - A vendored dependency validation failure means the supplied
vendor/doesn’t exactly represent the production packages incomposer.lock; repair the transferred tree or configure Composer credentials so it can be rebuilt. app/etc/env.phpandauth.jsonmust be removed from whichever source is selected. If either was committed to Git, also treat the repository history as exposed credential material.- A compile failure should be fixed in the selected Git revision or prepared Workspace, not by changing generated files after the build.
- A schema or data-patch failure should be reviewed in deploy details before retrying.
- A database newer than the release’s code means the selected source is older than the last migration applied; deploy a revision that includes the modules and versions the database already has.
- A failed storefront or preview check means the new release returned an error, Magento’s error page, or a slow response for a checked page. Reproduce that page from the same source and fix it there; the previous release keeps serving meanwhile.
- A search problem should be separated into indexer state, OpenSearch health, and storefront query behavior.
Use Recover from a failed deploy and Get support when the failing layer is managed by synsmarts.