This package is a Composer plugin to be used in projects to be deployed on VIP Go platform and provides a CLI command with two different purposes:
The package provides a command composer vip
that can be used to both prepare a local environment and deploy to VIP Go repository.
Examples:
composer vip --local # prepare local environment
composer vip --deploy --branch="develop" # deploy to VIP Go repository
Deploy command as shown above require some configuration in composer.json
, at the very least the GitHub URL for the repository, that if not present in composer.json
, can be passed to the command via the --git-url
option.
It is important to note that composer vip
command must be run after composer install|update.
Here's a one liner to both update Composer dependencies and prepare local environment:
composer update && composer vip
If this is the first time you come here, it is suggested to read below for better understand of what, how and why this command does what it does.
Skip to Command reference section for detailed documentation on the command and its available options.
VIP Go platform is a managed WordPress hosting that allows to deploy to its server via a Git commit to a repository hosted on GitHub. Different branches means different environments, and master
branch is for production.
The repository does not contain the full WordPress folder, but a sort of the /wp-content
folder.
"Sort of" because there are some differences:
mu-plugins
folder as normally they are, but in a /client-mu-plugins
folder, because mu-plugins
is reserved for proprietary MU plugins always present on the platform/vip-config
folder that must contain at least a vip-config.php
file that is loaded from the platform wp-config.php
and it is the place where to set constants that are normally located on wp-config.php
(not having access to the whole installation wp-config.php
is not editable)./private
folder that contains not browser-accessible files, but useful to store PHP-accessible data, configuration, and alike./images
browser-accessible folder that contains images that can be made available for the website./uploads
folder. All the media are stored on a CDN and will not be present on the server filesystem at all.More info can be found here: https://vip.wordpress.com/documentation/vip-go/understanding-your-vip-go-codebase/
On top of that, as mentioned above, VIP Go as quite a few proprietary MU plugins that will always be loaded.
This means that to have a local environment that can be used to develop websites there's the need of:
vip-config/vip-config.php
from wp-config.php
More info can be found here: https://vip.wordpress.com/documentation/vip-go/local-vip-go-development-environment/
To have a local environment entirely based on Composer, where plugins, themes, libraries, and WordPress core are all installed via Composer, requires additional tasks on top of that:
/wp-content/...
)The aim of the package is to make all these tasks as simple and straightforward as possible.
For local development it is necessary:
git
commandA folder on local environment must be dedicated to the project. The example structure is something like this:
In the structure in the image above only composer.json
and vip-config/vip-config.php
are mandatory, all the other folders/files are optional.
/config
The config folder that will contain the YAML files used for domain configuration, as described in VIP Go documentation.
/images
This folder contains site-wide available images, it is part of the standard VIP Go codebase.
/mu-plugins
This folder contains project-specific MU plugins. Please note that these are not the VIP Go MU plugins, but MU plugins that are specific to the project.
The standard Inpsyde process requires a different repository for each plugin/theme/library then pulled together via the composer.json
in this repository. However, each MU plugin is a single PHP file, often composed of a few lines, and put each of them in a separate repository is overkill. This is why /mu-plugins
folder exists: all the files contained in there will be deployed in the client-mu-plugins
folder of VIP Go codebase.
/private
This folder is the equivalent of the namesake folder in VIP Go codebase. As described in VIP Go documentation this folder exists to contain files that are not web accessible but can be accessed by your theme or plugins. Typical use-cases are certificates and key files, etc.
Please note that the private folder on VIP is only readable from PHP and not writable.
/themes
This folder contains project-specific themes.
The standard Inpsyde process requires a different repository for each theme that are then pulled together via the composer.json
. However, sometimes to put themes and especially child-themes in a separate repository might be overkill. This is why /themes
can be used: all the files contained in there will be deployed in the themes
folder of VIP Go codebase, alongside any other theme required via Composer.
/vip-config
This is where the site configuration is placed. There is a correspondent and namesake folder in VIP Go codebase that is supposed to contain a vip-config.php file, that is used to contain PHP configuration constants that in a “normal” installation would go in wp-config.php
, considering that is not accessible on VIP Go.
/composer.json
This is where “the magic” happens. Composer is used to pulling together all the dependencies that will be used in the project.
The composer.json
is pretty standard. There are a few things that must be taken into consideration:
inpsyde/vip-composer-plugin
extra.vip-composer
can be used to configure / customize plugin behavior. This is entirely optional.config.vendor-dir
must be used to point the "client MU plugins folder", by default vip/client-mu-plugins/vendor
(but outer folder name, /vip
, might change based on configuration of extra.vip-composer.vip.local-dir
)The whole set of settings available, with their defaults, looks like this:
{
"config": {
"vendor-dir": "vip/client-mu-plugins/vendor",
"platform": {
"php": "8.1"
}
},
"extra": {
"vip-composer": {
"vip": {
"local-dir": "vip",
"muplugins-local-dir": "vip-go-mu-plugins"
},
"git": {
"url": "",
"branch": ""
},
"wordpress": {
"version": "^6.2",
"local-dir": "public",
"uploads-local-dir": "uploads"
},
"plugins-autoload": {
"include": ["*/*"]
},
"dev-paths": {
"muplugins-dir": "mu-plugins",
"plugins-dir": "plugins",
"themes-dir": "themes",
"languages-dir": "languages",
"images-dir": "images",
"vip-config-dir": "vip-config",
"config-dir": "config",
"private-dir": "private"
},
"custom-env-names": [
]
}
}
}
The config
object is part of Composer schema, and not specific of this plugin. It is shown above for completeness. The config.platform
is set above to 7.3
because that's the version used on VIP Go platform at the moment of writing, and setting this will help in getting same dependencies that will be deployed even running a different PHP version locally.
Because all vip-composer
configuration is optional, if what shown above is fine for you, there's no need to add any configuration at all, because these defaults will be used in absence of configuration.
vip-composer.vip
One of the things that the command provided by this plugin do is to create a folder that mirrors the structure of VIP Go repository. This folder will be located in the root of the project folder.
vip-composer.vip.local-dir
config controls the name of that folder.
Another thing that the plugin command does is to download VIP Go MU plugins, and make them usable in local WordPress installation.
vip-composer.vip.muplugins-local-dir
configuration controls the name of folder where those MU plugins will be downloaded (inside project root).
vip-composer.git
This object controls the Git configuration for VIP Go GitHub repository. As shown above, default settings are empty, this requires that both URL and branch must be passed as options to composer vip
command.
Might be a good idea to at least fill in the URL to avoid having to type long commands.
Note: the URL must be provided in the HTTPS format (because easier to validate), even if the command (if possible) will use SSH to interact with GitHub.
vip-composer.wordpress
When the composer vip
command runs to setup local environment it installs WordPress. This configuration object controls the target location and the version that will be installed.
vip-composer.wordpress.version
controls the installed version. If this is empty, the plugin will look into require
object to see the version of packages with type wordpress-core
and will use the version of the first package found with that type. This configuration accepts any of the format accepted by Composer package links, plus "latest"
, to always get the latest version.
vip-composer.wordpress.local-dir
controls the folder, inside project root, where WordPress will be installed. Note that this folder (and not the project root) must be set as the webroot in the local environment web server.
vip-composer.wordpress.uploads-local-dir
controls the folder, inside project root, where the "uploads" folder will be located. The uploads folder, in facts, is located outside the WordPress folder to make the WordPress folder completely disposable without losing the media. The folder will be symlinked by the plugin command into /wp-content/uploads
so WordPress will work with no issues.
vip-composer.plugins-autoload
VIP suggests to load plugins via code using wpcom_vip_load_plugin
function
(see VIP documentation for details).
An excerpt:
we recommend loading your plugins from code. Loading plugins in code results in more control and a greater consistency across your production, non-production environments, and local development environments.
This package, by default, creates a loader MU plugin that uses wpcom_vip_load_plugin
to load plugins via code as suggested by VIP.
However, in multisite installations, it might be desirable to have some plugins activated in only some of the sites, and this is not possible when loading plugins via wpcom_vip_load_plugin
.
Thanks to plugins-autoload
setting it is possible to select which plugins will be autoloaded via either a deny-list (list of plugins to don't autoload) or a allow-list (list of plugins to autoload).
Without any setting the default is "autoload everything".
To control which plugins to include it is possible to list them, eventually with *
as wildcard, e. g.:
{
"extra": {
"vip-composer": {
"plugins-autoload": {
"include": [
"foo/some-package",
"bar/*",
"baz/something-*"
]
}
}
}
}
In the case it is easier to exclude packages from being loaded, it is possible to use the exclude
key:
{
"extra": {
"vip-composer": {
"plugins-autoload": {
"exclude": [
"foo/some-package",
"bar/*"
]
}
}
}
}
To be noted:
include
and exclude
keys are provided, exclude
is ignored: any package matching include
will be loaded, anything else will not.vip-composer.dev-paths
As shown above in the Prepare the local installation section, in the root of the project folder there might be some folder for themes, plugins, MU plugins that can be used to include those things in the same repository of the project, without using a separate repository for them. Moreover, there are folder like config
, private
and images
that can be used to fill the related VIP folder.
Only the config/vip-config.php
is mandatory all the other folders and their content is optional.
vip-composer.dev-paths
controls the name of those folders. By default names are the same names used by VIP Go repository, except for mu-plugins/
is renamed to client-mu-plugins/
.
vip-composer.custom-env-names
VIP expects WordPress configuration normally placed in wp-config.php
(e.g. constants with secrets) to be placed in a vip-config.php
file. To help having environment-specific setting, this package support multiple files where to set such configuration, where each file is environment-specific and named after the environment.
The configuration files can be placed directly in the ./vip-config/
folder in a "website repository" root folder, or can be placed in separate Composer packages having the vip-composer-plugin-env-config
type, whose support is handled by this package.
In the latter case, the supported files that are copied over from packages into website config folder are, by default, those named after the environments supported by WordPress core, and they are: local.php
, development.php
, staging.php
, and production.php
, plus a file named all.php
aimed at target all environments.
Considering VIP GO allows us to have more environments or anyway name them differently, it is possible to expand the list of supported files names via the vip-composer.custom-env-names
configuration.
Assuming default configuration and a folder structure like the one shown in the screenshot under the Prepare the local installation section, after running:
composer update && composer vip --local
(and waiting for a while) the structure of the project folder will be:
Files and folder created by the command have been highlighted above in light yellow. Let's list them:
/public
This is the project web-root, and it contains a standard WordPress installation.
Note: in the image all the WordPress root files except index.php
(wp-load.php
, wp-login.php
, etc...) have been removed for readability’s sake.
/uploads
This folder will contain all the media files uploaded locally in WordPress. The folder is located outside the /public
folder to make the latter entirely disposable. However, because /public
folder is the web-root, /uploads
folder is symlinked to /public/wp-content/uploads
that is the standard WordPress uploads folder, so as long as WordPress (and the web-server) are concerned uploads can be served correctly.
Especially relevant for Linux users: make sure the folder is writable by the local web-server and PHP.
/vip
This folder contains the exact 1:1 representation of the VIP Go repository. It contains exactly the files that will be pushed to the VIP Go repository for the project. More on this folder in next section.
/vip-go-mu-plugins
This folder contains VIP Go MU plugins. In the wp-config.php
file that is also generated, this folder is already configured as the WordPress WPMU_PLUGIN_DIR
so that locally WordPress will correctly load all the VIP MU plugins.
/composer.lock
The Composer lock file.
Those familiar with Composer could wonder where the Composer "vendor" folder and the Composer autoload file are located.
The answer is: inside /vip/client-mu-plugins
. As written above, the /vip
folder contains exactly what will be pushed to the VIP Git repository, and because for sure we need Composer libraries and autoload online, we need those to be inside the /vip
folder.
/wp-cli.yml
WP CLI config file. It contains a reference to the WordPress installation path, so WP CLI commands can be executed from the project root folder without having to pass the --path
parameter all the time.
/wp-config.php
WordPress' configuration file for the local environment. This is slightly different from a "standard" wp-config.php
because it contains
WPMU_PLUGIN_DIR
pointing /vip-go-mu-plugins
as the source of MU plugins.require
statement to load vip-config/vip-config.php
simulating what happens in VIP GoThe first time the VIP Go Composer plugin is executed there's the need to fill it with project settings, e. g. DB settings, nonce keys and such.
/vip
folder in detailLet's "zoom" in the /vip
folder:
/client-mu-plugins
This folder contains the Composer /vendor
folder, including the autoload.php
file. This is a "standard" Composer vendor folder, and it is located here thanks to the config.vendor-dir
configuration added in composer.json
.
This folder also contains a copy of all MU plugins available in /mu-plugins
folder.
Finally, it contains the __loader.php
file, a MU plugin generated by the composer vip
command that contains instructions to:
wpcom_vip_load_plugin
function as recommended in VIP documentation/config
, /images
, and /languages
This folder contain a copy of any file located in the namesake folders under root. In the example above these folders are empty because the correspondent folders under root are empty or do not exist at all.
/plugins
This folder contain all the plugins that have been required via Composer (in the example, just one), plus a copy of any plugin located in /plugins
folder under root (in the example that folder does not exist at all).
/private
This folder will contain a copy of any file located in /private
folder under root (in the example that folder does not exist at all) plus a deploy-id
file, a text file that contains a random UUID that is unique per build (and so per deployment). It can be used by application code, for example, to bust caches so that at every deploy caches are invalidated.
/themes
This folder contain all the themes that have been required via Composer (in the example, just one), plus a copy of any plugin located in /themes
folder under root (in the example there's a child theme).
Please note that even if this approach is supported, it is suggested to use separate repositories for themes, due to an issue with "dev paths" using sub-folders, and themes always comes in a folder.
Make sure to review the section Managing Dev Paths below that documents this matter in detail.
/vip-config
This folder contain a copy of any file located in /vip-config
folder under root, at the very least the vip-config.php
file that is required.
In the section right above has been said how the folders /client-mu-plugins
, /config
, /images
, /languages
, /plugins
, /themes
, and /vip-config
, all might contain copies of files and folders located at the root of the package. The reason for this is to make the /vip
folder an exact 1:1 representation of what will be deployed to VIP, but there are some gotchas associated with this approach.
Make sure to review the section Managing Dev Paths below that documents this matter in detail.
.gitignore
sampleIt is important that new files generated by both Composer and this plugins needs to be git-ignored.
An example of .gitignore
could be the following:
/public/
/uploads/
/vip/
/vip-go-mu-plugins/
/wp-config.php
but note that this is not generated automatically.
Having a local environment up and running is just the start of the development process.
The workflow of development will be:
composer.json
composer update && composer vip --local
to update the dependencies and refresh the local environmentHaving to deal with remote repositories for each plugin/theme/library might be overkill, especially in the very early stages of development.
It is much better to deal with local repositories during development. It has been said how for simple and/or project specific MU plugins/plugins/themes it is possible to use "dev paths" for the scope, but very likely there will be the need to work on packages that need to live in separate repositories.
Luckily Composer supports "path repositories".
In short, instead of using a VCS repository "as source" for a package, Composer can use a local path (even relative) so that it is possible to run composer install
and get the content of that folder installed just like any other remotely-hosted package.
The nice thing about it is that the local folder used as path repository could be very well the local clone of a remote repository, so that when changes are finalized and tested locally (thanks to path repository) they can be pushed to the remote repository to have them deployed online.
The bad thing about it is that using path repositories requires changing the composer.json
and that's not an option, because it does not make sense to place local paths in a composer.json
that is pushed online.
To solve this problem it is possible to make use of Composer Studio, a Composer plugin that allows the usage of Composer path repositories without changing the composer.json
, but making use of a separate studio.json
file that can be easily git-ignored and so kept local.
As quickly written in the beginning, this plugin provides a single command:
composer vip
--local
- Tell the command to build the local environment
--deploy
- Tell the command to prepare the files and folders for production and commit any change to VIP Go GitHub repo, that is at any effect deploying the website.
--git-url
- Set the Git remote URL to pull from and push to. When --local
is used, this is relevant only if --git
or --push
are used as well.
--branch
- Set the Git branch to pull from and push to. When --local
is used, this is relevant only if --git
or --push
are used as well.
--git
- Build Git mirror folder, but do not push. To be used in combination with --local.
Ignored if --deploy
is used.
--push
- Build Git mirror and push it. To be used in combination with --local.
Ignored if --deploy
is used.
--sync-dev-paths
- Synchronize local dev paths. To be used as the only option.
--prod-autoload
- Generate production autoload. To be used in combination with --local.
It is assumed if --git
or vip-dev-env
is used.
--update-wp
- Force the update of WordPress core. To be used as the only option or in combination with --local.
Ignored if --deploy
is used.
--skip-wp
- Skip the update of WordPress core. To be used in combination with --local.
Ignored if --deploy
is used.
--update-vip-mu-plugins
- Force the update of Vip Go MU plugins. To be used as the only option or in combination with --local.
Ignored if --deploy
is used.
--skip-vip-mu-plugins
- Skip the update of Vip Go MU plugins. To be used in combination with --local.
Ignored if --deploy
is used.
--vip-dev-env
- Prepare the environment for vip dev-env
usage. To be used as the only option.
--local
option makes the command perform a set of tasks to prepare and/or update the local environment:
wp-config.php
if necessarywp-cli.yml
if necessaryThis is the default option and it is assumed if no option is passed.
--deploy
option makes the command perform a set of tasks to prepare, sync and update the VIP Go GitHub repository:
The command using this option is perfectly suitable to be run in CI pipelines.
Two commands options are available to configure Git operations:
--git-url
- To set the URL of Git repo to pull from / push to. If not provided, the value will be taken from composer.json
in the extra.vip-composer.git.url
config. If there's also no such config, the Git sync will fail.--branch
- To set the branch of Git repo to pull from / push to. If not provided, the value will be taken from composer.json
in the extra.vip-composer.git.branch
config. If there's also no such config, the Git sync will fail.Example:
composer vip --deploy --git-url="https://github.com/wpcomvip/my-project" --branch="develop"
By default, when --local
option is used the plugin prepare the local environment without bother with Git at all. Sometimes might be desirable to look at the Git diff of what would be pushed using --deploy
, before actually doing the deploy.
This could be achieved via the --git
option.
When this option is used, the plugin creates a folder inside /vip
that has an unique name prepended by a dot, something like /.vipgit5b59852eb21c7
.
This folder will be a Git repository, build from VIP Go GitHub repo, where all changes have been committed. So by pointing a Git client / tool to this folder it is possible to "preview" changes before pushing. And, actually, by running git push
on this folder it is possible to deploy the changes.
Sometimes it is also desirable to directly push the changes from local environment.
This could be achieved via the --push
option. Using this option in combination with --local
is different than just using --deploy
by the fact that the latter will only run tasks that are relevant for remote server (e. g. always skipping WP install, VIP MU plugins download...) so it is a good choice to deploy from a CI. By using --local --push
the command will update the development environment and also push changes to remote repo.
Git configuration (URL and branch) applies when using either --git
or --push
in the same way they do when using --deploy
.
Example:
composer vip --local --git --branch="develop"
One of the things that it seems harder to grasp about the folder structure promoted by this plugins is why there are "dev paths" (plugins, themes, config and all the other folders in VIP Go structure) in the root of the project and same folders are also copied under /vip
folder.
The reason is quite simple. The reason to exist of /vip
folder is to be a 1:1 mirror of the VIP Go Git repository.
Which means that when using Composer, a folder like /vip/plugins
will contain plugins that are installed via Composer. Same for themes and MU plugins.
If, for any reason, developers want to use the same "project" repository to include plugins, MU plugins, themes without them being on a separate repo, it would mean that /vip/plugins
(or /theme
or /client-mu-plugins
) would contain, after composer install, a "mix" of third party dependencies required via Composer and custom packages written for the project.
Because the latter should be surely kept under version control, while the former probably not, it would be necessary to rely on quite complex (and honestly hard to maintain) .gitignore
configuration.
By using separate folders, like this plugins does, the folders in root contain only custom work to be kept under version control, and then the command takes care of copying them, alongside other dependencies that Composer takes care of placing in proper place (thanks to a custom installer shipped with the plugin).
This way the /vip
folder can be completely Git-ignored and it also becomes completely disposable, which is a good things for folders that are automatically generated.
However, this approach has also two issues.
The first issue is that "dev paths" in root folder are "copied" into /vip
folder, which means that at any change the copy has to be done again.
This is why the plugin command provides the option --sync-dev-paths
.
This flag must be used as the only flag, and makes the command sync the dev paths from root to /vip
.
Example:
composer vip --sync-dev-paths
Considering this is a quite fast operation it makes sense to use (if possible) IDE feature that automatically run the above command when anything changes inside "dev paths".
Here's the screenshot on how this could be set up via in PHPStorm using a "file watcher":
The second issue regards themes and plugins that comes in own folder. The problem is that when a theme or a plugin in own folder is deleted from /themes
or /plugins
, it will not be deleted from /vip/themes
or vip/plugins
.
For example, if there's a theme in /themes/my-theme
, its files will be correcly kept in sync with /vip/themes/my-theme
as long as the /themes/my-theme
exists. However, if /themes/my-theme
is deleted, /vip/themes/my-theme
will not be deleted.
This issue does not affect single-file plugins, e. g. a plugin located at /plugins/my-plugin.php
will be correcly kept in sync with /vip/plugins/my-plugin.php
and if /plugins/my-plugin.php
is deleted, /vip/plugins/my-plugin.php
will be deleted as well.
For this reason it is suggested to use "dev paths" only for MU plugins and simple single-file plugins, but use a separate repository for themes (that always comes in own folder) or more complex plugins.
One of the things the command does when using --local
is to download WordPress from official release zip file ("no content" version).
This is done in 3 cases:
"latest"
is used as version requirement in plugin configuration in composer.json
and a new (stable) release have been madecomposer.json
changed (either in require
or plugin configuration) and the currently installed version does not satisfy the new requirements.This means that even if a newer version of WordPress is released that would satisfy the requirements, but the currently installed version also satisfy the requirements no installation is made.
For example if the requirements says 4.9.*
and the installed version is 4.9.5
but the 4.9.7
is available, WordPress is not updated by default when --local
option is used.
In this case an update can be forced by using --update-wp
flag.
This flag can be used in combination with --local
to mean "update local environment and also force the update of WP if a new acceptable version is available" or it can be used alone to mean "just update WP and nothing else".
This latter usage is worthy because, as previously said, when using this plugin, composer update
does not update WordPress.
Another option that controls the download of WordPress is --skip-wp
.
This option tells the command to never download WP. Can only be used in combination with --local
. This is useful when, for example, version requirements is set to "latest" but one wants to save the time necessary to download and unzip WordPress (which might take a while, especially on slow connections).
Must be noted that if WordPress folder is not there and --skip-wp
is used, the local installation will not functional.
It is also worth saying that if used together --update-wp
and --skip-wp
will make the command fail.
Example:
composer vip --update-wp
The most time-consuming task the first time command is ran is to download VIP Go MU plugins. Those plugins accounts for over 300 Mb in total, pulled from a repo with several recursive sub-modules.
This is why the composer vip
command by default only download the MU plugins if they are not there. So presumably the first time ever the command is ran, or if the folder is deleted by hand.
However, those MU plugins are actively developed, and it make sense from time to time update them locally to be in sync with what is on VIP Go servers.
This can be obtained via the --update-vip-mu-plugins
flag.
This flag can be used in combination with --local
to mean "update local environment and also force the update of VIP Go MU plugins" or it can be used alone to mean "just update VIP Go MU plugins".
The latter usage is basically an alias for:
git clone --recursive git@github.com:Automattic/vip-go-mu-plugins.git
but:
composer vip --update-vip-mu-plugins
is shorter to type and easier to remember.
Another option that controls the download of Vip Go MU plugins is --skip-vip-mu-plugins
.
This option tells the command to never download VIP Go MU plugins. Can only be used in combination with --local
. This is useful when MU plugins are not there (never downloaded or deleted by hand), but one wants to save the time necessary to download them, for any reason.
Must be noted that if MU plugins are not there and --skip-vip-mu-plugins
is used, the local installation will not be functional.
It is also worth saying that if used together --update-vip-mu-plugins
and --skip-vip-mu-plugins
will make the command fail.
Example:
composer vip --local --update-vip-mu-plugins
VIP dev-env simulates the VIP environment using Docker and Lando.
For this reason, while it is a local development environment has many characteristics of the production environment.
The --vip-dev-env
flag for the command, executes all the steps that are necessary to prepare the
vip/
folder, including the production autoload, skipping operations like the download of WordPress core
or VIP MU plugins because those are handled by the vip dev-env create
command.
Example:
composer vip --vip-dev-env
vip dev-env create --app-code="./vip"
VIP Composer Plugin is a free software, and is released under the terms of the MIT license. See LICENSE for complete license.
The team at Syde is engineering the Web since 2006.