# Create Magento App

Setting up Magento 2 framework on local can be stressful and take a long time. Worry not! We got you covered. This deployment technology combines two powerful approaches of containerization and Infrastructure as code to provision you a Magento 2 instance in minutes!

{% hint style="success" %}
See [what is new in version 2](/getting-started/what-is-new-in-version-2) of **magento-scripts**!
{% endhint %}

## 🚀 Get started in seconds

Create Magento App is a tiny package for HUGE framework. To create Magento app in seconds:

{% content-ref url="/pages/-MOVw4x6GNBPspaAoTXi" %}
[Getting started](/getting-started/getting-started)
{% endcontent-ref %}

Upon creation, type in the [start command](/getting-started/available-commands/start) to run the application deployment:

```bash
yarn start # for Yarn
npm start # for NPM
```

{% content-ref url="/pages/-MOqKE-M1Z08ORUmn5Qp" %}
[Available commands](/getting-started/available-commands)
{% endcontent-ref %}

## 🤝 Conflict-less design

The application will automatically select free ports. It will never let services previously installed on your machine down!

**Screwed a local installation?** Worry not, Create Magento App will set you up!&#x20;

## 🐛 Easy debugging

The powerful [XDebug](https://xdebug.org/) tool is a single command-line option flag away from you! Read how to use it:

{% content-ref url="/pages/-MOqXZ-Yri-qEN8pRN9x" %}
[Enabling XDebug](/usage-guide/enabling-xdebug)
{% endcontent-ref %}


# Getting Started

Create a new CMA instance in minutes

## Summary

* [ ] Make sure you have Node v12 or newer
* [ ] Install `create-magento-app` dependencies
* [ ] Initialize app with `create-magento-app`
* [ ] Enter the app's directory
* [ ] Start up the app with `npm start`

## Install Dependencies

**You’ll need to have Node >= 12 on your local development machine** (but it’s not required on the server). You can use [n](https://www.npmjs.com/package/n) (macOS, Linux) or [nvm-windows](https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows) to switch Node versions between different projects.

In addition, before setting up, make sure you have installed Docker! However, if you don't know or don't want to set it up manually, for Linux and macOS systems Docker installation is automated! Windows WSL2 systems will need to install Docker Desktop manually.

See more in the detailed guides below:

{% content-ref url="/pages/-MOVwpsWQzCvRc9jcPL8" %}
[Linux requirements](/getting-started/prerequisites/installation-on-linux)
{% endcontent-ref %}

{% content-ref url="/pages/-MOVx1PztQ7aSC\_MXO2i" %}
[MacOS requirements](/getting-started/prerequisites/installation-on-macos)
{% endcontent-ref %}

{% content-ref url="/pages/-MbpJWmV3cwn0JVn5fvs" %}
[Windows requirements](/getting-started/prerequisites/windows-requirements)
{% endcontent-ref %}

## Creating an App

To create a new app, you may choose one of the following methods:

{% tabs %}
{% tab title="NPX" %}

```bash
npx create-magento-app my-app
```

{% endtab %}

{% tab title="NPM" %}

```
npm init magento-app my-app
```

{% endtab %}

{% tab title="Yarn" %}

```
yarn create magento-app my-app
```

{% endtab %}
{% endtabs %}

Running any of these commands will create a directory called `my-app` inside the current folder. Inside that directory, it will generate the initial project structure and install the transitive dependencies. Learn more:

{% content-ref url="/pages/-MOWYsDpr9cLMyMxtSOj" %}
[Folder structure](/getting-started/folder-structure)
{% endcontent-ref %}

## Running the App

To start the app, navigate to its directory and run the `start` command:

```
cd my-app
npm start
```

This command will start Docker services, start Magento and open your app in the browser.

Create Magento App choose an available port for Magento 2 so it can vary. By default, it will use port 80 so the URL for the store will be <http://localhost:80/>.

### ScandiPWA setup and Theme Linking

If you plan to use the ScandiPWA theme, you have to do the [ScandiPWA setup](https://docs.create-scandipwa-app.com/getting-started/getting-started) and then come back to this CMA guide to do the theme linking:

{% content-ref url="/pages/-MO\_vUfSeKHDP-fbkXSh" %}
[Linking a Scandi Theme](/usage-guide/themes)
{% endcontent-ref %}


# Prerequisites

Before setting up, make sure you have installed the **libraries required to build the PHP**. Also, make sure to install **Docker** and **PHPBrew** in your system. See more in the detailed guides below:

{% content-ref url="/pages/-MOVwpsWQzCvRc9jcPL8" %}
[Linux requirements](/getting-started/prerequisites/installation-on-linux)
{% endcontent-ref %}

{% content-ref url="/pages/-MOVx1PztQ7aSC\_MXO2i" %}
[MacOS requirements](/getting-started/prerequisites/installation-on-macos)
{% endcontent-ref %}

{% content-ref url="/pages/-MbpJWmV3cwn0JVn5fvs" %}
[Windows requirements](/getting-started/prerequisites/windows-requirements)
{% endcontent-ref %}


# Linux requirements

## 1. Install Docker

You can use [Docker Desktop for Linux](https://docs.docker.com/desktop/setup/install/linux/) or [Docker Engine](https://docs.docker.com/engine/install/), but note that Docker Desktop will be slower than a Docker Engine setup.

CMA will prompt Docker installation and will try install it, but you can install it manually by executing the following commands:

```bash
# Download installation script
curl -fsSL https://get.docker.com -o get-docker.sh

# Run installation script
sudo bash get-docker.sh

# Add your user to the “docker” group to run docker without root.
sudo usermod -aG docker $USER

# After that you'll need to logout and login to your account or,
# you can temporarily enable group changes by running command below
newgrp docker
```

## 2. Prepare the environment

If you don't have **COMPOSER\_AUTH** environment variable or **auth.json** file in your project, CMA will run a setup wizard with detailed instructions for you to get access keys for the Magento repository.\
But you can also set up them manually by following the instructions below.

To work with Magento you need access keys to access the Magento repository.

1. Go to <https://marketplace.magento.com/customer/accessKeys/>
2. Generate Access Keypair

Now you have a **public key** and **private key** values.

To use them you have 2 options:

1. **Use `COMPOSER_AUTH` environmental variable**

   This option is used as a global variable on your machine.

   Replace `<public key>` and `<private key>` with your public and private key.

   ```bash
   export COMPOSER_AUTH='{
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }'
   ```

   Add the result to your `.bashrc` or `.zshrc` and reload your terminal.
2. **Use auth.json file**

   This option is used on a per-project basis, so your credentials will be always correct no matter which project you are working on.

   Create `auth.json` file in the root of your project and inside put the following content using the same `<public key>` and `<private key>` you obtained before:

   ```
   {
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }
   ```

## 3. Start your application

{% hint style="info" %}
Start command description can be found [here](/getting-started/available-commands/start).\
To access Magento CLI, Composer and PHP use [cli](/getting-started/available-commands/cli) command.
{% endhint %}


# MacOS requirements

{% hint style="success" %}

### **Apple Silicon** is supported as well!

All images come with arm64 architecture support!
{% endhint %}

## 1. Install Docker for Mac

Download and install Docker Desktop for Mac following the [official installation guide](https://docs.docker.com/docker-for-mac/install/).

{% hint style="warning" %}

## Heads up!

If you are working outside of the user's directory make sure to add your directory to the bindable directory list in **Docker** preferences. (**Docker -> Preferences -> Resources -> File Sharing**)\
If you don't do that, **Docker** will be unable to mount some directories inside containers and you will get a **startup** **error**.
{% endhint %}

### 1.1 Increase available resources for Docker

Increase the amount of allocated memory to at least 4 GB.\
Go to **Docker > Preferences > Resources > Memory > Advanced**. There drag memory slider to be at least 4 GB. You can also decrease **swap** size to its minimum value.\
\
Also, you can increase the number of CPUs available for Docker.\
By default, Docker Desktop is set to use half the number of processors available on the host machine. The more you set, the faster Docker containers will be.\
Just note that the more CPUs you select, the fewer resources will be left for your system.

{% hint style="success" %}

### Don't forget to enable VirtioFS in your Docker Desktop settings!

You can learn more about this experimental feature [here](/usage-guide/improve-performance#enabling-virtiofs-in-docker-desktop-on-mac).
{% endhint %}

## 2. Prepare the environment

If you don't have **COMPOSER\_AUTH** environment variable or **auth.json** file in your project, CMA will run a setup wizard with detailed instructions for you to get access keys for the Magento repository.\
But you can also set up them manually by following the instructions below.

To work with Magento you need access keys to access the Magento repository.

1. Go to <https://marketplace.magento.com/customer/accessKeys/>
2. Generate Access Keypair

Now you have a **public key** and **private key** values.

To use them you have 2 options:

1. **Use `COMPOSER_AUTH` environmental variable**

   This option is used as a global variable on your machine.

   Replace `<public key>` and `<private key>` with your public and private key.

   ```bash
   export COMPOSER_AUTH='{
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }'
   ```

   Add the result to your `.bashrc` or `.zshrc` and reload your terminal.
2. **Use auth.json file**

   This option is used on a per-project basis, so your credentials will be always correct no matter which project you are working on.

   Create `auth.json` file in the root of your project and inside put the following content using the same `<public key>` and `<private key>` you obtained before:

   ```
   {
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }
   ```

## 3. Start your application

{% hint style="info" %}
Start command description can be found [here](/getting-started/available-commands/start).\
To access Magento CLI, Composer and PHP use [cli](/getting-started/available-commands/cli) command.
{% endhint %}


# Apple Silicon

{% hint style="success" %}
Since **magento-scripts** version 2 is released, you don't need a special setup for macOS systems running on arm64 chips!

Follow [the installation for macOS](/getting-started/prerequisites/installation-on-macos) as usual!
{% endhint %}


# Windows requirements

## Using WSL

### 1. Install WSL

To install WSL2 on Windows follow [this guide](< https://docs.microsoft.com/en-us/windows/wsl/install-win10>).

{% hint style="info" %}
For [step #6 Install your Linux distribution of choice](https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-6---install-your-linux-distribution-of-choice) we recommend choosing the latest Ubuntu release, as it has the best compatibility on Windows.
{% endhint %}

### 1.1 Install Windows Terminal (Optional)

On Windows with WSL, it is recommended to use [Windows Terminal](https://docs.microsoft.com/en-us/windows/terminal/get-started).\
By using it you can open different shells and access different WSL distros in the same place, which is quite handy.

### 1.2 Install Visual Studio Code (Optional)

VSCode has excellent integration with WSL, so you can run commands, edit code and debug it inside a single editor.\
[Developing in WSL](https://code.visualstudio.com/docs/remote/wsl).

![](/files/-McUVj3wq2v7f-su7w7s)

### 2. Install Docker Desktop for Windows

Download and install [Docker Desktop for Windows](https://hub.docker.com/editions/community/docker-ce-desktop-windows).

### 3. Enable WSL 2 integration in Docker Desktop settings

Go to **Docker Desktop settings > General** and make sure that **Use the WSL 2 based engine** checkbox is checked.

![](/files/-McUOZ_owueFFwA0YvX7)

Then, go to Resources >WSL Integration and enable WSL integration into your distro.

![](/files/-McUOmfYntDg4h1lLMRN)

Toggle your distro and click **Apply & Restart**.

### 4. Prepare the environment

If you don't have **COMPOSER\_AUTH** environment variable or **auth.json** file in your project, CMA will run a setup wizard with detailed instructions for you to get access keys for the Magento repository.\
But you can also set up them manually by following the instructions below.

To work with Magento you need access keys to access the Magento repository.

1. Go to <https://marketplace.magento.com/customer/accessKeys/>
2. Generate Access Keypair

Now you have a **public key** and **private key** values.

To use them you have 2 options:

1. **Use `COMPOSER_AUTH` environmental variable**

   This option is used as a global variable on your machine.

   Replace `<public key>` and `<private key>` with your public and private key.

   ```bash
   export COMPOSER_AUTH='{
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }'
   ```

   Add the result to your `.bashrc` or `.zshrc` and reload your terminal.
2. **Use auth.json file**

   This option is used on a per-project basis, so your credentials will be always correct no matter which project you are working on.

   Create `auth.json` file in the root of your project and inside put the following content using the same `<public key>` and `<private key>` you obtained before:

   ```
   {
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }
   ```

### 5. Start your application

{% hint style="info" %}
Start command description can be found [here](/getting-started/available-commands/start).\
To access Magento CLI, Composer and PHP use [cli](/getting-started/available-commands/cli) command.
{% endhint %}

## Using VM

As an option, you can run CMA on Windows using a Linux VM running in [Virtual Box](https://www.virtualbox.org/) (free) or [VMWare Workstation Player](https://www.vmware.com/products/workstation-player.html) (paid).\
We recommend using [Ubuntu](https://ubuntu.com/download/desktop) or [Fedora](https://getfedora.org/en/workstation/download/) distros, although [Linux Mint](https://linuxmint.com/download.php), [CentOS](https://www.centos.org/download/) and distros based on `apt` , `pacman`, `yum`, `dnf` package managers should also work.\
[Installation guide](/getting-started/prerequisites/installation-on-linux) for this option is the same as installing on a regular Linux platform.


# Available commands

There are multiple commands available in Create Magento App:

### `yarn start` or `npm run start`

{% content-ref url="/pages/-MOkehwx5KVpndeSFuNx" %}
[Start the application](/getting-started/available-commands/start)
{% endcontent-ref %}

### `yarn stop` or `npm run stop`

{% content-ref url="/pages/-MOl8skLE48iS\_0zhCUD" %}
[Stop the application](/getting-started/available-commands/stop)
{% endcontent-ref %}

### `yarn status` or `npm run status`

{% content-ref url="/pages/-MOkcAE2gQgtaDLPHnYx" %}
[Check application status](/getting-started/available-commands/status)
{% endcontent-ref %}

### `yarn cli` or `npm run cli`

{% content-ref url="/pages/-MOl9D1L7FUjXY9a6GzM" %}
[Enter application CLI](/getting-started/available-commands/cli)
{% endcontent-ref %}

### `yarn logs` or `npm run logs`

{% content-ref url="/pages/-MOl9Li3NrDe0Pr1eqXX" %}
[Explore application logs](/getting-started/available-commands/logs)
{% endcontent-ref %}

### `yarn link` or `npm run link`

{% content-ref url="/pages/-MOlA0avsCc7JRKYulXU" %}
[Link a theme](/getting-started/available-commands/link)
{% endcontent-ref %}

## Experimental commands

### `yarn cleanup` or `npm run cleanup`

{% content-ref url="/pages/-MOgUGa7-eOwqltf-Iyu" %}
[⚠️ Uninstall a project](/getting-started/available-commands/cleanup)
{% endcontent-ref %}


# Start the application

## `yarn start` or `npm run start`

This command executes a local deployment of your Magento 2 application.\
It does it in the following steps:

1. Prepare your project for Magento 2.
2. Pull PHP, Varnish, MariaDB, ElasticSearch, Nginx and Redis images
3. Build project image
4. Deploy containers: PHP, Varnish, Redis, MariaDB, ElasticSearch, Nginx and SSL Terminator Nginx container.
5. Install Magento 2 using Composer.
6. Setup Magento 2.
7. Open a browser with up and running Magento 2 store.

### **Command options**

#### **`-p, --port`**

A port to run your application on.

{% hint style="info" %}
By default, Create Magento App will select a random available port.
{% endhint %}

```bash
yarn start --port <port> # for Yarn
npm run start -- --port <port> # for NPM
```

#### **`-n, --no-open`**

Disable auto-open of a browser window at the end of the workflow.

```bash
yarn start --no-open # for Yarn
npm run start -- --no-open # for NPM
```

{% hint style="info" %}
You can set `CMA_NO_OPEN=1` environment variable in your shell to persist this flag.
{% endhint %}

#### **`-d, --debug`**

{% hint style="warning" %}
Since **magento-scripts\@2.4.0** this option is not available.
{% endhint %}

Enable [XDebug](https://xdebug.org/) for debugging PHP.

```bash
yarn start --debug # for Yarn
npm run start -- --debug # for NPM
```

#### **`-s, --skip-setup`**

Skips Magento setup.

{% hint style="warning" %}
**Skipping Magento setup might result in conflict during runtime because Magento config will not be updated with a new port config.**\
This option can be used only if you **100% sure** that the ports configuration is the same.
{% endhint %}

In a nutshell, this option enables start command will just restart services and PHP-FPM, so if you need to restart the project it can be done in under 10 seconds\*.

```bash
yarn start --skip-setup # for Yarn
npm run start -- --skip-setup # for NPM
```

#### `--pull-images`

Pull Container Images.

This is used for updating container images.

```bash
yarn start --pull-images # for Yarn
npm run start -- --pull-images # for NPM
```

#### `--reset-global-config`

Reset global configuration for current CMA instance.

This will reset configuration that is set for some prompts that appears during setup.&#x20;

```bash
yarn start --reset-global-config # for Yarn
npm run start -- --reset-global-config # for NPM
```

#### `-v, --verbose`

{% hint style="info" %}
Since **magento-scripts\@1.8.0**
{% endhint %}

This option will enable printing of logs from Magento installation, setup and upgrade tasks.

```bash
yarn start --verbose # for Yarn
npm run start -- --verbose # for NPM
```

## Usage example

```bash
yarn start # for Yarn
npm start # for NPM
```


# Stop the application

## `yarn stop` or `npm run stop`

This command stops a local deployment of your Magento 2 application. It does it in the following steps:

1. Gracefully stops Docker containers.
2. Removes the Docker network used by the application.

## Usage example

```bash
yarn stop # for Yarn
npm run stop # for NPM
```


# Check application status

## `yarn status` or `npm run status`

{% hint style="warning" %}

### Heads up!

Command will work only after Create Magento App is installed.
{% endhint %}

This command will print the current Create Magento App project status. Status includes:

* Project name
* Project location
* Project creation date
* Platform version
* Platform architecture
* Docker version
* PHP version
* Composer version
* Magento version
* Docker containers status
  1. Container name
  2. Container image
  3. Container status
  4. Container network
  5. Container port forwarding
  6. Container environment variables
* Magento URL
* Magento admin panel URL
* Magento admin panel credentials

## Usage example

```bash
npm run status # for NPM
yarn status  # for Yarn
```


# Enter application CLI

In CLI you get control over running services, easy aliases for common service like magento and composer as well as easy debugging of any PHP code.

## `yarn cli` or `npm run cli`

Opens a new instance of Bash with aliases for PHP, Composer and Magento used in Create Magento App project.

<figure><img src="/files/DZERXC8WvXakaEhv6AMj" alt=""><figcaption></figcaption></figure>

## **Usage example**

First, run the script:

```bash
npm run cli # for NPM
yarn cli # for Yarn
```

Now, in the opened terminal and execute commands:

```bash
php -v
> PHP 7.4.30 (cli) ...

composer --version
> Composer version 1.10.19

# Can be used with alias
c --version
> Composer version 1.10.19

magento setup:upgrade
> ... magento upgrade output

# Can be used with alias
m se:up
> ...magento upgrade output
```


# Explore application logs

## `yarn logs <scope>` or `npm run logs <scope>`

Gives simple access to logs from PHP, Nginx, SSL-Terminator, Varnish, Redis, MariaDB and ElasticSearch containers and Magento.

### **Available scopes**

* `mariadb`
* `nginx`
* `ssl-terminator`
* `redis`
* `elasticsearch`
* `magento`
* `php`
* `varnish`

{% hint style="info" %}
If you are using OpenSearch, the scope will remain `elasticsearch`.
{% endhint %}

### **Command options**

#### `--details`

Show extra details provided to logs

```bash
yarn logs nginx --details # for Yarn
npm run logs nginx -- --details # for NPM
```

#### `--timestamps, -t`

Show timestamps

```bash
yarn logs nginx --timestamps # for Yarn
npm run logs nginx -- --timestamps # for NPM
```

#### `--follow, -f`

Follow log output

```bash
yarn logs nginx --follow # for Yarn
npm run logs nginx -- --follow # for NPM
```

#### `--since`

Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

```bash
yarn logs nginx --since=2s # for Yarn
npm run logs nginx -- --since=2s # for NPM
```

#### `--until`

Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

```bash
yarn logs nginx --until=2s # for Yarn
npm run logs nginx -- --until=2s # for NPM
```

## **Usage example**:

```bash
yarn logs nginx

> ... # nginx logs

# ctrl + c

# this is not alias, but rather service name matching
yarn logs ng # or nginx

> ... # nginx logs

# for ssl-terminator
yarn logs ssl

> ... # ssl-terminator logs

# and for mariadb
yarn logs ma # or mariadb

> ... # mariadb logs

# and for magento
yarn logs mag # or magento

> ... # magento logs
```


# Execute commands in Docker containers

## `yarn run exec <container name> [commands]` or `npm run exec -- <container name> [commands]`

{% hint style="info" %}
Since **magento-scripts\@1.1.0**
{% endhint %}

Executes command in a chosen container.

This command is basically a wrapper on top of [docker exec](https://docs.docker.com/engine/reference/commandline/exec/) command. It simplifies execution command in docker containers by providing names for docker containers so you don't have to search them by running a [status](/getting-started/available-commands/status) command or `docker ps`.

```bash
# Using docker exec

# 1. get container name
docker ps
> ... # docker ps otput

# 2. execute command
docker exec -it <container name> <command>

# Using CMA exec

# 1. execute command
yarn run exec <service name> <command>
> ... # output from command is piped to your terminal
```

If you don't want to execute specific command, by default exec command will use **bash** as a command (and **redis-cli** for redis container) so you will be connected to the container with interactive shell environment.

### **Available service names**:

* `mariadb`
* `php`
* `varnish`
* `nginx`
* `ssl-terminator`
* `redis`
* `elasticsearch`

{% hint style="info" %}
If you are using OpenSearch, service name will remain `elasticsearch`.
{% endhint %}

## Usage example

```bash
yarn run exec mariadb

>root@c8f223c3ea92:/# # inside a container with mariadb database

# ctrl + d or type 'exit' and press enter

# this is not alias, but rather service name matching
yarn run exec ma

>root@c8f223c3ea92:/# # inside a container with mariadb database

# custom command to check for nginx service status in container
yarn run exec nginx service nginx status

# expected output
>[ ok ] nginx is running.
```


# Link a theme

## `yarn run link <path>` or `npm run link <path>`

Sets ScandiPWA as a Magento Theme from your specified folder.

{% hint style="warning" %}

### Heads up!

Please follow [this guide](/usage-guide/themes) for linking ScandiPWA theme to your Magento App.
{% endhint %}

{% hint style="danger" %}
Since **magento-scripts** version 2 to link a theme it must be located within Magento project!
{% endhint %}

### Command options

#### `-v, --verbose`

{% hint style="info" %}
Since **magento-scripts\@1.9.0**
{% endhint %}

This option will enable printing of logs from linking a theme.

```bash
yarn run link ./path/to/scandipwa --verbose # for Yarn
npm run link ./path/to/scandipwa -- --verbose # for NPM
```

## Usage example

```bash
yarn run link ./path/to/scandipwa # for Yarn
npm run link ./path/to/scandipwa # for NPM
```


# Import database dump

## `yarn import-db [dump file path]` or `npm run import-db [dump file path]`

Imports database dump into MySQL container.

{% hint style="warning" %}
Note 1: To be able to import a database dump application must be running.\
Note 2: It is recommended to run the [start](/getting-started/available-commands/start) command after running database import to ensure that configuration is up-to-date.
{% endhint %}

### **Command options**

#### **`-r, --remote-db`**

Imports database from the remote server.\
Currently, the following protocols are supported:

* `ssh://`

{% tabs %}
{% tab title="yarn" %}

```bash
yarn import-db --remote-db ssh://my-username@my-server.com
```

{% endtab %}

{% tab title="npm" %}

```bash
npm run import-db -- --remote-db ssh://my-username@my-server.com
```

{% endtab %}
{% endtabs %}

Now it will connect via ssh to your server, create dump files (`dump-0.sql` and `dump-1.sql`), download them to your projects root folder, merge them into single `dump.sql` and import to your local instance with applied fixes.

To learn more about this option, read the following guide:

{% content-ref url="/pages/-Mchm5W0CLqGRl1Y1PU1" %}
[Importing remote database](/usage-guide/importing-database/importing-remote-database)
{% endcontent-ref %}

#### `--with-customers-data`

Does not exclude customers and orders data when importing local and remote database.

{% tabs %}
{% tab title="yarn" %}

```bash
yarn import-db ./dump.sql --with-customers-data
yarn import-db --remote-db ssh://my-username@my-server.com --with-customers-data 
```

{% endtab %}

{% tab title="npm" %}

```
npm run import-db ./dump.sql -- --with-customers-data
npm run import-db -- --remote-db ssh://my-username@my-server.com --with-customers-data
```

{% endtab %}
{% endtabs %}

If you are importing a remote database and using this option, CMA will create only one `dump.sql` file with all data inside it.

## **Usage example**:

```bash
yarn import-db ./dump.sql
... # output

# or with npm
npm run import-db ./dump.sql
... # output
```


# ⚠️ Uninstall a project

{% hint style="warning" %}

### Heads up!

This command is not shipped in Create Magento App template by default. To enable it add following line to your projects `package.json` field `scripts` :

```
"cleanup": "magento-scripts cleanup"
```

{% endhint %}

## `yarn cleanup` or `npm run cleanup`

This command allows you to gracefully uninstall Create Magento App project.

{% hint style="danger" %}

### Watch out!

You should not use this command! This is command description with how to use but we **strongly** recommend avoid using it.

It will remove Docker volumes (**you will lose all data inside Redis, MySQL and ElasticSearch**), run `magento setup:uninstall` command and remove config files from the cache folder.
{% endhint %}

### Command options

#### **`-f, --force`**

Cleanup will remove Magento files and CMA cache.\
The folder will remove to initial [structure](/getting-started/folder-structure).

{% hint style="info" %}

### Heads up!

PHP will not be removed by running this command. To remove it you should delete the folder `~/.phpbrew/php/php-7.3.11/`.
{% endhint %}

## Usage example

Add new line to `package.json`:

{% code title="package.json" %}

```bash
{
    "scripts": {
        "cleanup": "magento-scripts cleanup"
    }
}
```

{% endcode %}

Now use it as normal:

```bash
npm run cleanup # for NPM
yarn cleanup # for Yarn
```


# Folder structure

After creation, your project should look like this:

```
├── 📁 node_modules
├── 📄 package.json
└── 📄 README.md
```

Looks empty, isn't it? Well, that is because we haven't installed Magento 2 yet.

To install Magento 2 you need to bootstrap the project with [start](/getting-started/available-commands/start) command.

After Magento 2 installation folder structure should look

```
├── 📁 app
├── 📁 bin
├── 📁 dev
├── 📁 generated
├── 📁 lib
├── 📁 node_modules
|  ├── 📁 .create-magento-app-cache
|  |  ├── 📁 nginx
|  |  |  └── 📁 conf.d
|  |  |     └── 📄 default.conf
|  |  ├── 📁 ssl-terminator
|  |  |  └── 📁 conf.d
|  |  |     └── 📄 default.conf
|  |  ├── 📁 varnish
|  |  |  └── 📄 default.vcl
|  |  ├── 📄 port-config.json
|  |  ├── 📄 php-fpm-debug.conf
|  |  ├── 📄 php-fpm.conf
|  |  ├── 📄 php.ini
|  |  ├── 📄 mariadb.cnf
|  |  └── 📄 .magentorc
|  ... 📁 other packages
├── 📁 phpserver
├── 📁 pub
├── 📁 setup
├── 📁 var
├── 📁 vendor
├── 📄 ... Magento 2 files
├── 📄 cma.js
├── 📄 package.json
└── 📄 README.md
```

Inside `node_modules` there is `.create-magento-app-cache` folder. It contains all configuration files:

* PHP-FPM configuration file.
* PHP-FPM debug container configuration file.
* PHP configuration file.
* Nginx configuration file.
* SSL-Terminator (Nginx) configuration file.
* Varnish configuration file.
* MariaDB configuration file.
* CLI configuration file.
* Port configuration file.

In your projects root directory also will be created `cma.js` file that contains CMA configuration: Magento configuration, Docker services configuration, host and SSL configuration.


# Updating to New Releases

Create Magento App is divided into two packages:

* `create-magento-app` is a global command-line utility that you use to create new projects.
* `@scandipwa/magento-scripts` is a development dependency in the generated projects (including this one).

When you run `npx create-magento-app my-app` it automatically installs the latest version of Create Magento App.

We create a project with the latest version of `@scandipwa/magento-scripts` so you’ll get all the new features and improvements in newly created apps automatically.

To update an existing project to a new version of `@scandipwa/magento-scripts`, [open the change-log](https://github.com/scandipwa/create-magento-app/releases), find the version you’re currently on (check `package.json` in this folder, if you’re not sure), and apply the migration instructions for the newer versions.

In most cases bumping the `@scandipwa/magento-scripts` version in `package.json` and running `npm install` (or `yarn install`) in this folder should be enough, but it’s good to consult the [change-log](https://github.com/scandipwa/create-magento-app/releases) for potential breaking changes.

To bump the version of `@scandipwa/magento-scripts` to the latest available version, use:

{% tabs %}
{% tab title="yarn" %}

```
yarn add @scandipwa/magento-scripts@latest
```

{% endtab %}

{% tab title="npm" %}

```
npm install @scandipwa/magento-scripts@latest
```

{% endtab %}
{% endtabs %}

To install version 1 of `magento-scripts` use:

{% tabs %}
{% tab title="yarn" %}

```bash
yarn add @scandipwa/magento-scripts@^1
```

{% endtab %}

{% tab title="npm" %}

```
npm i @scandipwa/magento-scripts@^1
```

{% endtab %}
{% endtabs %}

We commit to keeping the breaking changes minimal so you can upgrade `@scandipwa/magento-scripts` painlessly.


# Testing Alpha Releases

Stable release of `@scandipwa/magento-scripts` package is releases in the end of the week, but sometimes we release an alpha version sooner.\
If you see an alpha release in [releases section on GitHub](https://github.com/scandipwa/create-magento-app/releases), you can install them by running command:

{% tabs %}
{% tab title="yarn (recommended)" %}

```
yarn add @scandipwa/magento-scripts@alpha
```

{% endtab %}

{% tab title="npm" %}

```
npm install @scandipwa/magento-scripts@alpha
```

{% endtab %}
{% endtabs %}

To return to stable release channel, use [Updating to New Releases](/getting-started/updating-to-new-releases) section.

{% content-ref url="/pages/-MQwi0gNKyS-NeEUvL7L" %}
[Updating to New Releases](/getting-started/updating-to-new-releases)
{% endcontent-ref %}


# Configuration File

{% code title="default cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        user: 'admin',
        password: 'scandipwa123',
        adminuri: 'admin',
        mode: 'developer',
        edition: 'community'
    },
    configuration: {}
};

```

{% endcode %}

The configuration file is created when you start the project `cma.js`, it's a tool that allows you to be in control of important parts of the project without headaches.

## Magento

Magento configuration is located in `magento` field and contains the following fields:

* `first_name`  - Admin first name
* `last_name` - Admin last name
* `email` - Admin email
* `user` - Admin user name
* `password` Admin password
* `adminuri` - Admin panel URL
* `mode` - Magento mode (description and list of available modes are located [here](https://devdocs.magento.com/guides/v2.4/config-guide/bootstrap/magento-modes.html))
* `edition` - Magento edition. Allowed values: `community`, `enterprise`.

## Services

In the `configuration` field we can configure PHP, Composer and Docker services.

### PHP

PHP configuration is located in the `php` field and contains the following fields:

* `baseImage` - PHP image without XDebug installed. You can select an image from the [PHP image list](/container-images/php-images).
* <mark style="color:red;">`debugImage`</mark> - PHP image with XDebug installed. You can select an image from the [PHP image list](/container-images/php-images). <mark style="color:orange;">(deprecated since</mark> <mark style="color:orange;"></mark><mark style="color:orange;">**magento-scripts\@2.4.0**</mark><mark style="color:orange;">)</mark>&#x20;
* `configTemplate` - `php.ini` template file location. With this option, you can define your own `php.ini` file that will be used by PHP. (Original `php.template.ini` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/php.template.ini))
* `debugTemplate` - `xdebug.ini` template file location. With this option you can tweak the XDebug configuration used in together with `debugImage`. (Original `php-debug.template.ini` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/php-debug.template.ini))
* `fpmConfigTemplate` - `php-fpm.conf` template file location. With this option you can tweak the PHP-FPM configuration used by PHP-FPM. (Original `php-fpm.template.conf` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/php-fpm.template.conf))
* `extensions` - Map of extensions that will be used for the project. By default, it contains the following extensions that are required by Magento. You can add an extension that will be required by some Composer package, CMA will automatically install it with the correct version.\
  Learn more about installing extensions in our guide on [Configuring PHP](/usage-guide/configuring-php)!
* `env` - Environment variables for container **Record\<string, string>**.
* `platform` - Select the platform mode for the service. Working values are `linux/amd64` and `linux/arm64`, but they are limited only to supported platforms by Docker. Default value `''` , which will tell magento-scripts to select the appropriate platform automatically. Recommended to use default value unless you specifically need to change platform to support a legacy Magento installation.

Example to install `fileinfo` extension:

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        php: {
            // let's add some extensions
            extensions: {
                fileinfo: {}
            }
        }
    }
};
```

{% content-ref url="/pages/-MVuGkDk6QkWgG2WM5\_q" %}
[Configuring PHP](/usage-guide/configuring-php)
{% endcontent-ref %}

Example to edit environment variable of  PHP container:

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        php: {
            // and add custom env variable
            env: {
                COMPOSER_MEMORY_LIMIT: -1
            }
        }
    }
};
```

### Nginx

Nginx configuration is located in the `nginx` field and contains the following fields:

* `image` - Container image **string**. For Nginx default version is `nginx:1.18.0` .
* `configTemplate` - Nginx template file location **string**. With this option, you can define your own nginx.conf file that will be used by Nginx. (Original `nginx.template.conf` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/nginx.template.conf))
* `platform` - Select the platform mode for the service. Working values are `linux/amd64` and `linux/arm64`, but they are limited only to supported platforms by Docker. Default value `''` , which will tell magento-scripts to select the appropriate platform automatically. Recommended to use default value unless you specifically need to change platform to support a legacy Magento installation.

{% hint style="info" %}
Nginx image is pulled from [Docker Hub](https://hub.docker.com/_/nginx).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        nginx: {
            // lets change nginx image to 1.19.0
            image: 'nginx:1.19.0',
            // and use custom nginx template
            configTemplate: './nginx.conf.template'
        }
    }
};
```

### MariaDB

MariaDB configuration is located in the `mariadb` field and contains the following fields:

* `image` - Container image. **string**.
* `useOptimizerSwitch` - MariaDB specific setting. **string** or **boolean**.\
  By default set to **true** for MariaDB 10.4 and newer version.\
  During template file compilation **true** will be transformed to the following configuration:

  ```
  rowid_filter=off
  ```

  Can be set to any valid configuration from [feature documentation](https://mariadb.com/kb/en/optimizer-switch/).
* `platform` - Select the platform mode for the service. Working values are `linux/amd64` and `linux/arm64`, but they are limited only to supported platforms by Docker. Default value `''` , which will tell magento-scripts to select the appropriate platform automatically. Recommended to use default value unless you specifically need to change platform to support a legacy Magento installation.

{% hint style="info" %}
MariaDB image is pulled from [Docker Hub](https://hub.docker.com/_/mariadb).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        mariadb: {
            // lets change mariadb image to 10.4
            image: 'mariadb:10.4',
            
            // and use optimizer switch with desired flag
            useOptimizerSwitch: 'rowid_filter=off'
        }
    }
};
```

### SearchEngine (OpenSearch / ElasticSearch)

SearchEngine configuration is located in the `searchengine` field and allows you to select **elasticsearch** and **opensearch** as options.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        searchengine: 'opensearch'
    }
};
```

For Magento 2.4.7 and older CMA by default will select **elasticsearch** for `searchengine` configuration.\
From Magento 2.4.8 and newer CMA by default will select **opensearch** for `searchengine` configuration.

#### ElasticSearch

ElasticSearch configuration is located in the `elasticsearch` field and contains the following fields:

* `image` - Container image **string**.
* `env` - Environment variables for container **object**.
* `platform` - Select the platform mode for the service. Working values are `linux/amd64` and `linux/arm64`, but they are limited only to supported platforms by Docker. Default value `''` , which will tell magento-scripts to select the appropriate platform automatically. Recommended to use default value unless you specifically need to change platform to support a legacy Magento installation.

{% hint style="info" %}
ElasticSearch image is pulled from [ElasticSearch Hub](https://www.docker.elastic.co/r/elasticsearch).
{% endhint %}

{% hint style="warning" %}
Magento 2.2.10 - 2.3.4 are using our [custom ElasticSearch image ](/container-images/elasticsearch-images/elasticsearch-6.8)that works on **amd64** and **arm64** architectures.
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        elasticsearch: {
            // lets change elasticsearch image version to 7.13.1
            image: 'elasticsearch:7.13.1',
            env: {
                // add additional environment variables
                ES_JAVA_OPTS: '-Xms2048m -Xmx4096m'
            }
        }
    }
};
```

#### OpenSearch

ElasticSearch configuration is located in the `opensearch` field and contains the following fields:

* `image` - Container image **string**.
* `env` - Environment variables for container **object**.
* `platform` - Select the platform mode for the service. Working values are `linux/amd64` and `linux/arm64`, but they are limited only to supported platforms by Docker. Default value `''` , which will tell magento-scripts to select the appropriate platform automatically. Recommended to use default value unless you specifically need to change platform to support a legacy Magento installation.

{% hint style="info" %}
OpenSearch image is pulled from [Docker Hub](https://hub.docker.com/r/opensearchproject/opensearch).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        opensearch: {
            // lets change opensearch image version to 2.13.0
            image: 'opensearchproject/opensearch:2.13.0',
            env: {
                // add additional environment variables
                OPENSEARCH_JAVA_OPTS: '-Xms2048m -Xmx4096m'
            }
        }
    }
};
```

{% content-ref url="/pages/X3G3a6jQotMdf6skyM1R" %}
[Using OpenSearch](/usage-guide/opensearch)
{% endcontent-ref %}

### Redis

Redis configuration is located in the `redis` field and contains the following fields:

* `image` - Container image **string**.
* `platform` - Select the platform mode for the service. Working values are `linux/amd64` and `linux/arm64`, but they are limited only to supported platforms by Docker. Default value `''` , which will tell magento-scripts to select the appropriate platform automatically. Recommended to use default value unless you specifically need to change platform to support a legacy Magento installation.

{% hint style="info" %}
Redis image is pulled from [Docker Hub](https://hub.docker.com/_/redis).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        redis: {
            // lets change redis image version to 6.2.4
            image: 'redis:6.2.4'
        }
    }
};
```

### Composer

Composer configuration is located in the `composer` field and contains the following fields:

* `version` - Composer version **string**. You can also use the `latest-stable`, `latest-preview`, `latest-1.x`, `latest-2.x` and `latest-2.2.x`.
* `plugins` - Map of Composer global plugins with a configuration that will be added to project image.
* `plugins[name].enabled` - a `boolean` which determines if the plugin should be enabled. For example, if you are using an older Magento version with Composer 1 [Prestissimo](https://github.com/hirak/prestissimo) plugin is enabled by default to speed-up installation and you can disable it!
* `plugins[name].options` - a `string` with additional options for `composer global require <name> <options>` command.

Examples:

<pre class="language-javascript"><code class="lang-javascript"><strong>/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
</strong>module.exports = {
    magento: { ... },
    configuration: {
        composer: {
            // lets change composer version to 2.8.8
            version: '2.8.8'
        }
    }
};
</code></pre>

<pre class="language-javascript"><code class="lang-javascript"><strong>// Define composer version from a channel
</strong><strong>
</strong><strong>/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
</strong>module.exports = {
    magento: { ... },
    configuration: {
        composer: {
            // lets change composer version to latest-2.2.x (LTS)
            version: 'latest-2.2.x'
        }
    }
};
</code></pre>

```javascript
// Install any composer plugin:

/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        composer: {
            plugins: {
                // <plugin vendor/plugin name>
                'hirak/prestissimo': {
                    enabled: true
                }
            }
        }
    }
};
```

### Varnish

Varnish configuration is located in the `varnish` field and contains the following fields:

* `enabled` - A **boolean** option to manually enable or disable Varnish in the setup. (Default: `false`)
* `configTemplate` - `varnish.vcl` template file location. With this option, you can define your own `varnish.vcl` file that will be used by Varnish. (Original `varnish.template.vcl` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/varnish.template.vcl))
* `image` - Varnish image **string**.
* `healthCheck` - A **boolean** option to manually enable or disable Varnish HealthCheck in the setup. (Default: `false`)
* `platform` - Select the platform mode for the service. Working values are `linux/amd64` and `linux/arm64`, but they are limited only to supported platforms by Docker. Default value `''` , which will tell magento-scripts to select the appropriate platform automatically. Recommended to use default value unless you specifically need to change platform to support a legacy Magento installation.

{% hint style="info" %}
Varnish image is pulled from [Docker Hub](https://hub.docker.com/_/varnish).
{% endhint %}

{% hint style="warning" %}
&#x20;Varnish is disabled by default since **magento-scripts\@2.4.0**.
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        varnish: {
            // lets change composer version to 6.0
            image: 'varnish:6.0'
        }
    }
};
```

### SSL Terminator (Nginx)

SSL Terminator is an Nginx instance, its configuration is located in `sslTerminator` field and contains the following fields:

* `image` - Container image **string**.
* `configTemplate` - SSL Terminator template file location **string**. With this option, you can define your own `ssl-terminator.template.conf` - File that will be copied inside the `$CMA_CACHE/ssl-terminator/conf.d/` folder which is mounted in Nginx container to `/etc/nginx/conf.d/` folder. **string** (Original `ssl-terminator.template.conf` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/ssl-terminator.template.conf))
* `platform` - Select the platform mode for the service. Working values are `linux/amd64` and `linux/arm64`, but they are limited only to supported platforms by Docker. Default value `''` , which will tell magento-scripts to select the appropriate platform automatically. Recommended to use default value unless you specifically need to change platform to support a legacy Magento installation.

{% hint style="info" %}
Nginx image is pulled from [Docker Hub](https://hub.docker.com/_/nginx).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        sslTerminator: {
            // lets change nginx image version to 1.19
            image: 'nginx:1.19.0',
            // and use custom ssl-terminator nginx template
            configTemplate: './ssl-terminator.conf.template'
        }
    }
};
```

### NewRelic

{% hint style="warning" %}
Available only on Linux. WSL/MacOS are not supported.
{% endhint %}

NewRelic is a monitoring service for applications and uses the following configurations fileds:

* `enabled` - Boolean indicating if NewRelic is used in the application or not. Default is `false`.
* `licenseKey` - License key **string**. Located in API Keys section on NewRelic.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        newRelic: {
            enabled: true,
            licenseKey: '<LICENSE_KEY>'
        }
    }
};
```

{% hint style="info" %}
Learn about adding NewRelic to your application [here](/usage-guide/configuring-newrelic).
{% endhint %}

## Domain

{% hint style="info" %}
Available in `magento-scripts` \~2.0.x and \~2.1.x
{% endhint %}

The host configuration is a string located in `host` field and by default, it is set to `localhost` .\
You can put your own host domain that will be set to nginx config as `server_name` and set Magento secure and unsecure base\_url values.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    host: 'scandipwa.local'
};

```

{% hint style="info" %}
Learn about adding a localhost domain to your application [here](/usage-guide/setup-custom-domain).
{% endhint %}

## Multi-Store Domains

{% hint style="info" %}
Since `magento-scripts` 2.2.x!
{% endhint %}

`storeDomains` allows to set different domains for Magento stores.

Use `store code` as `key` and domain as a `value`.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    storeDomains: {
        admin: 'scandipwa.local'
    }
};
```

{% hint style="info" %}
Learn about configuring Multi-Store domains in your application [here](/usage-guide/configuring-multi-store).
{% endhint %}

## SSL

SSL configuration is located in the `ssl` field and contains the following values:

* `enabled` - Enables or disables SSL in the application. **boolean** (`false` by default)
* `external_provider` - Allows to use external SSL provider in the application. **boolean** (`false` by default)
* `ssl_certificate` - SSL certificate file location **string**. You can put there your SSL certificate file location relative to the project root folder or use absolute value.
* `ssl_certificate_key` - SSL certificate key file location **string**. You can put there your SSL certificate file location relatively to the project root folder or use absolute value.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    ssl: {
        enabled: true,
        external_provider: false,
        ssl_certificate: './path/to/my/certificate',
        ssl_certificate_key: './path/to/my/certificate-key.pem'
    }
};

```

{% hint style="info" %}
Learn about enabling SSL in your application [here](/usage-guide/enabling-ssl).
{% endhint %}

## Prefix

Prefix configuration is a boolean located in the `prefix` field and by default, it is set to `true` .

But what prefixes are used for?\
Prefix is a unique identifier that will be appended to docker container and volume names to prevent possible interference between folders with similar names. (Interference between folders look like [that](https://github.com/scandipwa/create-magento-app/issues/13))\
Setting `prefix` to `false` is generally **not recommended** but might be necessary for legacy projects.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    prefix: false
};

```


# System Configuration File

## System Configuration File

{% hint style="info" %}
Since **magento-scripts 1.5.1**
{% endhint %}

This configuration file is located in your home directory and should have a name `.cmarc`.\
As it is not created automatically, you will need to do it manually.\
The default configuration file looks like this:

{% code title="$HOME/.cmarc" %}

```javascript
  {
    "useNonOverlappingPorts": false,
    "analytics": true
  }
```

{% endcode %}

This configuration file contains the following configuration options:

### Use Non-Overlapping Ports

{% hint style="info" %}
Recommended to enable this option if you are working with many CMA projects
{% endhint %}

Use non-overlapping ports is a feature that will tell CMA when choosing available ports on the system to also ignore ports that are already used by other CMA instances, even if they are stopped.\
That way it will ensure that your projects will not get new ports every time you switch between them.

To enable this feature, set `useNonOverlappingPorts` field in the system configuration file to `true`.

### Analytics

Analytics helps us to collect data about errors or possible slow-downs and helps us to identify areas that should be fixed or improved!

Of course, you have an option to opt out of analytic data collection. To do that set `analytics` field in the system configuration file to  `false` and CMA will not collect analytic data from your system.


# Supported Magento versions

When you first start the application, you will see the following prompt:

![Magento version selector](/files/jrnX0Ayoz9rbB48Php1o)

Here you can choose the Magento version to install.

## Supported versions

Currently, we support all Magento versions starting from Magento 2.2.10.

If you want to edit the project configuration using a [configuration file](/getting-started/config-file#project-configuration-file) use the configuration reference which is available [here](https://github.com/scandipwa/create-magento-app/tree/master/build-packages/magento-scripts/lib/config/versions).


# How does it work?

{% hint style="danger" %}

## This page is outdated

{% endhint %}

The installation of Create Magento App is done through many small steps or tasks and we like to group them by their purpose: Preparation, Installation, Configuration, Execution. Each of these groups works with a specific set of technologies to achieve the desired result.

## Overview

We use the `listr2` library to help us with task definition and display in the terminal. This library allows us to declare independent tasks and execute them in any order we want, passing down context to later tasks. Context is a way for tasks to share information and is a key aspect of Create Magento App installation process.

During the Preparation tasks, for example, context is populated with various settings, such as available ports, Magento version, `cma.js` configuration, etc, and the data is then used in later tasks. This approach simplifies the data flow and makes it easy for us to focus on one thing at a time, instead of doing multiple operations within each task.

## Preparation

This is the first group of tasks that are executed once you run Create Magento App. Tasks of this group perform various checks to validate that the necessary requirements are met and set up your machine to be ready for installation.

Create Magento App uses `Docker` under the hood and we have a task that is responsible for validating that it is installed on the machine and is ready to run. Below will be the list of tasks that are responsible for preparation.

### Checking cache folder

Create Magento App works with a lot of data and we don't want to run all of the operations each time the project is started, this is why some of the settings are cached for further use. This task is responsible for validating the presence of the cache folder.

### Checking requirements

Create Magento App uses `Docker`, `PHPBrew`, and `Composer` under the hood and this task is responsible for validating that all of them are installed on the machine and are ready to run, including their dependencies. In the scope of this task, your OS is also validated as Create Magento App only works on Mac and Linux.

### Loading Magento version

In case the machine has a local Magento installation or multiple Magento installations, the user will be prompted to select the Magento versions that they want to use. In case the Magento installation is missing, the default version (2.4.1) will be chosen instead.

### Get cached ports

Retrieves cached ports from the cache folder. This is needed to gracefully stop currently running `Docker` containers.

### Stopping Docker services

Stops running `Docker` containers of Create Magento App. If not containers related to the project are running, the task will be skipped.

### Stopping php-fpm

Kills the `php-fpm` process. Only the local `php-fpm` process for Create Magento App will be stopped.

### Get available ports

Retrieves the list of available ports. Will find free ports in case of the first installation, otherwise will validate the ports that have been retrieved from the cache in one of the previous steps. In case one of the cached ports is no longer available, a new one will be found instead.

### Save configuration

Saves the list of available ports to the configuration for further use in the application setup.

## Installation

The second group of tasks is where PHP and Magento get installed. PHP extensions are also installed in the scope of this task group.

### Install PHP

Installs the PHP binaries according to the version specified in the `cma.js`, otherwise installs PHP version 7.4.13 by default. During each subsequent run, this task will check for PHP extensions configuration and install any missing extensions, if they are present.

### Install Composer, prepare FS, and download images

Installs Composer to allow for Magento to install its dependencies. Prepares File System by creating folders and files necessary for Nginx, PHP, and php-fpm to run. This includes creating SSL certificates and updating the internal configuration file with paths to certain binaries and executables.

These tasks are grouped into one to run them in parallel, heavily decreasing the time needed for initial installation.

### Configuring PHP extensions

This task is responsible for configuring the PHP extensions and adding them to the active PHPBrew instance.

### Install Prestissimo

Installs Prestissimo, a plugin for Composer to allow it for parallel package installation. This plugin heavily decreases the time needed for initial installation, due to installing Magento's dependencies faster.

### Install Magento

This is finally the task where Magento installation takes place! This task creates the project folder, installs Magento, and connects with the ScandiPWA theme created using Create Scandipwa App if present.

## Configuration

Tasks in this group are responsible for creating and configuring the infrastructure needed for the application to work. This includes the Magento configuration itself as well as the setup of the `Docker` infrastructure, and connection establishment to the MySQL container.

### Starting Docker services

Starts 4 `Docker` services that are required for Create Magento App to operate. These services are `ElasticSearch`, `MySQL`, `Nginx`, and `Redis`. In case of initial installation, an appropriate `Docker` network will be created as well as Docker volumes to store the data.

### Connect to MySQL server

Running MySQL instance is one of the requirements for Magento configuration, and the Create Magento App makes sure that the connection is established. A check is made to see if the MySQL container is running and in case it's not, the retry mechanism is in place. A total of 10 tries will be made with a 5-second interval between each and in most cases, it's enough to establish a connection.

### Setup Magento

In this task, the Magento instance is configured for local development. Many sub-tasks will prepare the Magento instance by migrating the database, configuring URLs, creating an admin user, disabling the maintenance mode, and disabling the 2FA.

## Execution

Tasks from this list will use the data from all previous tasks to start the application up.&#x20;

### Starting php-fpm

Starts the PHP process manager and the Magento instance.

### Open browser

Opens up `localhost` in the browser. The Magento app will be accessible from there.


# Limitations

At the moment CMA has a few limitations that you should be aware of:

* You can create a maximum of 30 CMA instances running at the same time before running into network limits.\
  To remove custom networks not used by at least one container you can use the command `docker network prune` **OR** update to **magento-scripts** version **1.7.0 or newer** which will remove project network during stop command, freeing the network.
* Not all ports can be used for Magento to run on. Some browsers can throw an error **ERR\_UNSAFE\_PORT** on some ports below 1024.\
  If you encountered such issue, use [-p](/getting-started/available-commands/start#p-port) option in the start command and use ports above 1024.


# What Is New in Version 2

`magento-scripts` version 2.0.0 has been in development since mid-July 2022 and the main goal of its creation was to eliminate dependency on system packages.

That was the reason why `magento-scripts` stopped working on Ubuntu 22.04 (because of the upgraded OpenSSL version) and in general, required a super-complex system for installing and validating required packages on **all** systems, plus a complex and time-consuming PHP build time to process.\
And it was practically impossible to isolate CMA instances from one another without the need to compile PHP **for each instance**.\
But it was fast in the end because PHP was running on the host system and did not experience performance losses on file operations or processing power in the VM on macOS and other systems.

## What is new?

### PHP

Version 2 introduces a PHP container into the setup. With this move, we don't need a complex dependency installation and validation system, nor a complex PHP build system anymore.

<figure><img src="/files/vMdDYaTxv2P5ewofbHFM" alt=""><figcaption><p>PHP Image Infrastructure</p></figcaption></figure>

Now we will be using the new PHP Image infrastructure based on [the Alpine Linux image](https://hub.docker.com/_/alpine).&#x20;

Those are the steps for PHP images:

1. Alpine Linux image is used as a base for images with PHP.\
   Only in this step PHP is actually compiled. No additional extensions are installed.
2. PHP image is used as a base for images with PHP extensions for Magento.\
   In this step PHP extensions for [Magento 2.3](https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements.html#php-extensions) or [Magento 2.4](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/system-requirements.html) are installed.&#x20;
3. PHP image with Magento extensions is used as a base for Project Image that is built on the user system.\
   This image installs the Composer version corresponding to Magento requirements and additional extensions for PHP defined in the configuration file by a user.

Steps 2-3 are repeated for images with XDebug that are based on PHP images with XDebug.

It is necessary to have 2 images with XDebug and without to be able to switch between them instantly when running the [start command](/getting-started/available-commands/start) with [debug option](/getting-started/available-commands/start#d-debug).

{% hint style="success" %}
All images are built using [Docker Buildx](https://github.com/docker/buildx) for **AMD64** and **ARM64** architectures!
{% endhint %}

### Database - MariaDB

We observed a very strange behaviour with MySQL 5.7 on Linux systems with Docker Engine. When started container will consume all resources given to the system and basically freeze the computer.

In addition to that, we already have [MariaDB](https://hub.docker.com/_/mariadb) in our setup for macOS on ARM64 chips (M1) because MariaDB actually has ARM64 images that can run on those systems.

So we decided to bring more consistency to our setup and move everyone to [MariaDB](https://hub.docker.com/_/mariadb).

Since existing setups are still running on MySQL we developed a migration script that will run if it detects that you have MySQL volume in your project. The process is automated, the user just needs to press **ENTER** a few times to get a new working setup.

### Maildev

Maildev is also added to the setup so you will be able to catch emails during development.


# Using console commands

## Working with CLI

We have our PHP compiled, Composer installed, Magento 2 installed.\
But how access them? Everything is scattered across the file system.

That is where CLI comes in handy. It provides aliases for PHP, Composer and Magento in your project.\
We can open it by running a command:

```bash
npm run cli # for NPM
yarn cli # for Yarn
```

Now we have access to PHP, Composer and Magento, we can install PHP dependencies, upgrade Magento and so on.

```bash
php -v
> PHP 7.4.13 (cli) ...

composer --version
> Composer version 1.10.19

# Can be used with alias
c --version
> Composer version 1.10.19

magento setup:upgrade
> Magento upgrade output ...

# Can be used with alias
m se:up
> Magento upgrade output ...
```

## Common Usage

Flushing Magento cache

```bash
magento cache:clean

# or with aliases and shortcuts
m c:c
```

Magento upgrade

```bash
magento setup:upgrade

# or with aliases and shortcuts
m se:up
```

Upgrading Composer dependencies

```bash
composer upgrade

# or with alias
c upgrade
```


# Accessing Docker containers

Since V2 Create Magento App consists of a PHP Docker container that runs Magento and additional containers with Varnish, Redis, Elasticsearch, Nginx, and MariaDB, and CLI to connect all of these things together. We already have a [CLI](/getting-started/available-commands/cli) command that gives us access to [Magento CLI](https://experienceleague.adobe.com/docs/commerce-operations/reference/magento-open-source.html) and [Composer CLI](https://getcomposer.org/doc/03-cli.md), but how can we access the containers?\
That is where the connect command comes in handy!

```bash
yarn run exec <service name> # for Yarn
npm run exec <service name> # for NPM
```

Now we are inside of a chosen container.\
Here is a list of available service names:

* `mariadb`
* `nginx`
* `ssl-terminator (nginx)`
* `redis`
* `elasticsearch`
* `php`
* `phpWithXdebug`
* `varnish`

{% hint style="info" %}
If you are using OpenSearch, the service name `elasticsearch` will remain the same.
{% endhint %}

## Common Usage

```bash
yarn run exec mariadb

>root@c8f223c3ea92:/# # inside a mariadb container

# ctrl + d or type 'exit' and press enter

# this is not an alias, but rather service name matching
yarn run exec ma

>root@c8f223c3ea92:/# # inside a mariadb container

```


# Linking a Scandi Theme

## Summary

Before you start:

* [ ] Install Create Scandi App
* [ ] Make sure you have a Scandi theme to use
* [ ] Make sure you have a Create Magento App set up

Linking your theme:

* [ ] Link your app using `run link`
* [ ] Compile your app in Magento mode
* [ ] Enable the theme in the admin panel

## 1. Installing Create ScandiPWA App

Before you link a theme, make sure you have installed Create ScandiPWA App. Use [this guide](https://docs.create-scandipwa-app.com/getting-started/getting-started) for installing it.

## 2. Linking a Theme

{% hint style="danger" %}
Your theme must be located **inside** of your Magento project!
{% endhint %}

To link a ScandiPWA theme to your Create Magento App project you can use the command [link](/getting-started/available-commands/link):

```bash
npm run link ./path/to/your/scandipwa-app # for NPM

# or with yarn
yarn run link ./path/to/your/scandipwa-app
```

Create Magento App will link your ScandiPWA theme from your selected path as a symbolic link.

## 3. Run Create ScandiPWA App Compilation

Run the command below from your ScandiPWA App directory (`./path/to/my/scandipwa-app` )

```bash
BUILD_MODE=magento npm run start # Mac, Linux
set BUILD_MODE=magento && npm run start & set BUILD_MODE= # Windows
```

This command will now watch the files and put their compiled versions into the `magento/Magento_Theme` folder.

{% hint style="info" %}
Instead of starting your Create ScandiPWA App project, you can also use `npm run build`.  Learn more [here](https://docs.create-scandipwa-app.com/deploying-your-app/magento-theme#npm-run-build-or-yarn-build).&#x20;
{% endhint %}

## 4. Enable Theme

After you linked theme to your Create Magento App instance you need to activate it.

Go to your Magento Admin panel (by default it can be accessed on `/admin` url), **Content > Configuration**, choose a website that you want to apply theme on, click **Edit** and select your theme, click **Save** and that is it.

Open your store URL and theme should be online.


# Enabling XDebug

On this page you will be guided on activating XDebug PHP debugger in Create Magento App application.

## Debugging preparations

### The browser

You need to install [XDebug Helper by JetBrains extension](https://github.com/JetBrains/xdebug-extension) for [Chrome](https://chromewebstore.google.com/detail/xdebug-helper-by-jetbrain/aoelhdemabeimdhedkidlnbkfhnhgnhm) to activate the Debugging session in PHPStorm. Instructions are the same for [Firefox](https://addons.mozilla.org/en-GB/firefox/addon/xdebug-helper-by-jetbrains/).

<figure><img src="/files/by5KRF7swabH5MrQjGZ3" alt=""><figcaption><p>Install extension</p></figcaption></figure>

After installation, open extension **options** and select **Debug Trigger** value as **PHPStorm**.

<figure><img src="/files/bwPEBXtaUO2ToSo2EbAh" alt=""><figcaption><p>Set Debug Trigger value to PHPSTORM</p></figcaption></figure>

{% hint style="info" %}
This extension sets a cookie in your browser's requests: `XDEBUG_SESSION=PHPSTORM`. This cookie enables debugging in your browser.

Sometimes, you may want to enable debugging outside of the browser (for example, to debug individual GraphQL requests). You can also set `XDEBUG_SESSION=PHPSTORM` manually in the `Cookie` header. Most HTTP and GraphQL clients support this option.
{% endhint %}

Now, when you open your CMA webpage, you need to enable a debug session by pressing **Debug** in the extensions menu.

<figure><img src="/files/fasSaveK03sbTMaDswPD" alt=""><figcaption></figcaption></figure>

### The editor

{% tabs %}
{% tab title="PHPStorm" %}
[Go to settings and activate Docker connection](https://www.jetbrains.com/help/phpstorm/docker.html#install_docker). This needs to be done **once**.
{% endtab %}

{% tab title="VSCode" %}
Install [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) extension.
{% endtab %}
{% endtabs %}

## Debugging

### First step: Run Create Magento App

Use [start](/getting-started/available-commands/start) command.

```bash
yarn start # for Yarn
npm run start  # for NPM
```

Wait for the command to finish.

### Second step: Start the debugger

{% tabs %}
{% tab title="PHPStorm" %}
Choose the **create-magento-app** debug configuration in the top right corner of PHPStorm's window.

![](/files/-MP9paYlLVvTnpiCg1TC)

Click on **Start debugging** or press **Shift+F9**, put test breakpoint in **$project\_root/pub/index.php** file, reload the page and that is all!

Happy debugging!
{% endtab %}

{% tab title="VSCode" %}
Open debugging tab in VSCode (**Ctrl + Shift + D)** and select **Listen for Xdebug** configuration.

![](/files/-MlKyJn6mBiUVuAdbliM)

Click on **Start debugging** (or press **F5)**, put the test breakpoint in **$project\_root/pub/index.php** file, reload the page and that is all!

Happy debugging!
{% endtab %}
{% endtabs %}


# Enabling SSL

## Using an external SSL provider

{% hint style="info" %}
Available since `magento-scripts` 2.2.0
{% endhint %}

If you are using an external SSL provider, like Ngrok, you will need to use the following configuration:

{% code title="cma.js" %}

```javascript
module.export = {
    // other configuration
    ssl: {
        enabled: true,
        external_provider: true // <- enable this
    },
    storeDomains: {
        admin: 'a9a9-9999-99-999-99.ngrok-free.app' // <- put your domain here
    }
}
```

{% endcode %}

That is it! Just now we have enabled SSL in our application!\
With `storeDomains` you can expose any store in your instance.

Now to apply changes we need to run [start](/getting-started/available-commands/start) command **without** [**-s option**](/getting-started/available-commands/start#s-skip-setup).

{% hint style="warning" %}
You can run **only one** application with SSL enabled at the time because it will use port 443 which is the default port for SSL.
{% endhint %}

## Using local certificate

### 1. Get a certificate

You can use your existing certificate or create a new one using [mkcert](https://github.com/FiloSottile/mkcert) utility.\
Follow the installation [guide](https://github.com/FiloSottile/mkcert#installation) for your platform.&#x20;

After installation install mkcert certificate into your system by running the command below:

```bash
mkcert -install
```

Now we need to create a certificate.\
To create a certificate run command below:

```bash
> mkcert localhost 127.0.0.1

Created a new certificate valid for the following names 📜
 - "localhost"
 - "127.0.0.1"

The certificate is at "./localhost+1.pem" and the key at "./localhost+1-key.pem" ✅

It will expire on 13 May 2023 🗓
```

Now we have all files that we need for CMA config.

### 2. Setup CMA

Add to your `cma.js` file field `ssl` with the following object:

{% code title="cma.ks" %}

```javascript
module.export = {
    // other configuration
    ssl: {
        enabled: true,
        ssl_certificate: './localhost+1.pem',
        ssl_certificate_key: './localhost+1-key.pem'
    }
}
```

{% endcode %}

That is it! Just now we have enabled SSL in our application!\
Now to apply changes we need to run [start](/getting-started/available-commands/start) command **without** [**-s option**](/getting-started/available-commands/start#s-skip-setup).

{% hint style="warning" %}
You can run **only one** application with SSL enabled at the time because it will use port 443 which is the default port for SSL.
{% endhint %}


# Configuring PHP

PHP configuration is stored within the `cma.js` file:

```javascript
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        user: 'admin',
        password: 'scandipwa123',
        adminuri: 'admin',
        mode: 'developer',
    },
    configuration: {
        php: {
            // PHP configuration goes here
        }
    }
};

```

## Changing the PHP version

The default version of PHP for your project is defined by the Magento version according to Magento System Requirements for [Magento 2.4](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/system-requirements.html) and [Magento 2.3](https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements.html).

PHP to Magento version mapping will look like this:

* [PHP 8.4](/container-images/php-images/php-8.4) - Available for Magento 2.4.8
* [PHP 8.3](/container-images/php-images/php-8.3) - Magento 2.4.8
* [PHP 8.2 ](/container-images/php-images/php-8.2)- Magento 2.4.7 (+ patches)
* [PHP 8.1 ](/container-images/php-images/php-8.1)- Magento 2.4.4, 2.4.5, 2.4.6 (+ patches)
* [PHP 7.4](/container-images/php-images/php-7.4) - Magento 2.3.7, 2.4.0, 2.4.1, 2.4.2, 2.4.3 (+ patches)
* [PHP 7.3](/container-images/php-images/php-7.3) - Magento 2.3.3, 2.3.4, 2.3.5, 2.3.6 (+ patches)
* [PHP 7.2](/container-images/php-images/php-7.2) - Magento 2.2.10, 2.3.0, 2.3.1, 2.3.2 (+ patches)

To change the PHP version, select the PHP version from the [PHP Images](/container-images/php-images) section and then the PHP version with Magento extensions.&#x20;

For example, you have Magento 2.4.8 project and you want to use [PHP 8.4](/container-images/php-images/php-8.4). The configuration file `cma.js` will look accordingly:

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-8.4-magento-2.4'
        }
    }
};
```

{% endcode %}

After changing the configuration, restart the app to install the new PHP version:

```javascript
yarn start
```

And validate the new PHP installation through the CLI:

<figure><img src="/files/eoLe7D7VwJnbsRlNZCgZ" alt=""><figcaption></figcaption></figure>

Also, the PHP version will be printed during `start` command execution:

<figure><img src="/files/6MTLv48k2hLdKLTeKomR" alt=""><figcaption></figcaption></figure>

## Installing PHP extensions

{% hint style="success" %}
Some extensions have a separate package that can be integrated into `cma.js` like [ionCube extension](/scripts-extensions/php-extensions/deprecated-ioncube-extension)!
{% endhint %}

By default, only the extensions that are required by Magento are installed. If you need to install any additional extensions, cma.js will have to be changed accordingly.

### Simple extension installation

If the extension you want to install is available in[ Supported Extension list](https://github.com/mlocati/docker-php-extension-installer?tab=readme-ov-file#supported-php-extensions) in the [docker-php-extension-installer](https://github.com/mlocati/docker-php-extension-installer) project, then installation is pretty simple:

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            extensions: {
                calendar: {}
            }
        }
    }
};
```

{% endcode %}

This will install a PHP [calendar](https://www.php.net/manual/en/book.calendar.php) extension. Restart the app for changes to take effect:&#x20;

```javascript
yarn start
```

And validate newly installed extensions through the CLI:

```bash
yarn cli
bash$ php -m | grep calendar
calendar
```

### Complex extension installation

If extension is not available in the Supported Extension list, then you can define your custom command to install the extension from [pecl](https://pecl.php.net/).

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            extensions: {
                memcached: {
                    command: `apk add --no-cache --virtual .build-deps \\$PHPIZE_DEPS \
                    && pecl install memcached \
                    && docker-php-ext-enable memcached \
                    && apk del -f .build-deps`,
                    dependencies: [
                        'libevent-dev',
                        'libmemcached-dev',
                        'zlib-dev'
                    ]
                }
            }
        }
    }
};

```

{% endcode %}

All of this might look complicated, but this object describes the following information for **magento-scripts**:

1. PHP Extension name. Defined in `configuration.php.extensions` as a key for configuration object.
2. Command to install the extension inside the project image. Defined in `configuration.php.extensions[name].command` as a string or as a synchronous function that returns a string or asynchronous function that returns a string.  Optional.
3. Dependencies required by the extension. Defined in `configuration.php.extensions[name].dependencies` as an array of strings. Optional.

The current example defines that `memcached` extension requires 2 dependencies to be installed from [apk repository](https://pkgs.alpinelinux.org/packages): `libmemcached-dev` and `zlib-dev` and a command to install the extension itself.\
The command consists of 4 steps:

1. Installing build dependencies for [PECL](https://pecl.php.net/) extension.
2. Installing the extension itself from [PECL](https://pecl.php.net/).
3. Enabling installed extension
4. Removing build dependencies to save space inside the project image.

The command is written in one line because it will use one [RUN](https://docs.docker.com/engine/reference/builder/#run) instruction inside Dockerfile.\
Dependencies for extensions are recommended to move to the separate `dependencies` property because they will be installed together with other dependencies from other extensions in one RUN instruction inside Dockerfile.

After you made your changes restart the app for changes to take effect:

```javascript
yarn start
```

And validate newly installed extensions through the CLI:

```bash
yarn cli
bash$ php -m | grep memcached
memcached
```


# Configuring Multi-Store

{% hint style="info" %}
Since `magento-scripts` 2.2.0
{% endhint %}

## 1. Add domain to the /etc/hosts file

In order for this config to work you need to add your host domain to the `/etc/hosts` file, for example:

```bash
# /etc/hosts file
127.0.0.1 localhost
127.0.0.1 scandipwa.local # some other domain
```

## 2. Setup CMA

Multi-Store configuration is available via `storeDomains` property in `cma.js`.

You will need to put the store code as a `key` and your desired domain name as a `value` in this property, for example `admin` store key and `localhost` domain:

{% code title="cma.js" %}

```javascript
module.exports = {
    // other configurations
    storeDomains: {
        admin: 'scandipwa.local'
    }
};
```

{% endcode %}

{% hint style="danger" %}
Domain value must be pure like `google.com` or `scandipwa.local` or similar.

Subdomains can be used as well.
{% endhint %}

{% hint style="warning" %}
CMA will retrieve store codes from the `store_website` table, so make sure that the table is not empty.
{% endhint %}

That is it! Just now we have setup a domain in our application!\
Now to apply changes we need to run the [start](/getting-started/available-commands/start) command **without** [**-s option**](/getting-started/available-commands/start#s-skip-setup).


# Configuring NewRelic

{% hint style="warning" %}
Available only on Linux. WSL is not supported.
{% endhint %}

NewRelic will allow monitoring performance during development, hopefully allowing to spot performance regressions before going to prod.

You will need an infrastructure container running for the NewRelic daemon.

### 1. Retrieve your NR license key.

<https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/>

### 2. Run the following command

It will spin up a NewRelic infra container (Note that it will run in [privileged mode](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)):

<pre class="language-bash"><code class="lang-bash">docker run \
    -d \
<strong>    --name newrelic-infra \
</strong>    --network=host \
    --cap-add=SYS_PTRACE \
    --privileged \
    --pid=host \
    -v "/:/host:ro" \
    -v "/var/run/docker.sock:/var/run/docker.sock" \
    -e NRIA_LICENSE_KEY=&#x3C;LICENSE_KEY> \
    newrelic/infrastructure:latest
</code></pre>

Replace `<LICENSE_KEY>` with your license key

### 3. Add the following configuration to your `cma.js`

```javascript
module.exports = {
	... // other configurations
    configuration: {
        newRelic: {
            enabled: true,
            licenseKey: '<LICENSE_KEY>'
        }
    }
};
```

### 4. Run the `start` command without the `-s` option


# Access on the local network

Sometimes you need to run your CMA application in a mode where other users can access it to look at the development progress.

## 1. Get an IP address

Every device that is connected to the local is assigned an IP address in that network. Usually, this is done by the router.\
To get your IP address on the local network, use the following guide:

{% tabs %}
{% tab title="Ubuntu" %}

```bash
ifconfig -a
```

{% endtab %}

{% tab title="Manjaro Linux" %}

```bash
ip -4 addr | grep 192.168
```

{% endtab %}

{% tab title="macOS" %}

```bash
ipconfig getifaddr en0
> 192.168.0.xxx
```

{% endtab %}
{% endtabs %}

## 2. Make port public

Each OS has a different approach to opening ports in its firewall.

### Linux

We will be using [UFW](https://wiki.ubuntu.com/UncomplicatedFirewall) to control iptables rules.

{% tabs %}
{% tab title="Ubuntu" %}

```bash
# install it
sudo apt-get install ufw

# enable service
sudo ufw enable

# make sure that it is running
sudo ufw status verbose

# open port
sudo ufw allow in 80/tcp

# now we have port 80 available outside of our system
```

{% endtab %}

{% tab title="Manjaro Linux" %}

```bash
# install it
pamac install ufw

# enable service
sudo systemctl enable ufw.service
sudo ufw enable

# open port
sudo ufw allow in 80/tcp

# now we have port 80 available outside of our system
```

{% endtab %}
{% endtabs %}

### MacOS

Go to **System Preferences** > **Security & Privacy** > **Firewall**.\
Enable firewall. Then go to **Firewall Options** and make sure the only two options selected are **Automatically allow built-in software to receive incoming connections** and **Automatically allow downloaded signed software to receive incoming connections**.

## 3. Setup CMA

### magento-scripts 2.2.x and newer

Add to your `cma.js` file field `host` with your IP address:

```javascript
module.export = {
    ... // other configuration
    storeDomains: {
        admin: '192.168.0.100'
    }
}
```

That is it! Now your devices on the local network can communicate with your CMA instance!

You also need to apply changes by running the [start](/getting-started/available-commands/start) command **without** [**-s option**](/getting-started/available-commands/start#s-skip-setup).

{% hint style="info" %}
Learn more about storeDomains [here](/usage-guide/configuring-multi-store)!
{% endhint %}

### magento-scripts 2.1.x and older

Add to your `cma.js` file field `host` with your IP address:

```javascript
module.export = {
    ... // other configuration
    host: '192.168.0.100'
}
```

That is it! Now your devices on the local network can communicate with your CMA instance!<br>

You also need to apply changes by running the [start](/getting-started/available-commands/start) command **without** [**-s option**](/getting-started/available-commands/start#s-skip-setup).


# Using custom domain

{% hint style="danger" %}

## For Multi-Store configuration use [the following guide](/usage-guide/configuring-multi-store)

{% endhint %}

{% hint style="warning" %}
This page is relevant for `magento-scripts` versions before 2.2.x.

Version 2.2.x is using Multi Store configuration.
{% endhint %}

## 1. Add domain to the /etc/hosts file

In order for this config to work you need to add your host domain to the `/etc/hosts` file, for example:

```bash
# /etc/hosts file
127.0.0.1 localhost
127.0.0.1 scandipwa.local # some other domain
```

## 2. Setup CMA

Add to your `cma.js` file field `host` with your domain:

```javascript
module.export = {
    magento: { ... },
    host: 'scandipwa.local'
}
```

That is it! Just now we have setup a domain in our application!\
Now to apply changes we need to run the [start](/getting-started/available-commands/start) command **without** [**-s option**](/getting-started/available-commands/start#s-skip-setup).


# Using Enterprise Edition

## 1. Create new CMA app

```bash
npx create-magento-app@latest magento-enterprise
```

## 2. Set magento.edition to "enterprise" in the config file

{% code title="cma.js" %}

```javascript
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        user: 'admin',
        password: 'scandipwa123',
        adminuri: 'admin',
        mode: 'developer',
        edition: 'enterprise' // <- edit this
    },
    configuration: {}
};

```

{% endcode %}

## 3. Run the application

Start the application with the [start](/getting-started/available-commands/start) command.

{% hint style="warning" %}
You need access keys with access to Magento Enterprise on them to be able to install the **enterprise edition**.
{% endhint %}

```bash
npm run start
```


# Using OpenSearch

{% hint style="info" %}
Available since `magento-scripts` 2.3.1
{% endhint %}

{% hint style="info" %}
From Magento 2.4.8 CMA will use OpenSearch as the default search engine.
{% endhint %}

## 1. Create new CMA app

```bash
npx create-magento-app@latest magento-with-opensearch
```

## 2. Set searchengine to "opensearch" in the configuration section of the config file

{% code title="cma.js" %}

```javascript
module.exports = {
    // ...other configurations
    configuration: {
        searchengine: 'opensearch' // <- set this
    }
};
```

{% endcode %}

### 2.1 Configure OpenSearch (optional)

```javascript
module.exports = {
    // ...other configurations
    configuration: {
        searchengine: 'opensearch',
        opensearch: {
            // change opensearch image here
            image: 'opensearchproject/opensearch:2.13.0',
            env: {
                // additional environment variables for container
                OPENSEARCH_JAVA_OPTS: '-Xms2048m -Xmx4096m'
            }
        }
    }
};
```

## 3. Run the application

You need to apply changes by running the [start](/getting-started/available-commands/start) command **without** [**-s option**](/getting-started/available-commands/start#s-skip-setup).


# Importing database

To import the database use the [import-db](/getting-started/available-commands/import-db) command.

{% hint style="warning" %}

### **Heads up!**

If you are running a version older than **magento-scripts\@1.6.0**, you will need to start project manually using [start command](/getting-started/available-commands/start)!
{% endhint %}

{% tabs %}
{% tab title="Yarn" %}

```bash
yarn import-db <dump file path>
```

{% endtab %}

{% tab title="NPM" %}

```bash
npm run import-db <dump file path>
```

{% endtab %}
{% endtabs %}

When the command is called, multiple steps are executed to ensure the success of the import. These steps are as follows:

* A connection established with MySQL
* Theme configurations will be dumped and restored after the dump is imported
* The dump will be imported into MySQL from the specified file
* It will be ensured that dump will work with CMA set up by setting necessary configuration values
* And Magento setup will be running to finish the configuration.

To import database from remote ssh server, use the following guide:

{% content-ref url="/pages/-Mchm5W0CLqGRl1Y1PU1" %}
[Importing remote database](/usage-guide/importing-database/importing-remote-database)
{% endcontent-ref %}


# Importing remote database

{% hint style="warning" %}
Currently, **only SSH protocol is supported**!
{% endhint %}

To import database from remote server use[ import-db](/getting-started/available-commands/import-db) command with `--remote-db` option:

{% tabs %}
{% tab title="yarn" %}

```bash
yarn import-db --remote-db ssh://my-username@my-server.com
```

{% endtab %}

{% tab title="npm" %}

```
npm run import-db -- --remote-db ssh://my-username@my-server.com
```

{% endtab %}
{% endtabs %}

CMA will connect via ssh to your server, create 2 dump files (`dump-0.sql` and `dump-1.sql`), download them to your projects root folder, merge them into single `dump.sql` and import to your local instance with applied fixes.

### Is there a reason to use import from remote db when possible?

There is a good reason for it!\
The dump file created by this command is much smaller than dump files that are created the usual way.\
This is because we omit **orders** and **customers** data when we're creating dump file so it comes in a much smaller size.

For example, a dump from a database could weigh 2.7GB, now using this import feature size will be reduced to 4MB.

### Why 3 dump files?

The reason to make 3 dump files is simple: [mysqldump](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html) utility cannot make dump files with only a few tables without data, --no-data option is a boolean so we have only 2 options, either include data or not.

`dump-0.sql` file contains **all** the database tables **with data**, except for the order and customer-related tables.\
`dump-1.sql` file contains **only** orders and customer-related table structures, **without data**.\
`dump.sql` file is made from concatenating `dump-0.sql` with `dump-1.sql` , which are downloaded from your remote server, so it's **a full dump file**.


# Converting legacy Docker setup to CMA

We have an older [magento-docker](https://github.com/scandipwa/magento-docker) setup for ScandiPWA 1, 2, 3 but since it is not very versatile when it comes to development, you can "upgrade" it to use CMA!

## 1. Install CMA

Go to `src` folder and install CMA:

```bash
cd ./src

# if npm is not initialized, then run
npm init -y

# then install @scandipwa/magento-scripts package
npm i @scandipwa/magento-scripts@latest

# and make sure your package.json has the following scripts:
{
    ...
    "scripts": {
        "start": "magento-scripts start",
        "stop": "magento-scripts stop",
        "cli": "magento-scripts cli",
        "logs": "magento-scripts logs",
        "link": "magento-scripts link",
        "status": "magento-scripts status",
        "exec": "magento-scripts exec",
        "import-db": "magento-scripts import-db"
    }
    ...
}
```

## 2. Adjust composer dev packages

You need to adjust `require-dev` dependencies, ideally just replace them with the following ones which are shipped in default Magento 2.3 template:

```javascript
{
    ...
    "require-dev": {
        "allure-framework/allure-phpunit": "~1.2.0",
        "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
        "friendsofphp/php-cs-fixer": "~2.14.0",
        "lusitanian/oauth": "~0.8.10",
        "magento/magento-coding-standard": "*",
        "magento/magento2-functional-testing-framework": "~2.6.4",
        "pdepend/pdepend": "2.5.2",
        "phpcompatibility/php-compatibility": "^9.3",
        "phpmd/phpmd": "@stable",
        "phpstan/phpstan": "^0.12.2",
        "phpunit/phpunit": "~6.5.0",
        "sebastian/phpcpd": "~3.0.0",
        "squizlabs/php_codesniffer": "~3.4.0"
    }
    ...
}
```

## 3. Adjust theme webpack configuration

Magento does not serve theme files in older ScandiPWA versions so we need to reconfigure webpack devserver.

Go to file `app/design/frontend/Scandiweb/pwa/src/config/webpack.development.config.js` and your configuration for `devServer` should look like this:

{% code title="webpack.development.config.js" %}

```javascript
{
    devServer: {
        watchContentBase: true,
        publicPath: '/',
        historyApiFallback: true,
        port: 3003,
        https: false,
        overlay: true,
        compress: true,
        inline: true,
        hot: true,
        // comment or remove lines below
    
        // host: '0.0.0.0',
        // public: 'scandipwa.local',
        // allowedHosts: [
        //     '.local'
        // ],
    
        // add this to the config
        // NOTE: to get magento port you can use [npm run status] command
        proxy: {
            '/graphql': 'http://localhost:<your magento port>'
        }
    }
}
```

{% endcode %}

Comment or remote `host`, `public` and `allowedHosts` properties and add `proxy` property with a value of an object with mapping `/graphql` url to our Magento url.

> \[NOTE] You can define Magento port using `--port` option in start command. ([Docs](/getting-started/available-commands/start#p-port))

If you want to use a port other than 3003 for the frontend you can! Just edit `port` property in this config file.

Note that you cannot use ports below 1024 because it will require root privileges and for your own safety **we do not recommend running scripts as root**.

## 4. Run the project and resolve possible issues.

We have adjusted the project configuration enough to start working with CMA itself. Now we can try running the project.

Go to `src` folder and run:

```bash
npm run start
```

To run frontend you will need to use a command `watch`:

```bash
# go to frontend folder first
cd app/design/frontend/Scandiweb/pwa

npm run watch
```

In general, that is it!

## \[BONUS]

### Preserve data from the old setup

{% hint style="success" %}
**magento-scripts** will do this automatically!
{% endhint %}

To preserve data in the database, you will need to do as follows:

1. After you run magento setup, new MySQL volume will be created. You will need to get old mysql volume name and new one.
   1. To get new mysql volume name, run command:

      ```bash
       docker container inspect <mysql container>
      ```

      &#x20;and here go to the property `HostConfig.Mounts` and you should see volume name in a `Source` field.
   2. To get an old mysql volume name you can just use template: `<folder name>_mysql-data` where `folder name` is your folder name, you can get it by running `basename "$PWD"` command.
2. Now, stop the project and run commands below with replaced `<new_volume>` name and `<old_volume>` name values from the steps before.

   ```bash
    npm run stop # to stop the project

    docker volume rm <new_volume>

    docker volume create --name <new_volume>

    docker run --rm -it -v <old_volume>:/from:ro -v <new_volume>:/to alpine \
        ash -c "cd /from ; cp -av . /to"
   ```

   That's it! If you want to save some space, you can delete the old volume altogether by running the command: `docker volume rm <old_volume>`

### Delete unsed files

Since we are not using a clean Docker setup anymore, we don't need `docker-compose.*.yml` files, `Dockerfile` files as well as `build` and `opt` folder.

Go to the root directory of the project and run:

```bash
rm ./Makefile ./Dockerfile* ./docker-compose.*

rm -rf ./build ./opt
```

`deploy` folder often has some necessary files, like `latest.sql` , so we can keep it for now.


# Installing CMA in an existing Magento project

CMA does not have to own your project from day one. If you already have a Magento 2 checkout — cloned from your team's repository, migrated from another Docker setup, or unpacked from a customer handover - you can add CMA to it and keep everything that is already there.

This page covers adding CMA to a Magento 2 project. If you are coming from our older [magento-docker](https://github.com/scandipwa/magento-docker) setup, read [Converting legacy Docker setup to CMA](/usage-guide/converting-legacy-docker-setup-to-cma) instead - it covers the ScandiPWA-specific steps as well.

## What changes when CMA manages your project

In a self-managed setup you own the infrastructure: you install and version-match every service, write the configs, pick the ports, and wire `env.php` by hand. CMA replaces all of that with a managed, per-project Docker stack derived from the Magento version in your `composer.json`. Your code, your database content, and your own scripts stay yours.

<table data-header-hidden="false" data-header-sticky data-search="false"><thead><tr><th width="153.55859375">Area</th><th>You manage in a vanilla setup</th><th width="343.976806640625">CMA manages for you</th></tr></thead><tbody><tr><td>Services</td><td>Install and configure nginx, PHP-FPM, a database, Redis, a search engine, a mail catcher, SSL, optionally Varnish</td><td>One <code>start</code> runs the full stack as containers: nginx, two PHP-FPM (one with Xdebug), MariaDB, Redis, ElasticSearch or OpenSearch, MailDev, an SSL-terminating proxy, optional Varnish</td></tr><tr><td>Service versions</td><td>Track Adobe's requirements matrix; upgrade each component when Magento bumps it</td><td>Every service version is pinned to your Magento version — a Magento upgrade swaps the whole stack for you</td></tr><tr><td>PHP</td><td>Install the right PHP and ~28 extensions per project; switch versions between projects</td><td>A prebuilt container image matching your Magento version; your host PHP is irrelevant</td></tr><tr><td>Ports</td><td>Hardcode host ports, resolve clashes between projects</td><td>Assigned automatically, cached per project, bound to <code>127.0.0.1</code>; several CMA projects run side by side</td></tr><tr><td>Wiring</td><td>Hand-edit <code>env.php</code> hosts and base URLs after every change</td><td><code>env.php</code> and the base URLs are rewritten to point at the containers on every start</td></tr><tr><td>Daily commands</td><td><code>docker exec</code>, <code>docker logs</code>, mysql client incantations</td><td><code>npm run cli</code> (a shell with <code>magento</code>, <code>composer</code>, <code>mariadb</code> aliases), <code>exec</code>, <code>logs</code>, <code>status</code></td></tr><tr><td>Debugging</td><td>Toggle Xdebug ini and restart PHP-FPM</td><td>A second PHP-FPM container with Xdebug is always ready; enabled per request via browser cookie, or <code>debugphp</code> for CLI</td></tr><tr><td>IDE setup</td><td>Hand-written <code>launch.json</code> and PhpStorm config</td><td><code>.vscode/</code> and <code>.idea/</code> are generated and kept in sync with the assigned ports</td></tr></tbody></table>

### What CMA decides for you

The convenience comes with opinionated defaults. These are the ones an existing project is most likely to notice:

* **The database is fixed.** MariaDB, database name `magento`, user `magento`/`magento`, root password `scandipwa`. None of it is configurable - relevant if your dump references another schema name. `npm run status` prints the credentials and ports.
* **An admin user is ensured on every start.** If the user from `cma.js` (default `admin` / `scandipwa123`) is missing - including right after a database import — it is created.
* **Two-factor auth is disabled** by adding `markshust/magento2-module-disabletwofactorauth` as a dev dependency - this edits your `composer.json` and `composer.lock`. Composer plugin approvals (`allow-plugins`) may also be written back to `composer.json`.
* **All outgoing mail goes to the bundled MailDev** mail catcher; the SMTP settings in your database are overwritten on every start. Nothing is ever delivered for real.
* **The `block_html` and `layout` caches are disabled on every start** (and `full_page` too while Varnish is off - which it is by default).
* **There is no cron.** CMA neither installs a crontab nor runs Magento's cron. Indexers, queued emails, and every other scheduled job run only when you run `bin/magento cron:run` yourself, e.g. through `npm run exec`.
* **`env.php` is re-serialized** when CMA rewrites it, so comments and custom formatting in that file are lost.
* **Generated service configs are disposable.** They live in `node_modules/.create-magento-app-cache/` and are regenerated on every start — customize them through the template options in `cma.js`, not by editing the generated files.

{% hint style="info" %}
Need a start without the Magento-side changes? `npm run start -- --skip-setup` skips the whole setup phase — the `env.php` rewrite, admin user, 2FA module, cache and SMTP changes — for that run.
{% endhint %}

## Before you start

Your project should be a Magento 2 root — the folder that holds `composer.json`, `bin/magento` and `app/etc`.

Make sure you have:

* All the [prerequisites](/getting-started/prerequisites) installed for your platform (Docker, Node.js 16 or newer, and the OS packages listed there).
* Composer credentials for `repo.magento.com`, either as an `auth.json` file in the project root or in the `COMPOSER_AUTH` environment variable. CMA checks for both and will prompt you if neither is present.
* Your Magento version in [the list of supported versions](/getting-started/supported-magento-versions).
* Any previous stack for this project **stopped** — if it was running under another Docker setup or native services, shut those down first so the two do not compete for containers and volumes.

{% hint style="warning" %}
CMA refuses to run as `root`. Run every command below as your normal user.
{% endhint %}

{% stepper %}
{% step %}

## Add CMA to the project

Point the generator at your existing project instead of a new folder name:

```bash
cd /path/to/your/magento/project

npx create-magento-app .
```

CMA detects that the folder is not empty and switches to *adopt* mode. In this mode it:

* **merges** `package.json` — the CMA scripts and the `@scandipwa/magento-scripts` dependency are added, and everything you already have (your own scripts, dependencies, indentation) is kept as-is;
* **creates** `cma.js`, `AGENTS.md`, `CLAUDE.md` and `README.md` **only if they do not exist yet**;
* refreshes its own agent instructions under `.claude/magento-scripts/` and `.agents/magento-scripts/`;
* installs the Node dependencies.

At the end it prints exactly what it created, what it merged, and what it left alone. The full list of files CMA may add, with commit guidance, is in [What CMA adds to your project](#what-cma-adds-to-your-project) below.

{% hint style="info" %}
If your `package.json` already defines a script CMA also wants — most commonly `start`, used by frontend tooling — CMA does **not** overwrite it. It reports the clash instead, and you can reach that command through `npx magento-scripts start`.
{% endhint %}

### Doing it by hand

If you would rather not run the generator, install the package directly:

```bash
# only if the project has no package.json yet
npm init -y

npm i @scandipwa/magento-scripts@latest
```

Then add the scripts to your `package.json`:

{% code title="package.json" %}

```json
{
    "scripts": {
        "start": "magento-scripts start",
        "stop": "magento-scripts stop",
        "cli": "magento-scripts cli",
        "logs": "magento-scripts logs",
        "link": "magento-scripts link",
        "status": "magento-scripts status",
        "exec": "magento-scripts exec",
        "import-db": "magento-scripts import-db"
    }
}
```

{% endcode %}
{% endstep %}

{% step %}

## Review `cma.js`

`cma.js` is the project's [configuration file](/getting-started/config-file). The generator creates it from a default template — it does **not** inspect your project — so review it before the first start:

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        // the admin account CMA ensures exists on every start
        user: 'admin',
        password: 'scandipwa123',
        // must match the admin path your project already uses —
        // it is written into app/etc/env.php on every start
        adminuri: 'admin',
        mode: 'developer',
        // 'community' or 'enterprise' — must match composer.json
        edition: 'community'
    },
    configuration: {}
}
```

{% endcode %}

Three values are worth checking:

* **`edition`** — the template defaults to `community`. If your `composer.json` requires `magento/product-enterprise-edition`, set it to `enterprise`; CMA fails fast when the two contradict.
* **`adminuri`** — written into `backend.frontName` in `app/etc/env.php` on every start. If your project uses a custom admin path, set it here first.
* **`user` / `password`** — the admin account CMA creates when missing. Change them if the defaults are not acceptable even locally.
  {% endstep %}

{% step %}

## First run

How you run CMA for the first time depends on whether you have a database dump.

### With a database dump

Skip `start` and go straight to the import — `import-db` is self-contained: it stops running containers, assigns ports, starts the services, and waits for MariaDB itself.

```bash
npm run import-db -- ./dump.sql
```

Beyond importing (see [Importing database](/usage-guide/importing-database) for the details), it also adapts the dump for local use: it asks before dropping and recreating the `magento` database, removes a custom admin path in favor of `adminuri` from `cma.js`, points the search-engine configuration at the local container, and offers to strip customers, orders and admin users from the imported data. Base URLs are handled automatically — both `import-db` and every later `start` set them to match the assigned ports.

### Without a dump

```bash
npm run start
```

With an empty database, the first start installs a blank Magento.

### What happens on the first start

1. **Reads your Magento version** from `magento/product-community-edition` (or `-enterprise-edition`) in `composer.json`, falling back to `composer.lock`. You are not asked to pick a version.
2. **Adjusts `composer.json`** if needed — adds the `repo.magento.com` repository and `magento/composer-root-update-plugin` when they are missing.
3. **Runs `composer install`** when the installed state is incomplete or out of sync with `composer.lock`; skipped when everything already lines up.
4. **Generates service configs** into `node_modules/.create-magento-app-cache` and starts the containers on free ports.
5. **Rewrites `app/etc/env.php`** to point at those containers (see below).
6. **Sets up the database** based on what `setup:db:status` reports: everything up to date — nothing runs; schema changes pending — `setup:upgrade`; Magento reports it is not installed at all (a non-empty database without a valid installation state) — `setup:install` followed by `setup:upgrade`.

Every start — first or not — also applies the managed defaults described in [What CMA decides for you](#what-cma-decides-for-you): the admin user, the 2FA module, the cache and SMTP changes, and the base URLs.

When the start finishes, CMA prints the storefront, admin and MailDev URLs. `npm run status` shows them again at any time, along with the database credentials; `npm run cli` opens a shell inside the stack with `magento`, `composer` and `mariadb` ready as aliases.

### What happens to `app/etc/env.php`

If the file exists, CMA edits it in place rather than replacing it, but several keys are rewritten on **every** start:

| Key                                      | What CMA does                                                         |
| ---------------------------------------- | --------------------------------------------------------------------- |
| `backend.frontName`                      | set to `magento.adminuri` from `cma.js`                               |
| `db.connection.default.host`             | pointed at the MariaDB container                                      |
| `session.redis.host` / `.port`           | pointed at the Redis container (when `session.save` is `redis`)       |
| `cache.frontend.default.backend_options` | server and port pointed at the Redis container                        |
| `http_cache_hosts`                       | replaced with CMA's Varnish host, or removed when Varnish is disabled |
| `cache.persisted-query`                  | added or removed based on `composer.lock`                             |

The file is re-serialized on rewrite, so comments and custom formatting in it do not survive.

{% hint style="warning" %}
Commit or back up `app/etc/env.php` before the first start. Existing `http_cache_hosts` entries are dropped, and a `cache.persisted-query` block is kept only when it comes from `scandipwa/persisted-query`.
{% endhint %}
{% endstep %}
{% endstepper %}

## What CMA adds to your project

<table data-search="false"><thead><tr><th>Path</th><th>Purpose</th><th>Commit it?</th></tr></thead><tbody><tr><td><code>cma.js</code></td><td>project configuration</td><td>yes</td></tr><tr><td><code>package.json</code></td><td>CMA scripts and dependency</td><td>yes</td></tr><tr><td><code>README.md</code></td><td>project readme with the CMA commands</td><td>yes</td></tr><tr><td><code>AGENTS.md</code>, <code>CLAUDE.md</code>, <code>.claude/</code>, <code>.agents/</code></td><td>AI agent instructions for the CMA commands</td><td>yes</td></tr><tr><td><code>node_modules/.create-magento-app-cache/</code></td><td>generated nginx / PHP / Varnish / MariaDB configs</td><td>no</td></tr><tr><td><code>.vscode/launch.json</code></td><td>XDebug launch configuration</td><td>your call</td></tr><tr><td><code>.idea/</code></td><td>PhpStorm PHP, XDebug and database settings</td><td>your call</td></tr><tr><td><code>.git/hooks/post-checkout</code></td><td>warns on <code>composer.json</code> / <code>composer.lock</code> changes after a branch switch</td><td>n/a</td></tr></tbody></table>

`README.md`, `AGENTS.md`, `CLAUDE.md` and `cma.js` are created only when missing; the `.claude/magento-scripts/` and `.agents/magento-scripts/` directories are CMA-managed and refreshed on every run. If your project uses husky or another hook manager, the git hook goes into that manager's directory instead of `.git/hooks`; an existing `post-checkout` hook is never overwritten.

Make sure `node_modules` is ignored in your `.gitignore` — that is where CMA keeps its generated service configs.

## Things to watch out for

**Version constraints must be exact.** CMA looks up your version string against its list of supported versions. `^2.4.7` works (the caret is stripped) and `2.4.7-p3` works, but a constraint like `~2.4.7` or `>=2.4.6` fails with `No config found for magento version ~2.4.7`. Pin an exact supported version in `composer.json`.

**Edition mismatches abort the start.** CMA fails fast when `composer.json` requires both editions at once, or when the edition there contradicts `edition` in `cma.js` — see [Review `cma.js`](#review-cmajs).

**A `start` script may already be taken.** CMA never overwrites it — see the hint in [Add CMA to the project](#add-cma-to-the-project).

**`vendor/` is validated against `composer.lock`.** Packages that are in `vendor/` but not in the lock file — a manually dropped module, for instance — make CMA treat the folder as corrupted and re-run `composer install`.


# Improve Performance

## Update to the latest magento-scripts

In **magento-scripts** version **2.4.0,** page load time was reduced significantly. Due to this improvement, Varnish was disabled **by default**.

{% content-ref url="/pages/-MQwi0gNKyS-NeEUvL7L" %}
[Updating to New Releases](/getting-started/updating-to-new-releases)
{% endcontent-ref %}

## Enabling VirtioFS in Docker Desktop on Mac

{% hint style="warning" %}
You must have the following version of macOS in order for this feature to work:

* macOS 12.2 and above (for Apple Silicon)
* macOS 12.3 and above (for Intel)
  {% endhint %}

For the best experience on macOS, it is recommended to enable VirtioFS in the **Docker Desktop** settings > **General** > **Choose file sharing implementation for your containers**.

<figure><img src="/files/Hfc0aD6wX5ko7txNVPke" alt=""><figcaption></figcaption></figure>

See the [blog post from the Docker team introducing VirtioFS](https://www.docker.com/blog/speed-boost-achievement-unlocked-on-docker-desktop-4-6-for-mac/).

{% hint style="warning" %}
At the time of writing, Docker VMM is in Beta and does not work stably in our testing. If you experience installation issues on Composer 2.8 or newer try updating PHP container images to the latest version by running [start with pull-images option](/getting-started/available-commands/start#pull-images)!&#x20;
{% endhint %}

## maritos/magento2-performance-fixes

### Description

To improve first request GraphQL performance we can use Composer package [maritos/magento2-performance-fixes](https://libraries.io/packagist/maritos%2Fmagento2-performance-fixes). (Source code available [here](https://github.com/maritos/magento2-performance-fixes))

In general, this package changes the default cache building process, when the cache is empty, it locks all incoming requests and waits until the first request finishes building cache and then all following requests instead of rebuilding cache just use it right away.

So yeah, up to 30% speed improvements for GraphQL requests on the first load from a thin air.

### Installation

#### Install Composer package

Install Composer package in your project.

```bash
npm run cli # open CLI

c require maritos/magento2-performance-fixes # install package
```

#### Extend composer.json

Add `extra` field in `composer.json`

{% code title="composer.json" %}

```javascript
"extra": {
    "magento-force": "override",
    "enable-patching": true,
    "composer-exit-on-patch-failure": true,
    "patches": {
        "magento/framework": {
            "performance fix #1 - vendor/magento/framework/Config/Data.php": "vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/Config/Data.patch",
            "performance fix #2 - vendor/magento/framework/App/ObjectManager/ConfigLoader.patch": "vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/App/ObjectManager/ConfigLoader.patch",
            "performance fix #3 - vendor/magento/framework/Interception/Config/Config.patch": "vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/Interception/Config/Config.patch"
        }
    }
}
```

{% endcode %}

#### Run composer install

After `composer install` make sure patches have been applied.\
Composer install output should be similar to:

```javascript
  - Applying patches for magento/framework
    vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/Config/Data.patch (performance fix #1 - vendor/magento/framework/Config/Data.php)
    vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/App/ObjectManager/ConfigLoader.patch (performance fix #2 - vendor/magento/framework/App/ObjectManager/ConfigLoader.patch)
    vendorPatch/magento/framework/Interception/Config/Config.patch (performance fix #3 - vendor/magento/framework/Interception/Config/Config.patch)
```

That's it! Happy coding!


# PHP Images

Create Magento App uses custom PHP images hosted on GitHub Docker Registry ([Containers home page](https://github.com/scandipwa/create-magento-app/pkgs/container/create-magento-app)).

## Supported CPU architectures

All images are built using [Docker Buildx](https://github.com/docker/buildx) for **amd64** and **arm64** CPU architectures.\
All current Intel (x86), AMD (x86) and Apple (arm64) CPUs should work with those container images.

## Details

### PHP 8.5 Images

Those images are available for try in Magento 2.4.9-beta1.

{% content-ref url="/pages/08EyslmKYbd043ygf7Jv" %}
[PHP 8.5](/container-images/php-images/php-8.5)
{% endcontent-ref %}

### PHP 8.4 Images

Those images are used in the following Magento versions:

* 2.4.9-beta1
* 2.4.8 (+ patches)

{% content-ref url="/pages/vpSDnSuKFBfwuTIkqoUv" %}
[PHP 8.4](/container-images/php-images/php-8.4)
{% endcontent-ref %}

### PHP 8.3 Images

Those images are used in the following Magento versions:

* 2.4.8&#x20;
* 2.4.7 (+ patches)

{% content-ref url="/pages/LqCKbbpQc35pOonBtI9a" %}
[PHP 8.3](/container-images/php-images/php-8.3)
{% endcontent-ref %}

### PHP 8.2 Images

Those images are used in the following Magento versions:

* 2.4.6 (optional) (+ patches)
* 2.4.7 (+ patches)

{% content-ref url="/pages/VMV17YEjjbT5RQZZdJAI" %}
[PHP 8.2](/container-images/php-images/php-8.2)
{% endcontent-ref %}

### PHP 8.1 Images

Those images are used in the following Magento versions:

* 2.4.4 (+ patches)
* 2.4.5 (+ patches)

{% content-ref url="/pages/hVj554nAwhrEOSu2bnU1" %}
[PHP 8.1](/container-images/php-images/php-8.1)
{% endcontent-ref %}

### PHP 7.4 Images

Those images are used in the following Magento versions:

* 2.3.7 (+ patches)
* 2.4.0 (+ patches)
* 2.4.1 (+ patches)
* 2.4.2 (+ patches)
* 2.4.3 (+ patches)

{% content-ref url="/pages/V3tFftvmv5sIZINJq1LK" %}
[PHP 7.4](/container-images/php-images/php-7.4)
{% endcontent-ref %}

### PHP 7.3 Images

Those images are used in the following Magento versions:

* 2.3.3 (+ patches)
* 2.3.4 (+ patches)
* 2.3.5 (+ patches)
* 2.3.6 (+ patches)

{% content-ref url="/pages/5hUKRmX7oVeJx5XnMfPw" %}
[PHP 7.3](/container-images/php-images/php-7.3)
{% endcontent-ref %}

### PHP 7.2 Images

Those images are used in the following Magento versions:

* 2.2.10
* 2.3.0
* 2.3.1
* 2.3.2 (+ patches)

{% content-ref url="/pages/4ODoVb0PDLdYTzEj5jd6" %}
[PHP 7.2](/container-images/php-images/php-7.2)
{% endcontent-ref %}


# PHP 8.5

## Magento 2.4 extensions bundle

To pull the PHP 8.5 image with Magento 2.4 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-8.5-magento-2.4
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-8.5-magento-2.4'
        }
    }
};
```

{% endcode %}


# PHP 8.4

## Magento 2.4 extensions bundle

To pull the PHP 8.4 image with Magento 2.4 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-8.4-magento-2.4
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-8.4-magento-2.4'
        }
    }
};
```

{% endcode %}


# PHP 8.3

## Magento 2.4 extensions bundle

To pull the PHP 8.3 image with Magento 2.4 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-8.3-magento-2.4
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-8.3-magento-2.4'
        }
    }
};
```

{% endcode %}


# PHP 8.2

## Magento 2.4 extensions bundle

To pull the PHP 8.2 image with Magento 2.4 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-8.2-magento-2.4
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-8.2-magento-2.4'
        }
    }
};
```

{% endcode %}


# PHP 8.1

## Magento 2.4 extensions bundle

To pull the PHP 8.1 image with Magento 2.4 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-8.1-magento-2.4
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-8.1-magento-2.4'
        }
    }
};
```

{% endcode %}


# PHP 7.4

## Magento 2.4 extensions bundle

To pull the PHP 7.4 image with Magento 2.4 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-7.4-magento-2.4
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-7.4-magento-2.4'
        }
    }
};
```

{% endcode %}


# PHP 7.3

## Magento 2.4 extensions bundle

To pull the PHP 7.3 image with Magento 2.4 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-7.3-magento-2.4
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-7.3-magento-2.4'
        }
    }
};
```

{% endcode %}

## Magento 2.3 extensions bundle

To pull the PHP 7.3 image with Magento 2.3 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-7.3-magento-2.3
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-7.3-magento-2.3'
        }
    }
};
```

{% endcode %}


# PHP 7.2

## Magento 2.3 extensions bundle

To pull the PHP 7.2 image with Magento 2.3 extensions, you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:php-7.2-magento-2.3
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        php: {
            baseImage: 'ghcr.io/scandipwa/create-magento-app:php-7.2-magento-2.3'
        }
    }
};
```

{% endcode %}


# ElasticSearch Images

{% hint style="danger" %}
magento-scripts v2.4.10 retires custom ElasticSearch image. Instead, ElasticSearch 6.8 and 7.6 OOTB will run in `linux/amd64` mode on Apple Silicon.
{% endhint %}

Create Magento App uses some custom ElasticSearch images hosted on GitHub Docker Registry ([Containers home page](https://github.com/scandipwa/create-magento-app/pkgs/container/create-magento-app)).

The only reason the following images are built by us and hosted on GitHub Docker Registry is that the original ElasticSearch image does not have both amd64 and arm64 CPU architectures supported.

## Supported CPU architectures

All images are built using [Docker Buildx](https://github.com/docker/buildx) for **amd64** and **arm64** CPU architectures.\
All current Intel (x86), AMD (x86) and Apple (arm64) CPUs should work with those container images.

## Details

### ElasticSearch 6.8

This image is used in the following Magento versions:

* 2.2.10
* 2.3.0
* 2.3.1 (+ patches)
* 2.3.2 (+ patches)
* 2.3.3 (+ patches)
* 2.3.4 (+ patches)

{% content-ref url="/pages/K48yeO1GsyJOxjwWhCCO" %}
[ElasticSearch 6.8](/container-images/elasticsearch-images/elasticsearch-6.8)
{% endcontent-ref %}


# ElasticSearch 6.8

To pull the ElasticSearch 6.8 image you can run the following command:

```bash
docker pull ghcr.io/scandipwa/create-magento-app:elasticsearch-6.8
```

You can set this image in the configuration file to be used in your project.

{% code title="cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    // ... other configurations
    configuration: {
        elasticsearch: {
            image: 'ghcr.io/scandipwa/create-magento-app:elasticsearch-6.8'
        }
    }
};
```

{% endcode %}


# PHP Extensions

{% content-ref url="/pages/xCoRIWBhWTf17K5GYaSf" %}
[PHP Extensions Package](/scripts-extensions/php-extensions/php-extensions-package)
{% endcontent-ref %}

{% content-ref url="/pages/jMrg2C5xZUMzImXlsI8F" %}
[(deprecated) ionCube Extension](/scripts-extensions/php-extensions/deprecated-ioncube-extension)
{% endcontent-ref %}


# PHP Extensions Package

This package simplifies the installation of the following PHP extensions in the Create Magento App project using `magento-scripts` **V2**.

* `memcached`
* `pdo_sqlsrv` (Microsoft SQL Server)
* `sqlsrv` (Microsoft SQL Server)&#x20;
* `ionCube`
* `Imagick` (since version 1.0.6)

{% hint style="info" %}
With newer versions of the package, this list might be updated!
{% endhint %}

### Installation

1. Install package.

   ```bash
   npm i @scandipwa/magento-scripts-php-extensions@latest

   # or with yarn

   yarn add @scandipwa/magento-scripts-php-extensions@latest
   ```
2. Enable extensions in `cma.js`

   <pre class="language-javascript"><code class="lang-javascript"><strong>// cma.js
   </strong>const {
       ioncube,
       memcached,
       pdo_sqlsrv,
       sqlsrv,
       imagick
   } = require('@scandipwa/magento-scripts-php-extensions');

   /** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
   module.exports = {
       // ... other configurations
       configuration: {
           php: {
               extensions: { // &#x3C;- set extensions here
                   ioncube,
                   memcached,
                   pdo_sqlsrv,
                   sqlsrv,
                   imagick
               }
           }
       }
   };
   </code></pre>
3. Run `magento-scripts`

   ```bash
   npm start

   # or with yarn

   yarn start
   ```

### Demo

Demo setup available [here](https://github.com/scandipwa/create-magento-app/tree/master/sample-packages/magento-2.4.3-p1-ioncube)


# (deprecated) ionCube Extension

{% hint style="danger" %}

### Deprecated package!

Please use [PHP Extensions Package](/scripts-extensions/php-extensions/php-extensions-package) for installing the ionCube PHP extension into the CMA V2 project!
{% endhint %}

This extension simplifies the installation of ionCube extension in CMA project.

## Installation

1\. Install package.

```bash
npm i @scandipwa/magento-scripts-php-ioncube-extension@latest

# with yarn

yarn add @scandipwa/magento-scripts-php-ioncube-extension@latest
```

2\. Enable extension in `cma.js`

{% code title="cma.js" %}

```javascript
const ioncube = require('@scandipwa/magento-scripts-php-ioncube-extension');

/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: {
        // ... magento config
    },
    configuration: {
        php: {
            extensions: {
                ioncube // <- set extension here
            }
        }
    }
};
```

{% endcode %}

3\. Run `magento-scripts`

```bash
npm start

# with yarn

yarn start
```

4\. Confirm that extension is installed

```bash
npm run cli

> php -v
PHP 7.4.27 (cli) (built: Jan  7 2022 17:53:56) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with the ionCube PHP Loader + ionCube24 v11.0.0, Copyright (c) 2002-2021, by ionCube Ltd.
```

## Demo

Demo setup available [here](https://github.com/scandipwa/create-magento-app/tree/master/sample-packages/magento-2.4.3-p1-ioncube)


# Common Issues

## Required parameter 'theme\_dir' was not passed

![](/files/AmxGP0Ld8uTjFEjud8x8)

The issue appears when you have an incorrect theme path in the theme configuration in the database.

To fix the issue follow the steps below:

1. Connect to your database using the database client. (like [Beekeeper Studio](https://www.beekeeperstudio.io/))

   You can get host, port and credentials after running the [status](/getting-started/available-commands/status) command.
2. Open `core_config_data` table and find a row with `design/theme/theme_id` path value.
3. Open `theme` table and find a row with `theme_id` value corresponding to `value` from the previous step.
4. Make sure that `theme_path` value is the same as the one declared in your theme's `registration.php` file. (for ScandiPWA it will be likely `scandipwa/scandipwa`)

## SQLSTATE\[HY000] \[2002] No such file or directory

An error message should look like this:

```
Response: SQLSTATE[HY000] [2002] No such file or directory

In InstallCommand.php line 274:
                               
Parameter validation failed  
                               

setup:install ...
```

This issue happens when `env.php`  file is missing.

Run [start](/getting-started/available-commands/start) command the second time.

## SQLSTATE\[HY000] \[2006] MySQL server has gone away

{% hint style="info" %}
Should not appear on **magento-scripts@>=1.3.0**.
{% endhint %}

```
Response: SQLSTATE[HY000] [2006] MySQL server has gone away

In InstallCommand.php line 274:
                               
Parameter validation failed


setup:install ...
```

This issue might appear at the first start of the project.

Run [start](/getting-started/available-commands/start) command the second time.

## The default website isn't defined. Set the website and try again.

{% hint style="info" %}
Should not appear on **magento-scripts@>=1.4.0**.
{% endhint %}

This issue might appear if you, for some reason, have no Magento database installed in MySQL.

Delete `app/etc/env.php` file, after that run [start](/getting-started/available-commands/start) command.\
This will force CMA to reinstall Magento but you will lose some configuration, for example, a persisted query that is required for the ScandiPWA theme.

## Connection to Redis localhost:port failed after 1 failures. Connection refused.

{% hint style="info" %}
Should not appear on **magento-scripts@>=1.3.1**.
{% endhint %}

This issue might appear if your port configuration has changed but Magento still uses old configuration.

There are 2 options on how to solve such a problem:

* Get current port configuration from `docker ps` or [status](/getting-started/available-commands/status) command and edit `app/etc/env.php` file and run the [start](/getting-started/available-commands/start) command.&#x20;

{% hint style="success" %}
&#x20;**Recommended,** as it is the safest option.
{% endhint %}

* Delete  `app/etc/env.php` file and run the [start](/getting-started/available-commands/start) command.

{% hint style="danger" %}
**Not recommended,** because you will lose **all** the configuration from that file.
{% endhint %}

## Redis is not configured for persistent queries.

{% hint style="info" %}
Should not appear on **magento-scripts@>=1.6.0**
{% endhint %}

This issue might appear if you have a theme installed but persisted queries are not set up for some reason.

Run [link](/getting-started/available-commands/link) command to re-link the theme and setup persisted queries.

## There are no commands defined in the "config" namespace.

This issue might appear if you have previously installed Magento with CMA but now lost all the data in MySQL for some reason.

Delete `app/etc/env.php` and run the [start](/getting-started/available-commands/start) command again.


# CMA Debugging

Create Magento App is a Node.js application and can be debugged just like any other Node.js application without any additional configuration. The easiest and preferred way of debugging CMA is via VSCode.

In order to debug with VSCode, you will need Node.js 11 or late and the setup is very simple:

1. Open up `package.json` in the project root folder.
2. The "Debug" button will appear above the "scripts" section.
3. Press the "Debug" button and select a script that you want to debug.
4. Set breakpoints and happy debugging!

During the CMA runtime, a list of steps or tasks is displayed in the terminal, which further simplifies the process of identifying the problem. The code for each task is isolated into its own file or function and is easily accessible in the code. Create Magento App is using `@scandipwa/magento-scripts` package that is located inside the `node_modules` folder to store all of the logic.

## Identifying the problem

In case the CMA installation failed, one of the tasks will be marked with a red cross. This is the task where something went wrong:

![CMA installation has failed at one of the tasks](/files/-MWERS-IfsztM2e7N-NK)

Most of the time, you will be given a human-readable error message explaining the problem and offering a solution. In case of an unexpected error, however, you might not be given any viable information and an immediate solution.

In order to debug CMA installation, the only thing you need to know is the name of the task, "Configuring PHP extensions" in my case. As mentioned above, all of the related code is located inside of `node_modules/@scandipwa/magento-scripts` folder and we will need to find that particular task in the code.

![Finding the task using VSCode](/files/-MWETBXWfqc3qz7ayT7u)

In most cases, a task can be found using the search functionality of your code editor. In some cases, however, the name of the task is set dynamically, such as "Using PHP version 7.4.13, checking extensions...". With this particular task, you can either search for just "Using PHP version" to find the place where it's set or find the task manually in the list of tasks.

The list of all tasks for a command is located inside the corresponding file in the `node_modules/@scandipwa/magento-scripts/lib/tasks` folder. As I am trying to debug the `yarn start` command, I can find the list of tasks in the `node_modules/@scandipwa/magento-scripts/lib/tasks/start.js` file.

![Tasks for CMA start command](/files/-MWEUKg6C-1qwTjariaA)

From the start command output, I know that the task that didn't run correctly went right after the "Saving Configuration" task that is easily locatable in the task list (line 33). And this means that the failed task is visible in the code by the name of `installPhp`. From that file, I can find the place where the computed task title is created,

![Place where the task name is generated](/files/-MWEW493FddZyFuTjr24)

And I can immediately see what's run next. In this case, a new task is executed, which happens to be the "Configuring PHP extensions" task that failed during the build. Now I am able to set the breakpoint inside of that task

![Setting the breakpoint inside of the failed task](/files/-MWEWY99EBgqhhLuIh5X)

## Debugging

Now I can run the debugger from the package.json in the project root.

![Running the debugger from package.json using the "Debug" button](/files/-MWEWqwvZK-gYVf6djuI)

The breakpoint will be triggered and now I will be able to debug the task line by line to identify and solve the problem.

![Breakpoint triggered during the "yarn start" script](/files/-MWEXLRMtfXlktcuxafz)


# Uninstall CMA

## 1. Uninstall Docker

On Mac, follow [these instructions](https://docs.docker.com/desktop/mac/install/#uninstall-docker-desktop) to remove Docker from your system.

On Windows, follow [these instructions](https://docs.docker.com/desktop/windows/install/#uninstall-docker-desktop) to remove Docker from your system.

On Linux, follow the following instructions for your distro:

{% tabs %}
{% tab title="Ubuntu" %}
1\. Uninstall the Docker Engine, CLI, and ContainerD packages:

```bash
sudo apt-get purge docker-ce docker-ce-cli containerd.io
```

2\. Images, containers, volumes, or customized configuration files on your host are not automatically removed. To delete all images, containers, and volumes:

```bash
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
```

Documentation is available [here](https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine).
{% endtab %}

{% tab title="Arch Linux" %}
To uninstall the Docker package:

```bash
sudo pacman -R docker
```

To uninstall the Docker package and dependencies that are no longer needed:

```bash
sudo pacman -Rns docker
```

The above commands will not remove images, containers, volumes, or user-created configuration files on your host. If you wish to delete all images, containers, and volumes run the following command:

```bash
rm -rf /var/lib/docker
```

Documentation is available [here](https://github.com/saturnism/docker/blob/master/docs/installation/archlinux.md#uninstallation).
{% endtab %}

{% tab title="CentOS" %}
1\. Uninstall the Docker Engine, CLI, and ContainerD packages:

```bash
sudo yum remove docker-ce docker-ce-cli containerd.io
```

2\. Images, containers, volumes, or customized configuration files on your host are not automatically removed. To delete all images, containers, and volumes:

```bash
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
```

Documentation is available [here](https://docs.docker.com/engine/install/centos/#uninstall-docker-engine).
{% endtab %}

{% tab title="Fedora" %}
1\. Uninstall the Docker Engine, CLI, and ContainerD packages:

```bash
sudo dnf remove docker-ce docker-ce-cli containerd.io
```

2\. Images, containers, volumes, or customized configuration files on your host are not automatically removed. To delete all images, containers, and volumes:

```bash
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
```

Documentation is available [here](https://docs.docker.com/engine/install/fedora/#uninstall-docker-engine).
{% endtab %}
{% endtabs %}


# Create Magento App

Setting up Magento 2 framework on local can be stressful and take a long time. Worry not! We got you covered. This deployment technology combines two powerful approaches of containerization and Infrastructure as code to provision you a Magento 2 instance in minutes!

## 🚀 Get started in seconds

Create Magento App is a tiny package for HUGE framework. To create Magento app in seconds:

{% content-ref url="/pages/-MOVw4x6GNBPspaAoTXi" %}
[Getting started](/v1/getting-started/getting-started)
{% endcontent-ref %}

Upon creation, type in the [start command](/v1/getting-started/available-commands/start) to run the application deployment:

```bash
yarn start # for Yarn
npm start # for NPM
```

{% content-ref url="/pages/-MOqKE-M1Z08ORUmn5Qp" %}
[Available commands](/v1/getting-started/available-commands)
{% endcontent-ref %}

## 🤝 Conflict-less design

The application will automatically select free ports. It will never let services previously installed on your machine down!

**Screwed a local installation?** Worry not, Create Magento App will set you up!&#x20;

## 🐛 Easy debugging

The powerful [XDebug](https://xdebug.org/) tool is a single command-line option flag away from you! Read how to use it:

{% content-ref url="/pages/-MOqXZ-Yri-qEN8pRN9x" %}
[Enabling XDebug](/v1/usage-guide/enabling-xdebug)
{% endcontent-ref %}


# Getting Started

Create a new CMA instance in minutes

## Summary

* [ ] Make sure you have Node v12 or newer
* [ ] Install `create-magento-app` dependencies
* [ ] Initialize app with `create-magento-app`
* [ ] Enter the app's directory
* [ ] Start up the app with `npm start`

## Install Dependencies

**You’ll need to have Node >= 12 on your local development machine** (but it’s not required on the server). You can use [n](https://www.npmjs.com/package/n) (macOS, Linux) or [nvm-windows](https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows) to switch Node versions between different projects.

In addition, before setting up, make sure you have installed the **libraries required to build the PHP**. Also, make sure to install **Docker** and **PHPBrew** in your system. See more in the detailed guides below:

{% content-ref url="/pages/-MOVwpsWQzCvRc9jcPL8" %}
[Linux requirements](/v1/getting-started/prerequisites/installation-on-linux)
{% endcontent-ref %}

{% content-ref url="/pages/-MOVx1PztQ7aSC\_MXO2i" %}
[MacOS requirements](/v1/getting-started/prerequisites/installation-on-macos)
{% endcontent-ref %}

{% content-ref url="/pages/-MbpJWmV3cwn0JVn5fvs" %}
[Windows requirements](/v1/getting-started/prerequisites/windows-requirements)
{% endcontent-ref %}

## Creating an App

To create a new app, you may choose one of the following methods:

{% tabs %}
{% tab title="NPX" %}

```bash
npx create-magento-app my-app
```

{% endtab %}

{% tab title="NPM" %}

```
npm init magento-app my-app
```

{% endtab %}

{% tab title="Yarn" %}

```
yarn create magento-app my-app
```

{% endtab %}
{% endtabs %}

Running any of these commands will create a directory called `my-app` inside the current folder. Inside that directory, it will generate the initial project structure and install the transitive dependencies. Learn more:

{% content-ref url="/pages/-MOWYsDpr9cLMyMxtSOj" %}
[Folder structure](/v1/getting-started/folder-structure)
{% endcontent-ref %}

## Running the App

To start the app, navigate to its directory and run the `start` command:

```
cd my-app
npm start
```

This command will start Docker services, start Magento and open your app in the browser.

Create Magento App choose an available port for Magento 2 so it can vary. By default, it will use port 80 so the URL for the store will be <http://localhost:80/>.

### ScandiPWA setup and Theme Linking

If you plan to use the ScandiPWA theme, you have to do the [ScandiPWA setup](https://docs.create-scandipwa-app.com/getting-started/getting-started) and then come back to this CMA guide to do the theme linking:

{% content-ref url="/pages/-MO\_vUfSeKHDP-fbkXSh" %}
[Linking a Scandi Theme](/v1/usage-guide/themes)
{% endcontent-ref %}


# Prerequisites

Before setting up, make sure you have installed the **libraries required to build the PHP**. Also, make sure to install **Docker** and **PHPBrew** in your system. See more in the detailed guides below:

{% content-ref url="/pages/-MOVwpsWQzCvRc9jcPL8" %}
[Linux requirements](/v1/getting-started/prerequisites/installation-on-linux)
{% endcontent-ref %}

{% content-ref url="/pages/-MOVx1PztQ7aSC\_MXO2i" %}
[MacOS requirements](/v1/getting-started/prerequisites/installation-on-macos)
{% endcontent-ref %}

{% content-ref url="/pages/-MbpJWmV3cwn0JVn5fvs" %}
[Windows requirements](/v1/getting-started/prerequisites/windows-requirements)
{% endcontent-ref %}


# Linux requirements

{% hint style="danger" %}
**OpenSSL 3.0** is not supported!\
PHP introduced support for **OpenSSL 3.0** only in PHP 8.1, so you will not be able to compile older versions of PHP if you have **OpenSSL 3.0** in your system.\
\
Ubuntu 22.04 ships with **OpenSSL 3.0**, so ATM you will need an older release of Ubuntu of another distro that has **OpenSSL 1.1**
{% endhint %}

## 1. Install platform-specific dependencies:

{% hint style="warning" %}
Since **magento-scripts 1.4.0** CMA will also check installed dependencies before starting the application, and if they are missing will provide instructions on how to install them!
{% endhint %}

{% tabs %}
{% tab title="Ubuntu" %}

```bash
sudo apt install \
    libcurl4-openssl-dev \
    libonig-dev \
    libjpeg-dev \
    libjpeg8-dev \
    libjpeg-turbo8-dev \
    libpng-dev \
    libicu-dev \
    libfreetype6-dev \
    libzip-dev \
    libssl-dev \
    build-essential \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    libssl-dev \
    libxml2-dev \
    libxslt1-dev \
    libonig-dev \
    php-cli \
    php-bz2 \
    pkg-config \
    autoconf \
    libsodium-dev \
    cmake \
    php
```

{% endtab %}

{% tab title="Linux Mint" %}

```bash
sudo apt install \
    libjpeg-dev \
    libjpeg8-dev \
    libjpeg-turbo8-dev \
    libpng-dev \
    libicu-dev \
    libfreetype6-dev \
    libzip-dev \
    libssl-dev \
    build-essential \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    libssl-dev \
    libxml2-dev \
    libxslt1-dev \
    libonig-dev \
    php-cli \
    php-bz2 \
    pkg-config \
    autoconf \
    libcurl4-openssl-dev \
    libsodium-dev \
    cmake \
    php
```

{% endtab %}

{% tab title="CentOS" %}

```bash
sudo yum install --enablerepo=PowerTools \
    openssl-devel \
    libjpeg-turbo-devel \
    libpng-devel \
    gd-devel \
    libicu \
    libicu-devel \
    libzip-devel \
    libtool-ltdl-devel \
    oniguruma-devel \
    libsodium \
    libsodium-devel \
    libtool-ltdl-devel \
    oniguruma-devel \
    libxml2-devel \
    bzip2-devel \
    curl-devel \
    libxslt-devel \
    autoconf \
    php
```

{% endtab %}

{% tab title="Fedora" %}

```bash
sudo yum install openssl-devel \
    openssl-devel \
    libjpeg-turbo-devel \
    libpng-devel \
    gd-devel \
    libicu \
    libicu-devel \
    libzip-devel \
    libtool-ltdl-devel \
    oniguruma-devel \
    libsodium \
    libsodium-devel \
    libtool-ltdl-devel \
    oniguruma-devel \
    libxml2-devel \
    bzip2-devel \
    curl-devel \
    libxslt-devel \
    autoconf \
    php
```

{% endtab %}

{% tab title="Arch Linux" %}

```bash
sudo pacman -S freetype2 \
    openssl \
    oniguruma \
    libxslt \
    bzip2 \
    libjpeg-turbo \
    libpng \
    icu \
    libxml2 \
    autoconf \
    libzip \
    sqlite \
    readline \
    perl \
    libsodium \
    php \
    pkgconf
```

{% endtab %}
{% endtabs %}

## 2. Install Docker

You can follow the [official installation guide from Docker](https://docs.docker.com/engine/install/ubuntu/) or use commands below:

```bash
# Download installation script
curl -fsSL https://get.docker.com -o get-docker.sh

# Run installation script
sudo bash get-docker.sh

# Add your user to the “docker” group to run docker without root.
sudo usermod -aG docker $USER

# After that you'll need to logout and login to your account or,
# you can temporarily enable group changes by running command below
newgrp docker
```

## 3. Install PHPBrew

{% hint style="warning" %}
Since **magento-scripts\@1.7.0** this part will be done automatically.
{% endhint %}

To install PHPBrew on Linux you will need to follow [installation](https://github.com/phpbrew/phpbrew#installation) instructions or use commands below:

```bash
# Download PHPBrew
curl -L -O https://github.com/phpbrew/phpbrew/releases/latest/download/phpbrew.phar

# Make it executable
chmod +x phpbrew.phar

# Move PHPBrew binary to system folder.
sudo mv phpbrew.phar /usr/local/bin/phpbrew

# Initialize PHPBrew
phpbrew init
```

## 4. Prepare the environment

To work with Magento you need access keys to access the Magento repository.

1. Go to <https://marketplace.magento.com/customer/accessKeys/>
2. Generate Access Keypair

Now you have a **public key** and **private key** values.

To use them you have 2 options:

1. **Use `COMPOSER_AUTH` environmental variable**

   This option is used as a global variable on your machine.

   Replace `<public key>` and `<private key>` with your public and private key.

   ```bash
   export COMPOSER_AUTH='{
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }'
   ```

   Add the result to your `.bashrc` or `.zshrc` and reload your terminal.
2. **Use auth.json file**

   This option is used on a per-project basis, so your credentials will be always correct no matter which project you are working on.

   Create `auth.json` file in the root of your project and inside put the following content using the same `<public key>` and `<private key>` you obtained before:

   ```
   {
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }
   ```

## 5. Start your application

{% hint style="info" %}
Start command description can be found [here](/v1/getting-started/available-commands/start).\
To access Magento CLI, Composer and PHP use [cli](/v1/getting-started/available-commands/cli) command.
{% endhint %}


# MacOS requirements

{% hint style="success" %}
**Apple Silicon** is supported as well!\
To get CMA working on Apple Silicon go to [the following section](/v1/getting-started/prerequisites/installation-on-macos/installation-on-macos-apple-silicon).&#x20;
{% endhint %}

{% content-ref url="/pages/-MZWxY9FTrMx55hi5ewh" %}
[Apple Silicon](/v1/getting-started/prerequisites/installation-on-macos/installation-on-macos-apple-silicon)
{% endcontent-ref %}

## 1. Install Brew

Brew can be installed from the [official website](https://brew.sh/) or you can copy-paste this command in your mac terminal:

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

## 2. Install dependencies

Run the command below to install the required system dependencies.

{% hint style="warning" %}
Since **magento-scripts\@1.4.0** CMA will also check installed dependencies before starting the application.\
If some of them **are missing**, will provide instructions on how to install them!
{% endhint %}

{% tabs %}
{% tab title="Intel / X86 (Rosetta 2)" %}

```bash
brew install zlib \
    bzip2 \
    libiconv \
    libzip \
    libsodium \
    curl \
    libpng \
    gd \
    freetype \
    oniguruma \
    icu4c \
    libxml2 \
    openssl@1.1
```

{% endtab %}

{% tab title="M1 / ARM64" %}

```bash
brew install php \
    autoconf \
    pkg-config \
    gd
```

{% endtab %}
{% endtabs %}

You need to install dependencies for both platforms if you are running the M1 system!

## 3. Install Docker for Mac

Download and install Docker Desktop for Mac following the [official installation guide](https://docs.docker.com/docker-for-mac/install/).

{% hint style="warning" %}

## Heads up!

If you are working outside of users directory make sure to add your directory to bindable directory list in **Docker** preferences. (**Docker -> Preferences -> Resources -> File Sharing**)\
If you don't do that, **Docker** will be unable to mount some directories inside containers and you will get **startup** **error**.
{% endhint %}

## 3.1 Increase available resources for Docker

Increase the amount of allocated memory to at least 4 GB.\
Go to **Docker > Preferences > Resources > Memory > Advanced**. There drag memory slider to be at least 4 GB. You can also decrease **swap** size to its minimum value.\
\
Also, you can increase the number of CPUs available for Docker.\
By default, Docker Desktop is set to use half the number of processors available on the host machine. The more you set, the faster Docker containers will be.\
Just note that the more CPUs you select, the fewer resources will be left for your system.

## 4. Install PHPBrew

{% hint style="warning" %}
Since **magento-scripts\@1.7.0** this part will be done automatically.
{% endhint %}

PHPBrew is used to compile PHP with required extensions to run Magento 2 on your system.

```bash
# Install XCode
xcode-select --install

# Install PHPBrew dependencies
brew install autoconf pkg-config

# Download PHPBrew
curl -L -O https://github.com/phpbrew/phpbrew/releases/latest/download/phpbrew.phar

# Make it executable
chmod +x phpbrew.phar

# Move PHPBrew binary to system folder.
sudo mv phpbrew.phar /usr/local/bin/phpbrew

# Initialize PHPBrew
phpbrew init
```

## 5. Prepare the environment

To work with Magento you need access keys to access the Magento repository.

1. Go to <https://marketplace.magento.com/customer/accessKeys/>
2. Generate Access Keypair

Now you have a **public key** and **private key** values.

To use them you have 2 options:

1. **Use `COMPOSER_AUTH` environmental variable**

   This option is used as a global variable on your machine.

   Replace `<public key>` and `<private key>` with your public and private key.

   ```bash
   export COMPOSER_AUTH='{
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }'
   ```

   Add the result to your `.bashrc` or `.zshrc` and reload your terminal.
2. **Use auth.json file**

   This option is used on a per-project basis, so your credentials will be always correct no matter which project you are working on.

   Create `auth.json` file in the root of your project and inside put the following content using the same `<public key>` and `<private key>` you obtained before:

   ```
   {
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }
   ```

## 6. Start your application

{% hint style="info" %}
Start command description can be found [here](/v1/getting-started/available-commands/start).\
To access Magento CLI, Composer and PHP use [cli](/v1/getting-started/available-commands/cli) command.
{% endhint %}


# Apple Silicon

{% hint style="warning" %}
Available since **magento-scripts 1.5.0**
{% endhint %}

## System preparation

To prepare your system you will need to be running CMA under Rosetta 2.

Install Rosetta 2 first:

```bash
softwareupdate --install-rosetta
```

After installing rosetta, we also need to configure the terminal to run CMA under emulation.

1. Locate the Terminal application within the **Utilities** folder (**Finder > Go menu > Utilities**)
2. Select `Terminal.app` and right-click on it, then choose “Duplicate”
3. Rename the duplicated Terminal app something obvious and distinct, like ‘Rosetta Terminal’
4. Now select the freshly renamed ‘Rosetta Terminal’ app and right-click and choose “Get Info” (or hit **Command+i**)
5. Check the box for “Open using Rosetta”, then close the Get Info window
6. Run the “Rosetta Terminal” as usual.

Now, we need to install 2 versions of [Brew package manager](https://brew.sh/): intel x86 version and arm version.\
To do that, open both native and rosetta terminals and run the usual install command in both of them:

```shell
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

Now we have 2 Brew installed, but to actually use the correct brew depending on our terminal translation enabled we need to put the following script inside your `$HOME/.zshrc` file.

```bash
if [ "$(sysctl -n sysctl.proc_translated)" = "1" ]; then
    local brew_path="/usr/local/homebrew/bin"
else
    local brew_path="/opt/homebrew/bin"
fi
export PATH="${brew_path}:${PATH}"
```

And after this, proceed with the usual [MacOS installation](/v1/getting-started/prerequisites/installation-on-macos) using the Rosetta terminal.

## Changes with setup and expected issues

* [MySQL container image](https://hub.docker.com/_/mysql) doesn't have an arm64 version, so we are using [MariaDB](https://hub.docker.com/_/mariadb) instead.\
  MariaDB is a fork of MySQL so almost all of the features should work as expected.
* Sometimes containers might have a problem with connecting to the host network, so after you run the [start](/v1/getting-started/available-commands/start) command and open the browser, it might say that **this site can't be reached**.\
  If you have this problem, try running the [start](/v1/getting-started/available-commands/start) command again, maybe with option [-s](/v1/getting-started/available-commands/start#s-skip-setup) to speed up the startup process.


# Windows requirements

## Using WSL

{% hint style="info" %}
Since **magento-scripts\@1.6.0**
{% endhint %}

### 1. Install WSL

To install WSL2 on Windows follow [this guide](< https://docs.microsoft.com/en-us/windows/wsl/install-win10>).

{% hint style="info" %}
For [step #6 Install your Linux distribution of choice](https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-6---install-your-linux-distribution-of-choice) we recommend choosing the latest Ubuntu release, as it has the best compatibility on Windows.
{% endhint %}

### 1.1 Install Windows Terminal (Optional)

On Windows with WSL, it is recommended to use [Windows Terminal](https://docs.microsoft.com/en-us/windows/terminal/get-started).\
By using it you can open different shells and access different WSL distros in the same place, which is quite handy.

### 1.2 Install Visual Studio Code (Optional)

VSCode has excellent integration with WSL, so you can run commands, edit code and debug it inside a single editor.\
[Developing in WSL](https://code.visualstudio.com/docs/remote/wsl).

![](/files/-McUVj3wq2v7f-su7w7s)

### 2. Install Docker Desktop for Windows

Download and install [Docker Desktop for Windows](https://hub.docker.com/editions/community/docker-ce-desktop-windows).

### 3. Enable WSL 2 integration in Docker Desktop settings

Go to **Docker Desktop settings > General** and make sure that **Use the WSL 2 based engine** checkbox is checked.

![](/files/-McUOZ_owueFFwA0YvX7)

Then, go to Resources >WSL Integration and enable WSL integration into your distro.

![](/files/-McUOmfYntDg4h1lLMRN)

Toggle your distro and click **Apply & Restart**.

### 4. Install platform-specific dependencies:

{% hint style="warning" %}
Since **magento-scripts 1.4.0** CMA will also check installed dependencies before starting the application, and if they are missing will provide instructions on how to install them!
{% endhint %}

Full list of dependencies for each Linux distro available [here](/v1/getting-started/prerequisites/installation-on-linux#1-install-platform-specific-dependencies).

{% tabs %}
{% tab title="Ubuntu" %}

```bash
apt-get install \
    libcurl4-openssl-dev \
    libonig-dev \
    libjpeg-dev \
    libjpeg8-dev \
    libjpeg-turbo8-dev \
    libpng-dev \
    libicu-dev \
    libfreetype6-dev \
    libzip-dev \
    libssl-dev \
    build-essential \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    libssl-dev \
    libxml2-dev \
    libxslt1-dev \
    libonig-dev \
    php-cli \
    php-bz2 \
    pkg-config \
    autoconf \
    libsodium-dev
```

{% endtab %}
{% endtabs %}

### 5. Install PHPBrew

{% hint style="warning" %}
Since **magento-scripts\@1.7.0** this part will be done automatically.
{% endhint %}

To install PHPBrew on Linux you will need to follow [installation](https://github.com/phpbrew/phpbrew#installation) instructions or use the commands below:

```bash
# Download PHPBrew
curl -L -O https://github.com/phpbrew/phpbrew/releases/latest/download/phpbrew.phar

# Make it executable
chmod +x phpbrew.phar

# Move PHPBrew binary to system folder.
sudo mv phpbrew.phar /usr/local/bin/phpbrew

# Initialize PHPBrew
phpbrew init
```

### 6. Prepare the environment

To work with Magento you need access keys to access the Magento repository.

1. Go to <https://marketplace.magento.com/customer/accessKeys/>
2. Generate Access Keypair

Now you have a **public key** and **private key** values.

To use them you have 2 options:

1. **Use `COMPOSER_AUTH` environmental variable**

   This option is used as a global variable on your machine.

   Replace `<public key>` and `<private key>` with your public and private key.

   ```bash
   export COMPOSER_AUTH='{
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }'
   ```

   Add the result to your `.bashrc` or `.zshrc` and reload your terminal.
2. **Use auth.json file**

   This option is used on a per-project basis, so your credentials will be always correct no matter which project you are working on.

   Create `auth.json` file in the root of your project and inside put the following content using the same `<public key>` and `<private key>` you obtained before:

   ```
   {
       "http-basic":{
           "repo.magento.com": {
               "username": "<public key>",
               "password": "<private key>"
           }
       }
   }
   ```

### 7. Start your application

{% hint style="info" %}
Start command description can be found [here](/v1/getting-started/available-commands/start).\
To access Magento CLI, Composer and PHP use [cli](/v1/getting-started/available-commands/cli) command.
{% endhint %}

## Using VM

As an option, you can run CMA on Windows using a Linux VM running in [Virtual Box](https://www.virtualbox.org/) (free) or [VMWare Workstation Player](https://www.vmware.com/products/workstation-player.html) (paid).\
We recommend using [Ubuntu](https://ubuntu.com/download/desktop) or [Fedora](https://getfedora.org/en/workstation/download/) distros, although [Linux Mint](https://linuxmint.com/download.php), [CentOS](https://www.centos.org/download/) and distros based on `apt` , `pacman`, `yum`, `dnf` package managers should also work.\
[Installation guide](/v1/getting-started/prerequisites/installation-on-linux) for this option is the same as installing on a common Linux platform.


# Available commands

There are multiple commands available in Create Magento App:

### `yarn start` or `npm run start`

{% content-ref url="/pages/-MOkehwx5KVpndeSFuNx" %}
[Start the application](/v1/getting-started/available-commands/start)
{% endcontent-ref %}

### `yarn stop` or `npm run stop`

{% content-ref url="/pages/-MOl8skLE48iS\_0zhCUD" %}
[Stop the application](/v1/getting-started/available-commands/stop)
{% endcontent-ref %}

### `yarn status` or `npm run status`

{% content-ref url="/pages/-MOkcAE2gQgtaDLPHnYx" %}
[Check application status](/v1/getting-started/available-commands/status)
{% endcontent-ref %}

### `yarn cli` or `npm run cli`

{% content-ref url="/pages/-MOl9D1L7FUjXY9a6GzM" %}
[Enter application CLI](/v1/getting-started/available-commands/cli)
{% endcontent-ref %}

### `yarn logs` or `npm run logs`

{% content-ref url="/pages/-MOl9Li3NrDe0Pr1eqXX" %}
[Explore application logs](/v1/getting-started/available-commands/logs)
{% endcontent-ref %}

### `yarn link` or `npm run link`

{% content-ref url="/pages/-MOlA0avsCc7JRKYulXU" %}
[Link a theme](/v1/getting-started/available-commands/link)
{% endcontent-ref %}

## Experimental commands

### `yarn cleanup` or `npm run cleanup`

{% content-ref url="/pages/-MOgUGa7-eOwqltf-Iyu" %}
[⚠️ Uninstall a project](/v1/getting-started/available-commands/cleanup)
{% endcontent-ref %}


# Start the application

## `yarn start` or `npm run start`

This command executes a local deployment of your Magento 2 application.\
It does it in the following steps:

1. Prepare your project for Magento 2.
2. Install and compile the correct PHP version with required extensions to run Magento 2.
3. Deploy services, Redis, MySQL, ElasticSearch and Nginx, in Docker containers for Magento 2.
4. Install Magento 2 with Composer.
5. Setup Magento 2.
6. Open a browser with up and running Magento 2 store.

### **Command options**

#### **`-p, --port`**

A port to run your application on.

{% hint style="info" %}
By default, Create Magento App will select a random available port.
{% endhint %}

```bash
yarn start --port <port> # for Yarn
npm run start -- --port <port> # for NPM
```

#### **`-n, --no-open`**

Disable auto-open of a browser window at the end of the workflow.

```bash
yarn start --no-open # for Yarn
npm run start -- --no-open # for NPM
```

#### **`-d, --debug`**

Enable [XDebug](https://xdebug.org/) for debugging PHP.

```bash
yarn start --debug # for Yarn
npm run start -- --debug # for NPM
```

#### **`-s, --skip-setup`**

Skips Magento setup.

{% hint style="warning" %}
**Skipping Magento setup might result in conflict during runtime because Magento config will not be updated with a new port config.**\
This option can be used only if you **100% sure** that the ports configuration is the same.
{% endhint %}

In a nutshell, this option enables start command will just restart services and PHP-FPM, so if you need to restart the project it can be done in under 10 seconds\*.

```bash
yarn start --skip-setup # for Yarn
npm run start -- --skip-setup # for NPM
```

\* Tested on Ryzen 9 3900x system with NVME SSD with a result in 9.5s.

#### `--import-db`

{% hint style="info" %}
Since **magento-scripts\@1.3.0**
{% endhint %}

Imports database dump to the MySQL container.

Does the same thing as the [import-db](/v1/getting-started/available-commands/import-db) command but allows to use it during start, so the project can be bootstrapped from zero in 1 command.

```bash
yarn start --import-db ./dump.sql # for Yarn
npm run start -- --import-db ./dump.sql # for NPM
```

#### `--recompile-php`

{% hint style="info" %}
Since **magento-scripts\@1.6.0**
{% endhint %}

Sometimes, on macOS when dynamic dependencies are updated, PHP might break.\
To fix this issue you need to manually delete the PHP binary in `~/.phpbrew/php/php-<version>`, so CMA will detect it and compile it.\
Now, you just need to pass this option in the start command and CMA will take care of everything.

```bash
yarn start --recompile-php # for Yarn
npm run start -- --recompile-php # for NPM
```

#### `-v, --verbose`

{% hint style="info" %}
Since **magento-scripts\@1.8.0**
{% endhint %}

This option will enable printing of logs from Magento installation, setup and upgrade tasks.

```bash
yarn start --verbose # for Yarn
npm run start -- --verbose # for NPM
```

## Usage example

```bash
yarn start # for Yarn
npm start # for NPM
```


# Stop the application

## `yarn stop` or `npm run stop`

This command stops a local deployment of your Magento 2 application. It does it in the following steps:

1. Gracefully stops PHP-FPM with running Magento.
2. Gracefully stops Docker containers.

## Usage example

```bash
yarn stop # for Yarn
npm run stop # for NPM
```


# Check application status

## `yarn status` or `npm run status`

{% hint style="warning" %}

### Heads up!

Command will work only after Create Magento App is installed.
{% endhint %}

This command will print the current Create Magento App project status. Status includes:

* Project name
* Project location
* Project creation date
* Platform version
* Docker version
* PHPBrew version
* PHP version & location
* Magento version
* Docker containers status
  1. Container name
  2. Container image
  3. Container status
  4. Container network
  5. Container port forwarding
  6. Container environment variables
* Magento URL
* Magento admin panel URL
* Magento admin panel credentials

## Usage example

```bash
npm run status # for NPM
yarn status  # for Yarn
```


# Enter application CLI

## `yarn cli` or `npm run cli`

Opens a new instance of Bash with aliases for PHP, Composer and Magento used in Create Magento App project.

## **Usage example**

First, run the script:

```bash
npm run cli # for NPM
yarn cli # for Yarn
```

Now, in the opened terminal call desired commands:

```bash
php -v
> PHP 7.4.13 (cli) ...

composer --version
> Composer version 1.10.19

# Can be used with alias
c --version
> Composer version 1.10.19

magento setup:upgrade
> ... magento upgrade output

# Can be used with alias
m se:up
> ...magento upgrade output
```


# Explore application logs

## `yarn logs <scope>` or `npm run logs <scope>`

Gives simple access to logs from Nginx, Redis, MySQL and ElasticSearch containers and Magento.

{% hint style="info" %}
Before **magento-scripts** version 1.4.1 this command will attach logs from chosen service to your terminal so to exit press `CTRL + C`. To attach logs use option **-f**.
{% endhint %}

### **Available scopes**

* `mysql`
* `nginx`
* `redis`
* `elasticsearch`
* `magento`

### **Command options**

#### `--details`

Show extra details provided to logs

```bash
yarn logs nginx --details # for Yarn
npm run logs nginx -- --details # for NPM
```

#### `--timestamps, -t`

Show timestamps

```bash
yarn logs nginx --timestamps # for Yarn
npm run logs nginx -- --timestamps # for NPM
```

#### `--follow, -f`

Follow log output

```bash
yarn logs nginx --follow # for Yarn
npm run logs nginx -- --follow # for NPM
```

#### `--since`

Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

```bash
yarn logs nginx --since=2s # for Yarn
npm run logs nginx -- --since=2s # for NPM
```

#### `--until`

Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

```bash
yarn logs nginx --until=2s # for Yarn
npm run logs nginx -- --until=2s # for NPM
```

## **Usage example**:

```bash
yarn logs nginx

> ... # nginx logs

# ctrl + c

# this is not alias, but rather service name matching
yarn logs n # or n

> ... # nginx logs

# and for mysql
yarn logs m # or mysql

> ... # mysql logs

# and for magento
yarn logs ma # or magento

> ... # magento logs
```


# Execute commands in Docker containers

## `yarn run exec <container name> [commands]` or `npm run exec -- <container name> [commands]`

{% hint style="info" %}
Since **magento-scripts\@1.1.0**
{% endhint %}

Executes command in a chosen container.

This command is basically a wrapper on top of [docker exec](https://docs.docker.com/engine/reference/commandline/exec/) command. It simplifies execution command in docker containers by providing names for docker containers so you don't have to search them by running a [status](/v1/getting-started/available-commands/status) command or `docker ps`.

```bash
# Using docker exec

# 1. get container name
docker ps
> ... # docker ps otput

# 2. execute command
docker exec -it <container name> <command>

# Using CMA exec

# 1. execute command
yarn run exec <service name> <command>
> ... # output from command is piped to your terminal
```

If you don't want to execute specific command, by default exec command will use **bash** as a command (and **redis-cli** for redis container) so you will be connected to the container with interactive shell environment.

### **Available container names**:

* `mysql`
* `nginx`
* `redis`
* `elasticsearch`

## Usage example

```bash
yarn run exec mysql

>root@c8f223c3ea92:/# # inside a container with mysql database

# ctrl + d or type 'exit' and press enter

# this is not alias, but rather service name matching
yarn run exec m

>root@c8f223c3ea92:/# # inside a container with mysql database

# custom command to check for nginx service status in container
yarn run exec nginx service nginx status

# expected output
>[ ok ] nginx is running.
```


# Link a theme

## `yarn run link <path>` or `npm run link <path>`

Sets ScandiPWA as a Magento Theme from your specified folder.

{% hint style="warning" %}

### Heads up!

Please follow [this guide](/v1/usage-guide/themes) for linking ScandiPWA theme to your Magento App.
{% endhint %}

### Command options

#### `-v, --verbose`

{% hint style="info" %}
Since **magento-scripts\@1.9.0**
{% endhint %}

This option will enable printing of logs from linking a theme.

```bash
yarn run link ./path/to/scandipwa --verbose # for Yarn
npm run link ./path/to/scandipwa -- --verbose # for NPM
```

## Usage example

```bash
yarn run link ./path/to/scandipwa # for Yarn
npm run link ./path/to/scandipwa # for NPM
```


# Import database dump

{% hint style="info" %}
Since **magento-scripts\@1.3.0**
{% endhint %}

## `yarn import-db [dump file path]` or `npm run import-db [dump file path]`

Imports database dump into MySQL container.

{% hint style="warning" %}
Note 1: To be able to import a database dump application must be running.\
Note 2: It is recommended to run the [start](/v1/getting-started/available-commands/start) command after running database import to ensure that configuration is up-to-date.
{% endhint %}

### **Command options**

#### **`-r, --remote-db`**

{% hint style="info" %}
Since **magento-scripts\@1.6.0**
{% endhint %}

Imports database from the remote server.\
Currently, the following protocols are supported:

* `ssh://`

{% tabs %}
{% tab title="yarn" %}

```bash
yarn import-db --remote-db ssh://my-username@my-server.com
```

{% endtab %}

{% tab title="npm" %}

```bash
npm run import-db -- --remote-db ssh://my-username@my-server.com
```

{% endtab %}
{% endtabs %}

Now it will connect via ssh to your server, create dump files (`dump-0.sql` and `dump-1.sql`), download them to your projects root folder, merge them into single `dump.sql` and import to your local instance with applied fixes.

To learn more about this option, read the following guide:

{% content-ref url="/pages/-Mchm5W0CLqGRl1Y1PU1" %}
[Importing remote database](/v1/usage-guide/importing-database/importing-remote-database)
{% endcontent-ref %}

#### `--with-customers-data`

{% hint style="info" %}
Since **mangento-scripts\@1.6.1**
{% endhint %}

Does not exclude customers and orders data when importing local and remote database.

{% tabs %}
{% tab title="yarn" %}

```bash
yarn import-db ./dump.sql --with-customers-data
yarn import-db --remote-db ssh://my-username@my-server.com --with-customers-data 
```

{% endtab %}

{% tab title="npm" %}

```
npm run import-db ./dump.sql -- --with-customers-data
npm run import-db -- --remote-db ssh://my-username@my-server.com --with-customers-data
```

{% endtab %}
{% endtabs %}

If you are importing a remote database and using this option, CMA will create only one `dump.sql` file with all data inside it.

## **Usage example**:

```bash
yarn import-db ./dump.sql
... # output

# or with npm
npm run import-db ./dump.sql
... # output
```


# ⚠️ Uninstall a project

{% hint style="warning" %}

### Heads up!

This command is not shipped in Create Magento App template by default. To enable it add following line to your projects `package.json` field `scripts` :

```
"cleanup": "magento-scripts cleanup"
```

{% endhint %}

## `yarn cleanup` or `npm run cleanup`

This command allows you to gracefully uninstall Create Magento App project.

{% hint style="danger" %}

### Watch out!

You should not use this command! This is command description with how to use but we **strongly** recommend avoid using it.

It will remove Docker volumes (**you will lose all data inside Redis, MySQL and ElasticSearch**), run `magento setup:uninstall` command and remove config files from the cache folder.
{% endhint %}

### Command options

#### **`-f, --force`**

Cleanup will remove Magento files and CMA cache.\
The folder will remove to initial [structure](/v1/getting-started/folder-structure).

{% hint style="info" %}

### Heads up!

PHP will not be removed by running this command. To remove it you should delete the folder `~/.phpbrew/php/php-7.3.11/`.
{% endhint %}

## Usage example

Add new line to `package.json`:

{% code title="package.json" %}

```bash
{
    "scripts": {
        "cleanup": "magento-scripts cleanup"
    }
}
```

{% endcode %}

Now use it as normal:

```bash
npm run cleanup # for NPM
yarn cleanup # for Yarn
```


# Folder structure

After creation, your project should look like this:

```
├── 📁 node_modules
├── 📄 package.json
└── 📄 README.md
```

Looks empty, isn't it? Well, that is because we haven't installed Magento 2 yet.

To install Magento 2 you need to bootstrap the project with [start](/v1/getting-started/available-commands/start) command.

After Magento 2 installation folder structure should look

```
├── 📁 app
├── 📁 bin
├── 📁 dev
├── 📁 generated
├── 📁 lib
├── 📁 node_modules
|  ├── 📁 .create-magento-app-cache
|  |  ├── 📁 composer
|  |  |  └── 📄 composer.phar
|  |  ├── 📁 nginx
|  |  |  └── 📁 conf.d
|  |  |     └── 📄 default.conf
|  |  ├── 📄 port-config.json
|  |  └── 📄 php-fpm.conf
|  ... 📁 other packages
├── 📁 phpserver
├── 📁 pub
├── 📁 setup
├── 📁 var
├── 📁 vendor
├── 📄 ... Magento 2 files
├── 📄 cma.js
├── 📄 package.json
└── 📄 README.md
```

Inside `node_modules` there is `.create-magento-app-cache` folder. It contains all configuration files and a local instance of [Composer](https://getcomposer.org/):

* Composer itself.
* PHP-FPM configuration file.
* Nginx configuration file.
* Port configuration file.

In your projects root directory also will be created `cma.js` file that contains CMA configuration: Magento configuration, Docker services configuration, host and SSL configuration.

{% hint style="info" %}
If you are upgrading an existing CMA project, old Magento configuration from `app-config.json` file inside cache folder will be converted to `magento` field in `cma.js` file.
{% endhint %}


# Updating to New Releases

Create Magento App is divided into two packages:

* `create-magento-app` is a global command-line utility that you use to create new projects.
* `@scandipwa/magento-scripts` is a development dependency in the generated projects (including this one).

When you run `npx create-magento-app my-app` it automatically installs the latest version of Create Magento App.

We create a project with the latest version of `@scandipwa/magento-scripts` so you’ll get all the new features and improvements in newly created apps automatically.

To update an existing project to a new version of `@scandipwa/magento-scripts`, [open the change-log](https://github.com/scandipwa/create-magento-app/releases), find the version you’re currently on (check `package.json` in this folder, if you’re not sure), and apply the migration instructions for the newer versions.

In most cases bumping the `@scandipwa/magento-scripts` version in `package.json` and running `npm install` (or `yarn install`) in this folder should be enough, but it’s good to consult the [change-log](https://github.com/scandipwa/create-magento-app/releases) for potential breaking changes.

To bump the version of `@scandipwa/magento-scripts` to latest available version, use:

{% tabs %}
{% tab title="yarn (recommended)" %}

```
yarn add @scandipwa/magento-scripts@latest
```

{% endtab %}

{% tab title="npm" %}

```
npm install @scandipwa/magento-scripts@latest
```

{% endtab %}
{% endtabs %}

We commit to keeping the breaking changes minimal so you can upgrade `@scandipwa/magento-scripts` painlessly.


# Testing Alpha Releases

Stable release of `@scandipwa/magento-scripts` package is releases in the end of the week, but sometimes we release an alpha version sooner.\
If you see an alpha release in [releases section on GitHub](https://github.com/scandipwa/create-magento-app/releases), you can install them by running command:

{% tabs %}
{% tab title="yarn (recommended)" %}

```
yarn add @scandipwa/magento-scripts@alpha
```

{% endtab %}

{% tab title="npm" %}

```
npm install @scandipwa/magento-scripts@alpha
```

{% endtab %}
{% endtabs %}

To return to stable release channel, use [Updating to New Releases](/v1/getting-started/updating-to-new-releases) section.

{% content-ref url="/pages/-MQwi0gNKyS-NeEUvL7L" %}
[Updating to New Releases](/v1/getting-started/updating-to-new-releases)
{% endcontent-ref %}


# Configuration File

## Project Configuration File

{% hint style="info" %}
Since **magento-scripts 1.2.0**
{% endhint %}

{% code title="default cma.js" %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        user: 'admin',
        password: 'scandipwa123',
        adminuri: 'admin',
        mode: 'developer',
        edition: 'community'
    },
    configuration: {}
};

```

{% endcode %}

The configuration file is created when you start the project `cma.js`, it's a tool that allows you to be in control of important parts of the project without headaches.

### Magento

Magento configuration is located in `magento` field and contains the following fields:

* `first_name`  - Admin first name
* `last_name` - Admin last name
* `email` - Admin email
* `user` - Admin user name
* `password` Admin password
* `adminuri` - Admin panel URL
* `mode` - Magento mode (description and list of available modes is located [here](https://devdocs.magento.com/guides/v2.4/config-guide/bootstrap/magento-modes.html))
* `edition` - Magento edition. Allowed values: `community`, `enterprise`.

### Services

In the field `configuration` we can configure PHP, Composer and Docker services.

#### PHP configuration

PHP configuration is located in the `php` field and contains the following fields:

* `version` - PHP version, by default it is using `7.4.27`.
* `configTemplate` - `php.ini` template file location. With this option, you can define your own `php.ini` file that will be used by PHP. (Original `php-template.ini` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/php.template.ini))
* `extensions` - Map of extensions that will be used for the project. By default, it contains the following extensions that are required by Magento: gd, intl, zlib, openssl, sockets, SimpleXML, xdebug. You can add an extension that will be required by some Composer package, CMA will automatically install it with the correct version.
* `disabledExtensions` - Array of strings as extension names.\
  If for some reason you need to manually disable an extension in your setup, you can put its name in this option. Be careful as this could potentially break your setup.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        php: {
            // lets change the default php version from 7.4.13 to 7.4.20
            version: '7.4.20',
            // and add some extensions
            extensions: {
                fileinfo: {},
                xdebug: {
                    version: '3.0.4'
                }
            }
        }
    }
};

```

#### Docker services configuration

#### Nginx

Nginx configuration is located in the `nginx` field and contains the following fields:

* `version` - Container version **string**. For Nginx default version is `1.18.0`&#x20;
* `configTemplate` - Nginx template file location **string**. With this option, you can define your own `nginx.template.conf` - File that will be copied inside the `$CMA_CACHE/nginx/conf.d/` folder which is mounted in Nginx container to `/etc/nginx/conf.d/` folder. **string** (Original `nginx.template.conf` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/nginx.template.conf))

{% hint style="info" %}
Nginx image is pulled from [Docker Hub](https://hub.docker.com/_/nginx).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        nginx: {
            // lets change nginx image version to 1.19
            version: '1.19.0',
            // and use custom nginx template
            configTemplate: './nginx.conf.template'
        }
    }
};
```

#### MySQL

MySQL configuration is located in the `mysql` field and contains the following fields:

* `version` - Container version **string**. For MySQL default version is `8.0`

{% hint style="info" %}
MySQL image is pulled from [Docker Hub](https://hub.docker.com/_/mysql).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        mysql: {
            // lets change mysql image version to 8.0.25
            version: '8.0.25'
        }
    }
};
```

#### ElasticSearch

ElasticSearch configuration is located in the `elasticsearch` field and contains the following fields:

* `version` - Container version **string**. For ElasticSearch default version is `7.6.2`

{% hint style="info" %}
ElasticSearch image is pulled from [ElasticSearch Hub](https://www.docker.elastic.co/r/elasticsearch).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        elasticsearch: {
            // lets change elasticsearch image version to 7.13.1
            version: '7.13.1'
        }
    }
};
```

#### Redis

Redis configuration is located in the `redis` field and contains the following fields:

* `version` - Container version **string**. For Redis default version is `6.0.10-alpine`

{% hint style="info" %}
Redis image is pulled from [Docker Hub](https://hub.docker.com/_/redis).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        redis: {
            // lets change redis image version to 6.2.4
            version: '6.2.4'
        }
    }
};
```

#### Composer

Composer configuration is located in the `composer` field and contains the following fields:

* `version` - Composer version **string**.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        composer: {
            // lets change composer version to 2.3.7
            version: '2.3.7'
        }
    }
};
```

#### Varnish

{% hint style="info" %}
Since **magento-scripts 1.15.0**
{% endhint %}

Varnish configuration is located in the `varnish` field and contains the following fields:

* `enabled` - A **boolean** option to manually enable or disable Varnish in the setup. (Default: `false`)
* `configTemplate` - `varnish.vcl` template file location. With this option, you can define your own `varnish.vcl` file that will be used by Varnish. (Original `varnish.template.vcl` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/varnish.template.vcl))
* `version` - Varnish version **string**.

{% hint style="info" %}
Varnish image is pulled from [Docker Hub](https://hub.docker.com/_/varnish).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        varnish: {
            // lets change composer version to 6.0
            version: '6.0'
        }
    }
};
```

#### SSL Terminator (Nginx)

{% hint style="info" %}
Since **magento-scripts 1.15.0**
{% endhint %}

SSL Terminator is an Nginx instance, it's configuration is located in `sslTerminator` field and contains the following fields:

* `version` - Container version **string**. For Nginx default version is `1.18.0`&#x20;
* `configTemplate` - SSL Terminator template file location **string**. With this option, you can define your own `ssl-terminator.template.conf` - File that will be copied inside the `$CMA_CACHE/ssl-terminator/conf.d/` folder which is mounted in Nginx container to `/etc/nginx/conf.d/` folder. **string** (Original `ssl-terminator.template.conf` file can be found [here](https://github.com/scandipwa/create-magento-app/blob/master/build-packages/magento-scripts/lib/config/templates/ssl-terminator.template.conf))

{% hint style="info" %}
Nginx image is pulled from [Docker Hub](https://hub.docker.com/_/nginx).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    configuration: {
        sslTerminator: {
            // lets change nginx image version to 1.19
            version: '1.19.0',
            // and use custom ssl-terminator nginx template
            configTemplate: './ssl-terminator.conf.template'
        }
    }
};
```

### Domain

The host configuration is a string located in `host` field and by default, it is set to `localhost` .\
You can put your own host domain that will be set to nginx config as `server_name` and set Magento secure and unsecure base\_url values.

{% hint style="info" %}
Learn about adding a localhost domain to your application [here](/v1/usage-guide/setup-custom-domain).
{% endhint %}

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    host: 'scandipwa.local'
};

```

### SSL

SSL configuration is located in the `ssl` field and contains the following values:

* `enabled` - Enables or disables SSL in the application. **boolean** (`false` by default)
* `ssl_certificate` - SSL certificate file location **string**. You can put there your SSL certificate file location relative to the project root folder or use absolute value.
* `ssl_certificate_key` - SSL certificate key file location **string**. You can put there your SSL certificate file location relatively to the project root folder or use absolute value.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    ssl: {
        enabled: true,
        ssl_certificate: './path/to/my/certificate',
        ssl_certificate_key: './path/to/my/certificate-key.pem'
    }
};

```

{% hint style="info" %}
Learn about enabling SSL in your application [here](/v1/usage-guide/enabling-ssl).
{% endhint %}

### Prefix

Prefix configuration is a boolean located in the `prefix` field and by default, it is set to `true` .

But what prefixes are used for?\
Prefix is a unique identifier that will be appended to docker container and volume names to prevent possible interference between folders with similar names. (Interference between folders look like [that](https://github.com/scandipwa/create-magento-app/issues/13))\
Setting `prefix` to `false` is generally **not recommended** but might be necessary for legacy projects.

```javascript
/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: { ... },
    prefix: false
};

```

## System Configuration FIle

{% hint style="info" %}
Since **magento-scripts 1.5.1**
{% endhint %}

This configuration file is located in your home directory and should have a name `.cmarc`.\
As it is not created automatically, you will need to do it manually.\
The default configuration file looks like this:

{% code title="$HOME/.cmarc" %}

```javascript
  {
    "useNonOverlappingPorts": false,
    "analytics": true
  }
```

{% endcode %}

This configuration file contains the following configuration options:

### Use Non-Overlapping Ports

{% hint style="info" %}
Recommended to enable this option if you are working with many CMA projects
{% endhint %}

Use non-overlapping ports is a feature that will tell CMA when choosing available ports on the system to also ignore ports that are already used by other CMA instances, even if they are stopped.\
That way it will ensure that your projects will not get new ports every time you switch between them.

To enable this feature, set `useNonOverlappingPorts` field in the system configuration file to `true`.

### Analytics

Analytics help us to collect data about errors or possible slow-downs and help us to identify areas that should be fixed or improved!

Of course, you have an option to opt-out of analytic data collection. To do that set `analytics` field in the system configuration file to  `false` and CMA will not collect analytic data from your system.


# Supported Magento versions

{% hint style="info" %}
Magento versions are available since **magento-scripts\@1.5.0**
{% endhint %}

When you first starting the application, you will see the following prompt:

![Magento version selector](/files/-MdbRDTuIwofbLxON4PC)

Here you can choose the Magento version to install.

## Supported versions

Currently, we support all Magento versions starting from Magento 2.3.0.

If you want to edit project configuration using a [configuration file](/v1/getting-started/config-file#project-configuration-file) use the configuration reference which is available [here](https://github.com/scandipwa/create-magento-app/tree/master/build-packages/magento-scripts/lib/config/versions).


# How does it work?

The installation of Create Magento App is done through many small steps or tasks and we like to group them by their purpose: Preparation, Installation, Configuration, Execution. Each of these groups works with a specific set of technologies to achieve the desired result.

## Overview

We use the `listr2` library to help us with task definition and display in the terminal. This library allows us to declare independent tasks and execute them in any order we want, passing down context to later tasks. Context is a way for tasks to share information and is a key aspect of Create Magento App installation process.

During the Preparation tasks, for example, context is populated with various settings, such as available ports, Magento version, `cma.js` configuration, etc, and the data is then used in later tasks. This approach simplifies the data flow and makes it easy for us to focus on one thing at a time, instead of doing multiple operations within each task.

## Preparation

This is the first group of tasks that are executed once you run Create Magento App. Tasks of this group perform various checks to validate that the necessary requirements are met and set up your machine to be ready for installation.

Create Magento App uses `Docker`, `PHPBrew`, and `Composer` under the hood and we have a task that is responsible for validating that all of them are installed on the machine and are ready to run, including their dependencies. Below will be the list of tasks that are responsible for preparation.

### Checking cache folder

Create Magento App works with a lot of data and we don't want to run all of the operations each time the project is started, this is why some of the settings are cached for further use. This task is responsible for validating the presence of the cache folder.

### Checking requirements

Create Magento App uses `Docker`, `PHPBrew`, and `Composer` under the hood and this task is responsible for validating that all of them are installed on the machine and are ready to run, including their dependencies. In the scope of this task, your OS is also validated as Create Magento App only works on Mac and Linux.

### Loading Magento version

In case the machine has a local Magento installation or multiple Magento installations, the user will be prompted to select the Magento versions that they want to use. In case the Magento installation is missing, the default version (2.4.1) will be chosen instead.

### Get cached ports

Retrieves cached ports from the cache folder. This is needed to gracefully stop currently running `Docker` containers.

### Stopping Docker services

Stops running `Docker` containers of Create Magento App. If not containers related to the project are running, the task will be skipped.

### Stopping php-fpm

Kills the `php-fpm` process. Only the local `php-fpm` process for Create Magento App will be stopped.

### Get available ports

Retrieves the list of available ports. Will find free ports in case of the first installation, otherwise will validate the ports that have been retrieved from the cache in one of the previous steps. In case one of the cached ports is no longer available, a new one will be found instead.

### Save configuration

Saves the list of available ports to the configuration for further use in the application setup.

## Installation

The second group of tasks is where PHP and Magento get installed. PHP extensions are also installed in the scope of this task group.

### Install PHP

Installs the PHP binaries according to the version specified in the `cma.js`, otherwise installs PHP version 7.4.13 by default. During each subsequent run, this task will check for PHP extensions configuration and install any missing extensions, if they are present.

### Install Composer, prepare FS, and download images

Installs Composer to allow for Magento to install its dependencies. Prepares File System by creating folders and files necessary for Nginx, PHP, and php-fpm to run. This includes creating SSL certificates and updating the internal configuration file with paths to certain binaries and executables.

These tasks are grouped into one to run them in parallel, heavily decreasing the time needed for initial installation.

### Configuring PHP extensions

This task is responsible for configuring the PHP extensions and adding them to the active PHPBrew instance.

### Install Prestissimo

Installs Prestissimo, a plugin for Composer to allow it for parallel package installation. This plugin heavily decreases the time needed for initial installation, due to installing Magento's dependencies faster.

### Install Magento

This is finally the task where Magento installation takes place! This task creates the project folder, installs Magento, and connects with the ScandiPWA theme created using Create Scandipwa App if present.

## Configuration

Tasks in this group are responsible for creating and configuring the infrastructure needed for the application to work. This includes the Magento configuration itself as well as the setup of the `Docker` infrastructure, and connection establishment to the MySQL container.

### Starting Docker services

Starts 4 `Docker` services that are required for Create Magento App to operate. These services are `ElasticSearch`, `MySQL`, `Nginx`, and `Redis`. In case of initial installation, an appropriate `Docker` network will be created as well as Docker volumes to store the data.

### Connect to MySQL server

Running MySQL instance is one of the requirements for Magento configuration, and the Create Magento App makes sure that the connection is established. A check is made to see if the MySQL container is running and in case it's not, the retry mechanism is in place. A total of 10 tries will be made with a 5-second interval between each and in most cases, it's enough to establish a connection.

### Setup Magento

In this task, the Magento instance is configured for local development. Many sub-tasks will prepare the Magento instance by migrating the database, configuring URLs, creating an admin user, disabling the maintenance mode, and disabling the 2FA.

## Execution

Tasks from this list will use the data from all previous tasks to start the application up.&#x20;

### Starting php-fpm

Starts the PHP process manager and the Magento instance.

### Open browser

Opens up `localhost` in the browser. The Magento app will be accessible from there.


# Limitations

At the moment CMA has a few limitations that you should be aware of:

* You can create a maximum of 30 CMA instances running at the same time before running into network limits.\
  To remove custom networks not used by at least one container you can use the command `docker network prune` **OR** update to **magento-scripts** version **1.7.0 or newer** which will remove project network during stop command, freeing the network.
* The same PHP version is used across all CMA instances that have the same PHP version.\
  So, if A instance is using PHP 7.4.13 and B instance is using the same 7.4.13 then you should be careful with PHP extension versions, they should match.\
  If they don't match, during runtime CMA will configure them with 2 versions at the same time causing interference in your code.\
  To avoid this, we can recommend not to run those instances at the same time.
* Not all ports can be used for Magento to run on. Some browsers can throw an error **ERR\_UNSAFE\_PORT** on some ports below 1024.\
  If you encountered such issue, use [-p](/v1/getting-started/available-commands/start#p-port) option in the start command and use ports above 1024.


# Using console commands

## Working with CLI

We have our PHP compiled, Composer installed, Magento 2 installed.\
But how access them? Everything is scattered across the file system.

That is where CLI comes in handy. It provides aliases for PHP, Composer and Magento in your project.\
We can open it by running a command:

```bash
npm run cli # for NPM
yarn cli # for Yarn
```

Now we have access to PHP, Composer and Magento, we can install PHP dependencies, upgrade Magento and so on.

```bash
php -v
> PHP 7.4.13 (cli) ...

composer --version
> Composer version 1.10.19

# Can be used with alias
c --version
> Composer version 1.10.19

magento setup:upgrade
> Magento upgrade output ...

# Can be used with alias
m se:up
> Magento upgrade output ...
```

## Common Usage

Flushing Magento cache

```bash
magento cache:flush

# or with aliases and shortcuts
m c:f
```

Magento upgrade

```bash
magento setup:upgrade

# or with aliases and shortcuts
m se:up
```

Upgrading Composer dependencies

```bash
composer upgrade

# or with alias
c upgrade
```


# Accessing Docker containers

Create Magento App consists of Magento, Docker containers with Redis, Elasticsearch, Nginx, and MySQL, and CLI to connect all of these things together. We already have a [CLI](/v1/getting-started/available-commands/cli) command that gives us access to [Magento CLI](https://devdocs.magento.com/guides/v2.4/reference/cli/magento.html) and [Composer CLI](https://getcomposer.org/doc/03-cli.md), but how can we access the containers?\
That is where the connect command comes in handy!

```bash
yarn run exec <container name> # for Yarn
npm run exec <container name> # for NPM
```

Now we are inside of a chosen container.\
Here is a list of available container names:

* `mysql`
* `nginx`
* `redis`
* `elasticsearch`

## Common Usage

```bash
yarn run exec mysql

>root@c8f223c3ea92:/# # inside a mysql container

# ctrl + d or type 'exit' and press enter

# this is not alias, but rather service name matching
yarn run exec m

>root@c8f223c3ea92:/# # inside a mysql container

```


# Linking a Scandi Theme

## Summary

Before you start:

* [ ] Install Create Scandi App
* [ ] Make sure you have a Scandi theme to use
* [ ] Make sure you have a Create Magento App set up

Linking your theme:

* [ ] Link your app using `run link`
* [ ] Compile your app in Magento mode
* [ ] Enable the theme in the admin panel

## 1. Installing Create ScandiPWA App

Before you link a theme, make sure you have installed Create ScandiPWA App. Use [this guide](https://docs.create-scandipwa-app.com/getting-started/getting-started) for installing it.

## 2. Linking a Theme

To link a ScandiPWA theme to your Create Magento App project you can use command [link](/v1/getting-started/available-commands/link):

```bash
npm run link ./path/to/your/scandipwa-app # for NPM

# or with yarn
yarn run link ./path/to/your/scandipwa-app
```

Create Magento App will link your ScandiPWA theme from your selected path as a symbolic link and will disable [Full Page cache](https://docs.magento.com/user-guide/system/cache-full-page.html).

This is necessary for proper hard-reload when developing Magento Theme.

{% hint style="warning" %}

### Heads up!

Disabling Full Page cache is necessary for theme development with hard reload. To enable Full Page cache run this command in [CLI](/v1/getting-started/available-commands/cli):

```bash
magento cache:enable full_page
```

{% endhint %}

## 3. Run Create ScandiPWA App Compilation

Run the command below from your ScandiPWA App directory (`./path/to/my/scandipwa-app` )

```bash
BUILD_MODE=magento npm run start # Mac, Linux
set BUILD_MODE=magento && npm run start & set BUILD_MODE= # Windows
```

This command will now watch the files and put their compiled versions into the `magento/Magento_Theme` folder.

{% hint style="info" %}
Instead of starting your Create ScandiPWA App project, you can also use `npm run build`.  Learn more [here](https://docs.create-scandipwa-app.com/deploying-your-app/magento-theme#npm-run-build-or-yarn-build).&#x20;
{% endhint %}

## 4. Enable Theme

After you linked theme to your Create Magento App instance you need to activate it.

Go to your Magento Admin panel (by default it can be accessed on `/admin` url), **Content > Configuration**, choose a website that you want to apply theme on, click **Edit** and select your theme, click **Save** and that is it.

Open your store URL and theme should be online.


# Enabling XDebug

## Enabling XDebug in PHPStorm

### 1. Run Create Magento App in debug mode.

Use [start](/v1/getting-started/available-commands/start) command with [debug](/v1/getting-started/available-commands/start#d-debug) option to enable [XDebug](https://xdebug.org/).

{% hint style="danger" %}
Do not run the following command with the [-s option](/v1/getting-started/available-commands/start#s-skip-setup)! CMA need to make adjustments to setup in debug mode!
{% endhint %}

```bash
yarn start --debug # for Yarn
npm run start -- --debug # for NPM
```

### 2. Setup PHPStorm

#### Set PHP CLI Interpreter

Go to **Settings > Languages & Frameworks > PHP** \
Here you need select correct CLI Interpreter for CMA project. CMA is currently using latest PHP 7.4 version so the path to PHP executable  should look like this: `$HOME/.phpbrew/php/php-7.4.13/bin/php` It should look like this:

![CLI Interpreters PHP configuration](/files/-MP5f6cd5Z_zGAro-Aer)

#### Set XDebug port and other debugging configuration&#x20;

Go to **Settings > PHP > Debug** (in old PHPStorm: **Settings > Languages & Frameworks > PHP > Debug**) \
Make sure you have set debug port for XDebug to 9003,9111 (9003 is the default for XDebug 3 and port 9111 is used as a default for XDebug 2) and **Ignore external connections through the unregistered server configuration** is checked.

![](/files/-MdrNFD-buAvTf1jH5LE)

#### Set Debug server configuration

Go to **Settings > Languages & Frameworks > PHP > Server**\
There you need to set up a debugging server for Create Magento App.\
Click +, use `http://localhost`  as **Host** value, put your Create Magento App running port as **Port** value, select **XDebug** as **Debugger** value.

{% hint style="info" %}
To find what your **Port** value is, use [status](/v1/getting-started/available-commands/status) command.
{% endhint %}

![](/files/-MgkRrqXEzZJSGAmWv0a)

Click **Apply** and close the window.

#### Set project debug configuration

Go to **Run > Edit Configurations**\
Click + and create new **PHP Remote Debug** configuration.\
Check **Filter debug connection by IDE key**, select your create-magento-app debug server as a **Server** value, use **PHPSTORM** as an **IDE Key** value.

![](/files/-MgkSRETZn2nr2YB9NfB)

Click **Apply** and close the window.

### 3. Prepare browser

You need to install [XDebug Helper](https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjbigjakmdgkmoaaaoc) extension for Chrome to activate Debugging session in PHPStorm. \
After installation open extension **options** and select **IDE Key** value as **PHPStorm**.

Now when you open your CMA webpage you need to enable debug session by pressing **Debug** in extensions menu.

{% hint style="info" %}
This extension sets a cookie in your browser's requests: `XDEBUG_SESSION=PHPSTORM`. This cookie enables debugging in your browser.

Sometimes, you may want to enable debugging outside of the browser (for example, to debug individual GraphQL requests). You can also set `XDEBUG_SESSION=PHPSTORM` manually in the `Cookie` header. Most HTTP and GraphQL clients support this option.
{% endhint %}

### 4. Start debugging

Choose **create-magento-app** debug configuration in the top right corner of PHPStorm's window.

![](/files/-MP9paYlLVvTnpiCg1TC)

And after that pretty much everything is ready for PHP debugging.\
Click on **Start debugging** or press **Shift+F9**, put test breakpoint in **$project\_root/pub/index.php** file, reload the page and that is all!

Happy debugging!

## Enabling XDebug in VSCode

### 1. Run Create Magento App in debug mode.

Use [start](/v1/getting-started/available-commands/start) command with [debug](/v1/getting-started/available-commands/start#d-debug) option to enable [XDebug](https://xdebug.org/).

```bash
yarn start --debug # for Yarn
npm run start -- --debug # for NPM
```

### 2. Setup VSCode

Install [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) extension.

Then, create a file `launch.json` in `.vscode` folder at the root of your project if it does not exist.\
Inside that file add the following configuration:

```bash
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "runtimeExecutable": "$HOME/.phpbrew/php/php-<php-version>/bin/php"
        }
    ]
}
```

Make sure to replace `<php-version>` variable with the PHP version that is used in your project.\
To get PHP version open [CLI](/v1/getting-started/available-commands/cli) and execute `php --version` command.

{% hint style="info" %}
If you are using XDebug, set port 9111 in the configuration instead of 9003.

Port 9003 is the default for XDebug 3 and port 9111 is for XDebug 2.
{% endhint %}

### 3. Prepare browser

You need to install the [XDebug Helper](https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjbigjakmdgkmoaaaoc) extension for Chrome to activate Debugging session in PHPStorm.&#x20;

Now when you open your CMA webpage you need to enable debug session by pressing **Debug** in the extensions menu.

{% hint style="warning" %}
VSCode debugger does not care what IDE key you select in xdebug helper settings.\
It automatically attaches when it sees a cookie with a name `XDEBUG_SESSION`.
{% endhint %}

{% hint style="info" %}
This extension sets a cookie in your browser's requests: `XDEBUG_SESSION=PHPSTORM`. This cookie enables debugging in your browser.

Sometimes, you may want to enable debugging outside of the browser (for example, to debug individual GraphQL requests). You can also set `XDEBUG_SESSION=PHPSTORM` manually in the `Cookie` header. Most HTTP and GraphQL clients support this option.
{% endhint %}

### 4. Start debugging

Open debugging tab in VSCode (**Ctrl + Shift + D)** and select **Listen for Xdebug** configuration.

![](/files/-MlKyJn6mBiUVuAdbliM)

Click on **Start debugging** (or press **F5)**, put test breakpoint in **$project\_root/pub/index.php** file, reload the page and that is all!

Happy debugging!


# Enabling SSL

## 1. Get a certificate

You can use your existing certificate or create a new one using [mkcert](https://github.com/FiloSottile/mkcert) utility.\
Follow the installation [guide](https://github.com/FiloSottile/mkcert#installation) for your platform.&#x20;

After installation install mkcert certificate into your system by running the command below:

```bash
mkcert -install
```

Now we need to create a certificate.\
To create a certificate run command below:

```bash
> mkcert localhost 127.0.0.1

Created a new certificate valid for the following names 📜
 - "localhost"
 - "127.0.0.1"

The certificate is at "./localhost+1.pem" and the key at "./localhost+1-key.pem" ✅

It will expire on 13 May 2023 🗓
```

Now we have all files that we need for CMA config.

## 2. Setup CMA

Add to your `cma.js` file field `ssl` with the following object:

```javascript
module.export = {
    ... other configuration
    ssl: {
        enabled: true,
        ssl_certificate: './localhost+1.pem',
        ssl_certificate_key: './localhost+1-key.pem'
    }
}
```

That is it! Just now we have enabled SSL in our application!\
Now to apply changes we need to run [start](/v1/getting-started/available-commands/start) command **without** [**-s option**](/v1/getting-started/available-commands/start#s-skip-setup).

{% hint style="warning" %}
You can run **only one** application with SSL enabled at the time because it will use port 443 which is the default port for SSL.
{% endhint %}


# Configuring PHP

PHP configuration is stored within the `cma.js` file:

```javascript
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        user: 'admin',
        password: 'scandipwa123',
        adminuri: 'admin',
        mode: 'developer',
    },
    configuration: {
        php: {
            // PHP configuration goes here
        }
    }
};

```

## Changing the PHP version

The default version of PHP supplied with Create Magento App is `7.4.13`. In order to change it, `cma.js` will have to be adjusted accordingly:

```javascript
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        user: 'admin',
        password: 'scandipwa123',
        adminuri: 'admin',
        mode: 'developer',
    },
    configuration: {
        php: {
            version: '7.4.14'
        }
    }
};

```

After changing the configuration, restart the app to install the new PHP version:

```javascript
yarn start
```

And validate the new PHP installation through the CLI:

```javascript
yarn cli
bash-3.2$ php -v
PHP 7.4.14 (cli) (built: Mar 16 2021 16:21:11) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Xdebug v3.0.3, Copyright (c) 2002-2021, by Derick Rethans
```

## Installing PHP extensions

By default, only the extensions that are required by Magento are installed. If you need to install any additional extensions, cma.js will have to be changed accordingly:

```javascript
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        user: 'admin',
        password: 'scandipwa123',
        adminuri: 'admin',
        mode: 'developer',
    },
    configuration: {
        php: {
            extensions: {
                memcached: {},
                sphinx: {
                    version: '1.3.3'
                }
            }
        }
    }
};

```

You can specify the version of the extension explicitly (like with `sphinx`) or install the latest available version automatically by leaving the object empty (like with `memcached`). Restart the app for changes to take effect:

```javascript
yarn start
```

And validate newly installed extensions through the CLI:

```javascript
yarn cli
bash-3.2$ php -m | grep "memcached\|sphinx"
memcached
sphinx
```

## FAQ

### My build failed after changing the PHP version, why?

{% hint style="warning" %}
Versions of PHP 7.4 older than 7.4.13 will not compile on Mac as of **magento-scripts 1.3.0**.
{% endhint %}

Before changing the PHP version, make sure that it's supported by the Magento version you're using. By default, Create Magento App runs on Magento 2.4 that requires PHP of version 7.4.x. Please check the [Magento 2.4 system requirements](https://devdocs.magento.com/guides/v2.4/install-gde/system-requirements.html#php) to see the list of supported PHP versions.

If the PHP version is correct and you have this issue, you should examine the build logs. Each failed build of Create Magento App supplies you with a build log and the location of that log is displayed at the end of the build:&#x20;

```javascript
Please checkout the build log file for more details:
	 tail /Users/user/.phpbrew/build/php-7.4.0/build.log
error Command failed with exit code 1.
```

### My build failed after installing PHP extensions, why?

Some PHP extensions require certain binaries to be installed on your machine and the build will fail otherwise. The path to log file will be displayed in the console when the build fails:

```javascript
Log stored at: /Users/user/.phpbrew/build/php-7.4.13/ext/memcached/build.log
```

You can print this log with `tail` command to see the output:

```javascript
checking for libmemcached location... configure: error: memcached support requires libmemcached. Use --with-libmemcached-dir=<DIR> to specify the prefix where libmemcached headers and library are located
```

In this case, the `libmemcached` library is missing on the machine and has to be installed for build to succeed.

### Known issue: magento-scripts on macOS cannot install gd extension on PHP 7.2

Link: <https://github.com/scandipwa/create-magento-app/issues/80>

You can fix this by adding:

```
configuration: {
    php: {
      extensions: {
        gd: {
          macosOptions: '--with-zlib-dir=$(brew --prefix zlib)'
        }
      }
    }
  }
```


# Use custom domain

## 1. Add domain to the /etc/hosts file

In order for this config to work you need to add your host domain to the `/etc/hosts` file, for example:

```bash
# /etc/hosts file
127.0.0.1 localhost
127.0.0.1 scandipwa.local # some other domain
```

## 2. Setup CMA

Add to your `cma.js` file field `host` with your domain:

```javascript
module.export = {
    magento: { ... },
    host: 'scandipwa.local'
}
```

That is it! Just now we have setup a domain in our application!\
Now to apply changes we need to run the [start](/v1/getting-started/available-commands/start) command **without** [**-s option**](/v1/getting-started/available-commands/start#s-skip-setup).


# Access on the local network

Sometimes you need to run your CMA application in a mode where other users can access it to look at the development progress.

## 1. Get an IP address

Every device that is connected to the local is assigned an IP address in that network. Usually, this is done by the router.\
To get your IP address on the local network, use the following guide:

{% tabs %}
{% tab title="Ubuntu" %}

```bash
ifconfig -a
```

{% endtab %}

{% tab title="Manjaro Linux" %}

```bash
ip -4 addr | grep 192.168
```

{% endtab %}

{% tab title="macOS" %}

```bash
ipconfig getifaddr en0
> 192.168.0.xxx
```

{% endtab %}
{% endtabs %}

## 2. Make port public

Each OS has a different approach to opening ports in its firewall.

### Linux

We will be using [UFW](https://wiki.ubuntu.com/UncomplicatedFirewall) to control iptables rules.

{% tabs %}
{% tab title="Ubuntu" %}

```bash
# install it
sudo apt-get install ufw

# enable service
sudo ufw enable

# make sure that it is running
sudo ufw status verbose

# open port
sudo ufw allow in 80/tcp

# now we have port 80 available outside of our system
```

{% endtab %}

{% tab title="Manjaro Linux" %}

```bash
# install it
pamac install ufw

# enable service
sudo systemctl enable ufw.service
sudo ufw enable

# open port
sudo ufw allow in 80/tcp

# now we have port 80 available outside of our system
```

{% endtab %}
{% endtabs %}

### MacOS

Go to **System Preferences** > **Security & Privacy** > **Firewall**.\
Enable firewall. Then go to **Firewall Options** and make sure the only two options selected are **Automatically allow built-in software to receive incoming connections** and **Automatically allow downloaded signed software to receive incoming connections**.

## 3. Setup CMA

Add to your `cma.js` file field `host` with your IP address:

```javascript
module.export = {
    ... other configuration
    host: '192.168.0.100'
}
```

That is it! Now your devices on the local network can communicate with your CMA instance!<br>

You also need to apply changes by running the [start](/v1/getting-started/available-commands/start) command **without** [**-s option**](/v1/getting-started/available-commands/start#s-skip-setup).


# Importing database

To import the database use the [import-db](/v1/getting-started/available-commands/import-db) command.

{% hint style="warning" %}

### **Heads up!**

If you are running a version older than **magento-scripts\@1.6.0**, you will need to start project manually using [start command](/v1/getting-started/available-commands/start)!
{% endhint %}

{% tabs %}
{% tab title="Yarn" %}

```bash
yarn import-db <dump file path>
```

{% endtab %}

{% tab title="NPM" %}

```bash
npm run import-db <dump file path>
```

{% endtab %}
{% endtabs %}

When the command is called, multiple steps are executed to ensure the success of the import. These steps are as follows:

* A connection established with MySQL
* Theme configurations will be dumped and restored after the dump is imported
* The dump will be imported into MySQL from the specified file
* It will be ensured that dump will work with CMA set up by setting necessary configuration values
* And Magento setup will be running to finish the configuration.

To import database from remote ssh server, use the following guide:

{% content-ref url="/pages/-Mchm5W0CLqGRl1Y1PU1" %}
[Importing remote database](/v1/usage-guide/importing-database/importing-remote-database)
{% endcontent-ref %}


# Importing remote database

{% hint style="warning" %}
Currently, **only SSH protocol is supported**!
{% endhint %}

To import database from remote server use[ import-db](/v1/getting-started/available-commands/import-db) command with `--remote-db` option:

{% tabs %}
{% tab title="yarn" %}

```bash
yarn import-db --remote-db ssh://my-username@my-server.com
```

{% endtab %}

{% tab title="npm" %}

```
npm run import-db -- --remote-db ssh://my-username@my-server.com
```

{% endtab %}
{% endtabs %}

CMA will connect via ssh to your server, create 2 dump files (`dump-0.sql` and `dump-1.sql`), download them to your projects root folder, merge them into single `dump.sql` and import to your local instance with applied fixes.

### Is there a reason to use import from remote db when possible?

There is a good reason for it!\
The dump file created by this command is much smaller than dump files that are created the usual way.\
This is because we omit **orders** and **customers** data when we're creating dump file so it comes in a much smaller size.

For example, a dump from a database could weigh 2.7GB, now using this import feature size will be reduced to 4MB.

### Why 3 dump files?

The reason to make 3 dump files is simple: [mysqldump](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html) utility cannot make dump files with only a few tables without data, --no-data option is a boolean so we have only 2 options, either include data or not.

`dump-0.sql` file contains **all** the database tables **with data**, except for the order and customer-related tables.\
`dump-1.sql` file contains **only** orders and customer-related table structures, **without data**.\
`dump.sql` file is made from concatenating `dump-0.sql` with `dump-1.sql` , which are downloaded from your remote server, so it's **a full dump file**.


# Using Enterprise Edition

{% hint style="info" %}
Since **magento-scripts\@1.4.0**
{% endhint %}

## 1. Create new CMA app

```bash
npx create-magento-app@latest magento-enterprise
```

## 2. Set magento.edition to "enterprise" in the config file

{% code title="cma.js" %}

```javascript
module.exports = {
    magento: {
        first_name: 'Scandiweb',
        last_name: 'Developer',
        email: 'developer@scandipwa.com',
        user: 'admin',
        password: 'scandipwa123',
        adminuri: 'admin',
        mode: 'developer',
        edition: 'enterprise' // <- edit this
    },
    configuration: {}
};

```

{% endcode %}

## 3. Run the application

Start the application with the [start](/v1/getting-started/available-commands/start) command.

{% hint style="warning" %}
You need access keys with access to Magento Enterprise on them to be able to install the **enterprise edition**.
{% endhint %}

```bash
npm run start
```


# Converting legacy Docker setup to CMA

We have an older [magento-docker](https://github.com/scandipwa/magento-docker) setup for ScandiPWA 1, 2, 3 but since it is not very versatile when it comes to development, you can "upgrade" it to use CMA!

## 1. Install CMA

Go to `src` folder and install CMA:

```bash
cd ./src

# if npm is not initialized, then run
npm init -y

# then install @scandipwa/magento-scripts package
npm i @scandipwa/magento-scripts@latest

# and make sure your package.json has the following scripts:
{
    ...
    "scripts": {
        "start": "magento-scripts start",
        "stop": "magento-scripts stop",
        "cli": "magento-scripts cli",
        "logs": "magento-scripts logs",
        "link": "magento-scripts link",
        "status": "magento-scripts status",
        "exec": "magento-scripts exec",
        "import-db": "magento-scripts import-db"
    }
    ...
}
```

## 2. Adjust composer dev packages

You need to adjust `require-dev` dependencies, ideally just replace them with the following ones which are shipped in default Magento 2.3 template:

```javascript
{
    ...
    "require-dev": {
        "allure-framework/allure-phpunit": "~1.2.0",
        "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
        "friendsofphp/php-cs-fixer": "~2.14.0",
        "lusitanian/oauth": "~0.8.10",
        "magento/magento-coding-standard": "*",
        "magento/magento2-functional-testing-framework": "~2.6.4",
        "pdepend/pdepend": "2.5.2",
        "phpcompatibility/php-compatibility": "^9.3",
        "phpmd/phpmd": "@stable",
        "phpstan/phpstan": "^0.12.2",
        "phpunit/phpunit": "~6.5.0",
        "sebastian/phpcpd": "~3.0.0",
        "squizlabs/php_codesniffer": "~3.4.0"
    }
    ...
}
```

## 3. Adjust theme webpack configuration

Magento does not serve theme files in older ScandiPWA versions so we need to reconfigure webpack devserver.

Go to file `app/design/frontend/Scandiweb/pwa/src/config/webpack.development.config.js` and your configuration for `devServer` should look like this:

{% code title="webpack.development.config.js" %}

```javascript
{
    devServer: {
        watchContentBase: true,
        publicPath: '/',
        historyApiFallback: true,
        port: 3003,
        https: false,
        overlay: true,
        compress: true,
        inline: true,
        hot: true,
        // comment or remove lines below
    
        // host: '0.0.0.0',
        // public: 'scandipwa.local',
        // allowedHosts: [
        //     '.local'
        // ],
    
        // add this to the config
        // NOTE: to get magento port you can use [npm run status] command
        proxy: {
            '/graphql': 'http://localhost:<your magento port>'
        }
    }
}
```

{% endcode %}

Comment or remote `host`, `public` and `allowedHosts` properties and add `proxy` property with a value of an object with mapping `/graphql` url to our Magento url.

> \[NOTE] You can define Magento port using `--port` option in start command. ([Docs](/v1/getting-started/available-commands/start#p-port))

If you want to use a port other than 3003 for the frontend you can! Just edit `port` property in this config file.

Note that you cannot use ports below 1024 because it will require root privileges and for your own safety **we do not recommend running scripts as root**.

## 4. Run the project and resolve possible issues.

We have adjusted the project configuration enough to start working with CMA itself. Now we can try running the project.

Go to `src` folder and run:

```bash
npm run start
```

To run frontend you will need to use a command `watch`:

```bash
# go to frontend folder first
cd app/design/frontend/Scandiweb/pwa

npm run watch
```

In general, that is it!

## \[BONUS]

### Preserve data from the old setup

To preserve data in the database, you will need to do as follows:

1. After you run magento setup, new MySQL volume will be created. You will need to get old mysql volume name and new one.
   1. To get new mysql volume name, run command:

      ```bash
       docker container inspect <mysql container>
      ```

      &#x20;and here go to the property `HostConfig.Mounts` and you should see volume name in a `Source` field.
   2. To get an old mysql volume name you can just use template: `<folder name>_mysql-data` where `folder name` is your folder name, you can get it by running `basename "$PWD"` command.
2. Now, stop the project and run commands below with replaced `<new_volume>` name and `<old_volume>` name values from the steps before.

   ```bash
    npm run stop # to stop the project

    docker volume rm <new_volume>

    docker volume create --name <new_volume>

    docker run --rm -it -v <old_volume>:/from:ro -v <new_volume>:/to alpine \
        ash -c "cd /from ; cp -av . /to"
   ```

   That's it! If you want to save some space, you can delete the old volume altogether by running the command: `docker volume rm <old_volume>`

### Delete unsed files

Since we are not using a clean Docker setup anymore, we don't need `docker-compose.*.yml` files, `Dockerfile` files as well as `build` and `opt` folder.

Go to the root directory of the project and run:

```bash
rm ./Makefile ./Dockerfile* ./docker-compose.*

rm -rf ./build ./opt
```

`deploy` folder often has some necessary files, like `latest.sql` , so we can keep it for now.


# Improve Performance

## maritos/magento2-performance-fixes

### Description

To improve first request GraphQL performance we can use Composer package [maritos/magento2-performance-fixes](https://libraries.io/packagist/maritos%2Fmagento2-performance-fixes). (Source code available [here](https://github.com/maritos/magento2-performance-fixes))

In general, this package changes the default cache building process, when the cache is empty, it locks all incoming requests and waits until the first request finishes building cache and then all following requests instead of rebuilding cache just use it right away.

So yeah, up to 30% speed improvements for GraphQL requests on the first load from a thin air.

### Installation

#### Install Composer package

Install Composer package in your project.

```bash
npm run cli # open CLI

c require maritos/magento2-performance-fixes # install package
```

#### Extend composer.json

Add `extra` field in `composer.json`

{% code title="composer.json" %}

```javascript
"extra": {
    "magento-force": "override",
    "enable-patching": true,
    "composer-exit-on-patch-failure": true,
    "patches": {
        "magento/framework": {
            "performance fix #1 - vendor/magento/framework/Config/Data.php": "vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/Config/Data.patch",
            "performance fix #2 - vendor/magento/framework/App/ObjectManager/ConfigLoader.patch": "vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/App/ObjectManager/ConfigLoader.patch",
            "performance fix #3 - vendor/magento/framework/Interception/Config/Config.patch": "vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/Interception/Config/Config.patch"
        }
    }
}
```

{% endcode %}

#### Run composer install

After `composer install` make sure patches have been applied.\
Composer install output should be similar to:

```javascript
  - Applying patches for magento/framework
    vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/Config/Data.patch (performance fix #1 - vendor/magento/framework/Config/Data.php)
    vendor/maritos/magento2-performance-fixes/vendorPatch/magento/framework/App/ObjectManager/ConfigLoader.patch (performance fix #2 - vendor/magento/framework/App/ObjectManager/ConfigLoader.patch)
    vendorPatch/magento/framework/Interception/Config/Config.patch (performance fix #3 - vendor/magento/framework/Interception/Config/Config.patch)
```

That's it! Happy coding!


# PHP Extensions

{% content-ref url="/pages/jMrg2C5xZUMzImXlsI8F" %}
[ionCube Extension](/v1/scripts-extensions/php-extensions/ioncube-extension)
{% endcontent-ref %}


# ionCube Extension

{% hint style="warning" %}

### This package is for `magento-scripts` V1 only!

{% endhint %}

This package simplifies the installation of the ionCube extension in the CMA project using `magento-scripts` **V1**.

## Installation

1\. Install package.

```bash
npm i @scandipwa/magento-scripts-php-ioncube-extension@0.0.3

# with yarn

yarn add @scandipwa/magento-scripts-php-ioncube-extension@0.0.3
```

2\. Enable extension in `cma.js`

{% code title="cma.js" %}

```javascript
const ioncube = require('@scandipwa/magento-scripts-php-ioncube-extension');

/** @type {import('@scandipwa/magento-scripts').CMAConfiguration} */
module.exports = {
    magento: {
        // ... magento config
    },
    configuration: {
        php: {
            extensions: {
                ioncube // <- set extension here
            }
        }
    }
};
```

{% endcode %}

3\. Run `magento-scripts`

```bash
npm start

# with yarn

yarn start
```

4\. Confirm that extension is installed

```bash
npm run cli

> php -v
PHP 7.4.27 (cli) (built: Jan  7 2022 17:53:56) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with the ionCube PHP Loader + ionCube24 v11.0.0, Copyright (c) 2002-2021, by ionCube Ltd.
```

## Demo

Demo setup available [here](https://github.com/scandipwa/create-magento-app/tree/master/sample-packages/magento-2.4.3-p1-ioncube)


# Common Issues

## Required parameter 'theme\_dir' was not passed

![](/files/AmxGP0Ld8uTjFEjud8x8)

The issue appears when you have an incorrect theme path in the theme configuration in the database.

To fix the issue follow the steps below:

1. Connect to your database using the database client. (like [Beekeeper Studio](https://www.beekeeperstudio.io/))

   You can get host, port and credentials after running the [status](/v1/getting-started/available-commands/status) command.
2. Open `core_config_data` table and find a row with `design/theme/theme_id` path value.
3. Open `theme` table and find a row with `theme_id` value corresponding to `value` from the previous step.
4. Make sure that `theme_path` value is the same as the one declared in your theme's `registration.php` file. (for ScandiPWA it will be likely `scandipwa/scandipwa`)

## SQLSTATE\[HY000] \[2002] No such file or directory

An error message should look like this:

```
Response: SQLSTATE[HY000] [2002] No such file or directory

In InstallCommand.php line 274:
                               
Parameter validation failed  
                               

setup:install ...
```

This issue happens when `env.php`  file is missing.

Run [start](/v1/getting-started/available-commands/start) command the second time.

## SQLSTATE\[HY000] \[2006] MySQL server has gone away

{% hint style="info" %}
Should not appear on **magento-scripts@>=1.3.0**.
{% endhint %}

```
Response: SQLSTATE[HY000] [2006] MySQL server has gone away

In InstallCommand.php line 274:
                               
Parameter validation failed


setup:install ...
```

This issue might appear at the first start of the project.

Run [start](/v1/getting-started/available-commands/start) command the second time.

## The default website isn't defined. Set the website and try again.

{% hint style="info" %}
Should not appear on **magento-scripts@>=1.4.0**.
{% endhint %}

This issue might appear if you, for some reason, have no Magento database installed in MySQL.

Delete `app/etc/env.php` file, after that run [start](/v1/getting-started/available-commands/start) command.\
This will force CMA to reinstall Magento but you will lose some configuration, for example, a persisted query that is required for the ScandiPWA theme.

## Connection to Redis localhost:port failed after 1 failures. Connection refused.

{% hint style="info" %}
Should not appear on **magento-scripts@>=1.3.1**.
{% endhint %}

This issue might appear if your port configuration has changed but Magento still uses old configuration.

There are 2 options on how to solve such a problem:

* Get current port configuration from `docker ps` or [status](/v1/getting-started/available-commands/status) command and edit `app/etc/env.php` file and run the [start](/v1/getting-started/available-commands/start) command.&#x20;

{% hint style="success" %}
&#x20;**Recommended,** as it is the safest option.
{% endhint %}

* Delete  `app/etc/env.php` file and run the [start](/v1/getting-started/available-commands/start) command.

{% hint style="danger" %}
**Not recommended,** because you will lose **all** the configuration from that file.
{% endhint %}

## Redis is not configured for persistent queries.

{% hint style="info" %}
Should not appear on **magento-scripts@>=1.6.0**
{% endhint %}

This issue might appear if you have a theme installed but persisted queries are not set up for some reason.

Run [link](/v1/getting-started/available-commands/link) command to re-link the theme and setup persisted queries.

## There are no commands defined in the "config" namespace.

This issue might appear if you have previously installed Magento with CMA but now lost all the data in MySQL for some reason.

Delete `app/etc/env.php` and run the [start](/v1/getting-started/available-commands/start) command again.




---

[Next Page](/llms-full.txt/1)

