It’s been an exciting time since we launched Upsun, and as you can imagine, we’ve all been doing a lot of experimenting. We’re testing the edges of frameworks we’ve always wanted to deploy, using Upsun as the perfect excuse to take an hour or two to try ‘em out.
We’re also doing a lot of migrations. Taking sites often deployed on Platform.sh and comparing their configuration, performance, and resource flexibility on Upsun.
So we were delighted when a colleague brought a WordPress art portfolio project into our Slack channel which he was trying to migrate with the following specs:
- Standard Plan
- A single primary developer
- 20GB of storage
- Running on PHP 7.4
- Using MariaDB 11.2
This post sets out to share what I did to help him migrate this project to Upsun from Platform.sh. Feel free to follow along on the experiment, just note that I:
- Had already installed the Upsun CLI
- Already created an account and organization on
console.upsun.com
And the same goes for Platform.sh. Now, let's get into it!
1. Setting up
I started by working from the original project on Platform.sh, which we'll refer to here with the project ID Xplatform-shX
. We'll migrate it to a project on Upsun, which we'll refer to here with the project ID YYYYupsunYYYY
. To set up a project for migration from Platform.sh to Upsun, complete the following:
- Clone the Platform.sh project repository:
platform get Xplatform-shX
- Create an Upsun project:
upsun project:create
- Configure Upsun as a remote:
upsun project:set-remote YYYYupsunYYYY
2. Configuring for Upsun
As you may have seen, the configuration for Upsun is more or less the same as Platform.sh. The only differences you may notice in this process relate to either the combining of configuration files or removing attributes used to configure resources on Platform.sh—the new resources API is the major distinguishing factor of Upsun.
To configure our chosen WordPress Platform.sh project for Upsun, I completed the following steps:
1. The Platform.sh project shared by our colleague contained what you would expect: .platform.app.yaml
, .platform/services.yaml
, and .platform/routes.yaml
files. We now have—from project:set-remote
—an .upsun
directory we can add an .upsun/config.yaml
file to. In this file, I included all of my Platform.sh configurations under some fairly intuitive keys:
# .upsun/config.yaml
applications:
app:
type: "php:7.4"
dependencies:
php:
wp-cli/wp-cli-bundle: "^2.4"
psy/psysh: "^0.10.4"
relationships:
database: "db:mysql"
variables:
php:
...
web:
locations:
"/":
...
"/wp-content/cache":
...
"/wp-content/uploads":
...
disk: 19400
mounts:
"public_html/wp-content/cache":
source: local
source_path: "cache"
"public_html/wp-content/uploads":
source: local
source_path: "uploads"
hooks:
deploy: |
...
services:
db:
type: mariadb:11.2
disk: 512
routes:
"https://{default}/":
type: upstream
upstream: "app:http"
cache:
enabled: true
cookies:
...
"https://www.{default}/":
type: redirect
to: "https://{default}/"
Everything's now in a single file. Services are under services
, routes under routes
, and the single app (app
) is under applications
(now under the key app
instead of using Platform.sh's name
attribute).
2. On Upsun, as previously mentioned, resources are configured via the API rather than YAML. Because of this, we need to remove disk
definitions for both the application (app
) and the MariaDB service db
.
3. Lastly, the _types_ of mounts on Platform.sh aren't quite the same as the options on Upsun. That is, we need to update our two mounts to use the type storage
instead of local
for the source
attribute. The reasoning behind this comes down to naming—mounts on Upsun aren't local in the same way. Any app container can be scaled up to multiple instances, requiring data in what was previously a local
mount to be shared between them. storage
is just a better name for this behavior, and for a single instance the behavior is identical to Platform.sh. For those of you who are curious, behind-the-scenes this mount type is actually a network storage service.
All of these changes result in a final configuration file, like this:
# .upsun/config.yaml
applications:
app:
type: "php:7.4"
dependencies:
php:
wp-cli/wp-cli-bundle: "^2.4"
psy/psysh: "^0.10.4"
relationships:
database: "db:mysql"
variables:
php:
...
web:
locations:
"/":
...
"/wp-content/cache":
...
"/wp-content/uploads":
...
mounts:
"public_html/wp-content/cache":
source: storage
source_path: "cache"
"public_html/wp-content/uploads":
source: storage
source_path: "uploads"
hooks:
deploy: |
...
services:
db:
type: mariadb:11.2
routes:
"https://{default}/":
type: upstream
upstream: "app:http"
cache:
enabled: true
cookies:
...
"https://www.{default}/":
type: redirect
to: "https://{default}/"
3. Data: completing the migration
With our configuration in place, we can test the project with an upsun push
.
Now, if you're following along and migrating your own WordPress project to Upsun, just before the deploy hook is run you'll notice something like this:
Configuring resources
Using default sizes
Setting 'app' profile size to '0.5'.
Setting 'app' disk to '512MB'.
Setting 'db' profile size to '0.5'.
Setting 'db' disk to '512MB'.
Creating environment main
Starting environment
Opening application app and its relationships
Executing deploy hook for application app
...
Opening environment
Environment configuration
app (type: php:7.4, cpu: 0.5, memory: 224, disk: 512)
mariadb (type: mariadb:10.11, cpu: 0.5, memory: 1408, disk: 512)
While the resources API allows you the flexibility to modify the resources available to your containers and environments, Upsun will automatically set some reasonable default values on your first push.
Nothing really to do here, just something nice to point out, I think.
When the activity has completed we have the WordPress install screen—that is, all of our code but none of our data. So let's migrate that data, starting with the following:
- Retrieve the Platform.sh database:
platform db:dump
- Retrieve the files:
platform mount:download
And since this particular migration project was an art portfolio website with almost 15 GB of art in mounts, I stepped away for an episode of Ted Lasso while the download finished. When it was finished, all of the file uploads were in the resources of our new Upsun project. You can update those resources with the CLI command upsun resources:set
. Here, I've kept everything the same as it was previously, only bumping up the disk allocated to app
up to 20048
MB.
Then, the same thing as before in reverse to upload the data:
upsun sql < ZZZZ...ZZZZ--dump.sql
upsun mount:upload
- Another episode of Ted Lasso for the upload
4. Success!
And just like that, our project—short of adding our domain—has been migrated to Upsun from Platform.sh.
Now that we’re finished we can:
- Observe our infrastructure metrics to help us determine if we’ve over-allocated resources for the project
- Use that information to tailor our resources
- Create a branch and upgrade to a more recent version of PHP and MariaDB
Best of luck with your own migrations! Join our community to let us know how it’s going.