Magento2 Deployment – How to Deploy Public PHP Files in Magento 2 Extension

composerdeploymentmagento-2.1magento2module

I need to deploy a publicly accessible PHP file as part of a Magento 2 extension. Obviously this is not intended, as usually all requests should be routed through index.php, but in this case it's needed for performance optimization.

Is it possible to do this without requiring manual installation steps (i.e. copy files to /pub)?

I thought about making it a static asset, but the PHP engine is disabled by default in pub/static for good reasons.

Can I use the Magento composer installer in some way?

Best Answer

First part is how to do this from an extension builder perspective. I'm leaving the second part as reference for project builders.

Extension builder answer:

You can't do this from within an extension which has

...
"type": "magento2-module"
...

in its composer.json file.

You will need to create a new/extra extension for these files. This new extension will have a composer.json as follows:

{
    "name": "vendor/magento-module-foomodule-files",
    "description": "Extra files for vendor/magento-component-foomodule",
    "require": {
        ...
    },
    "type": "magento2-component",
    "extra": {
        "map": [
           "pub_scripts/*",
           "pub_scripts"
        ]
    ]
}

Update your module's composer.json to require this new extension:

{
    "name": "vendor/magento-module-foomodule",
    ...
    "require": {
        "vendor/magento-module-foomodule-files": "*"
    }
    ...
}

During installation all files from /path/to/webroot/vendor/Vendor/magento-module-foomodule-files/pub_scripts/ directory will be copied to /path/to/webroot/pub_scripts/

Project builder answer:

You will have to write your own post install commands for composer. This is relatively simple though. Add the 'scripts' node to your composer.json as follows:

    ...
    "scripts": {
        "post-install-cmd": [
            "scripts/post-install-cmd/deploy.sh"
        ]
    }
}

Note: this is the composer.json file in the root of your project.

And the script itself: scripts/post-install-cmd/deploy.sh

#!/bin/bash

WEBROOT=/path/to/webroot

#copy file(s) (never move files away from vendor)
cp "${WEBROOT}/vendor/Vendor/Module/files/file1.php" "${WEBROOT}/pub_scripts/file1.php"
cp "${WEBROOT}/vendor/Vendor/Module/files/file2.php" "${WEBROOT}/pub_scripts/file2.php"

In this example I copy the files to the 'pub_scripts' directory. This directory will need to exist.

  • Replace Vendor/Module in the file path with you own values of course.
  • Make sure that files in the 'scripts' and 'pub_scripts' directories are not publicly accessible. Deny all access to the 'scripts' directory and use htaccess login and/or IP whitelist for the 'pub_scripts' directory.

Your script(s) are now available for you at

Related Topic