Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Deploying to Platform.sh

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

I have a wild idea. Let's deploy this site for real.

AssetMapper Deploy Requirements

You can deploy your code however you want... using any service or web server. It doesn't matter with AssetMapper. The only requirement is that your web server supports HTTP/2 so that our assets - the JavaScript and CSS files - can be downloaded in parallel super fast. HTTP/2 is the reason why it's not terribly important that our files aren't being combined to minimize requests.

All web servers - nginx, Caddy, whatever - do support HTTP/2. Or you could add Cloudflare or a similar service in front of your site which gives you this for free... along with some other benefits.

platform.sh Config File Setup

Anyway, we're going to deploy with Platform.sh, which is a "Platform as a Service". That means we can deploy just by creating a few config files. And this first section is all about getting that set up. Once we're done, we'll talk about some specifics of deploying with AssetMapper.

So, let's get started! We're going to do most of this in the command line with the Symfony binary. Start by running:

symfony project:init

This bootstraps a few platform.sh files, which you can see right here. .platform.app.yaml contains instructions for how to deploy - like which commands to run, what version of PHP to use, web server configuration and more. services.yaml is where you set up the services you need - like databases, queues, etc - and routes.yaml sets up your domains, and is a bit less important. Oh, and you can also add any custom php.ini config with this file.

I've been committing my progress along the way. So when I run

git status

it just shows these new files. Let's commit these and... great!

Registering the platform.sh Project

Now that we have those local files, we need to dial up the folks at platform.sh and tell them that we want to create a new project. We'll do that with:

symfony cloud:project:create

I already have some projects under Platform.sh.... which means I already have an organization... and it already has my credit card. Thieves! If you're doing this for the first time, you'll have a few extra steps.

Give your project a title, select a region - I'm using "eu-5" - and then it asks which branch will be your production environment. I'm using the default main branch.

Next, it asks if we want to set "Mixed Vinyl" as the remote for this repository. This is kinda cool because it exposes how platform.sh works. To deploy with platform.sh, we actually push our git repository to a remote repository on their services. They see this, take the code, and deploy!

Anyway, I'm going to say "no" - but you can say "yes". Because I'm saying no, you'll see me do this manually in a minute - and I'll explain more about it.

Finally, it asks to confirm pricing. This $12 USD per month is the developer rate that you can pay to play around with stuff. It will be more expensive when you decide to deploy your site to production for real. I love platform.sh because of how easy it makes my life, but there are cheaper options.

This will take a minute or two to set everything up behind the scenes. When it finishes... ding! We get some info, including the new Project ID.

Side Note: There is also a web interface on Platform.sh, so not everything needs to be done via the command line. But, yea know, nerds like me prefer the command line.

Linking the Local Code to the Remote Project

Copy the Project ID. At this point, we have some local config files - like .platform.app.yaml - and we created a new "project" on platform.sh. But the two aren't linked together yet: our local code doesn't know that it "belongs" to this project up on platform.sh.

To link them, run

symfony project:set-remote

and paste the Project ID.

Our First Deploy

Done! Ready to deploy? Do it with:

symfony deploy

We're currently on the "main" branch, so it's pushing to, basically our "production" machine, which is called an environment. One of the coolest parts of platform.sh is that you will deploy your main branch to the "production" environment, but you can also deploy other git branches to other platform.sh environments, which you can think of as other platform.sh servers.

Anyway, as I mentioned, behind the scenes, this command is just a shortcut to git push our branch up to a git remote on the platform.sh servers. And doing that kicks off the deploy!

Oooh, this looks fancy and geeky. Tons of details here, including a warning about using an old version of Composer. We'll fix that in a minute. Down here, we see that it's running symfony composer install and doing some other steps: all the basic stuff you need to deploy any Symfony app.

At the bottom, it gives us an SSL certificate, and if we keep scrolling... oooh, we have a message about a database error! Ignore that for now because... when it finishes, it gives us a URL!

Because we haven't configured any domains for the site, it gives us a temporary URL. Copy that, spin over and... our site is alive! It doesn't have any styling... since we haven't talked about AssetMapper, but it at least kinda works!

But how? How did it know to run composer install and those other things? What about that Composer warning and the database error? Let's dive into all of that next.

Leave a comment!

0
Login or Register to join the conversation
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "babdev/pagerfanta-bundle": "^4.0", // v4.2.0
        "doctrine/doctrine-bundle": "^2.7", // 2.10.0
        "doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.4
        "doctrine/orm": "^2.12", // 2.15.2
        "knplabs/knp-time-bundle": "^1.18", // v1.20.0
        "pagerfanta/doctrine-orm-adapter": "^4.0", // v4.1.0
        "pagerfanta/twig": "^4.0", // v4.1.0
        "stof/doctrine-extensions-bundle": "^1.7", // v1.7.1
        "symfony/asset": "6.3.*", // v6.3.0
        "symfony/asset-mapper": "6.3.*", // v6.3.0
        "symfony/console": "6.3.*", // v6.3.0
        "symfony/dotenv": "6.3.*", // v6.3.0
        "symfony/flex": "^2", // v2.3.1
        "symfony/framework-bundle": "6.3.*", // v6.3.0
        "symfony/http-client": "6.3.*", // v6.3.0
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/proxy-manager-bridge": "6.3.*", // v6.3.0
        "symfony/runtime": "6.3.*", // v6.3.0
        "symfony/stimulus-bundle": "^2.9", // v2.9.1
        "symfony/twig-bundle": "6.3.*", // v6.3.0
        "symfony/ux-turbo": "^2.9", // v2.9.1
        "symfony/web-link": "6.3.*", // v6.3.0
        "symfony/yaml": "6.3.*", // v6.3.0
        "twig/extra-bundle": "^2.12|^3.0", // v3.6.1
        "twig/twig": "^2.12|^3.0" // v3.6.1
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.4
        "symfony/debug-bundle": "6.3.*", // v6.3.0
        "symfony/maker-bundle": "^1.41", // v1.49.0
        "symfony/stopwatch": "6.3.*", // v6.3.0
        "symfony/web-profiler-bundle": "6.3.*", // v6.3.0
        "zenstruck/foundry": "^1.21" // v1.33.0
    }
}
userVoice