Platform from Scratch - Basic PHP setup
This post was originally published on the Platform.sh blog and reflects information from the time of publication.
In case you missed it, here’s the first post in the series - “Platform in a Nutshell”.
Hello, and welcome back to “Platform.sh from scratch”. The goal here will be to augment the official documentation with a short tutorial that shows how to set up a project for proper functioning on Platform.sh. We’ll dive into the “why” as little as possible here. For now let’s dive straight into the “how”.
We’re going to start with a very basic application, the example Silex app on the front page of the Silex website. This will be a standard Composer based project, so we’ll need a
composer.json
file to start with.
The project structure will look like this –
├── app
│ └── index.php
├── composer.json
└── composer.lock
The
composer.json
file can be created by running
composer require silex/silex
, or you can just copy this into
composer.json
at the root of your project directory –
{
"require": {
"silex/silex": "^2.0"
}
}
Run a quick
composer install
and the rest of the dependencies will be pulled down and placed into the standard
vendor
directory. We’re going to be using Git here, and in general you don’t want to version 3rd party dependencies like those that Composer downloads. Let’s create a
.gitignore
file and add the vendor directory to it.
echo "vendor" >> .gitignore
The entirety of the application codebase looks like this –
<?php
// in app/index.php
require_once __DIR__.'/../vendor/autoload.php';
$app = new Silex\Application();
$app->get(’/hello/{name}’, function($name) use($app) {
return ‘Hello ‘.$app->escape($name);
});
$app->run();
Very simply, all this app does add a route that responds to requests along the path of
hello/{whatever}
. As long as you’ve used the same directory structure, you can
cd
into the
app
directory and run
php -S 127.0.0.1:8080
to fire up the local php webserver and then head to localhost:8080/hello/user.
If all is working as expected, let’s head to Platform and get this thing ready for the development process.
Navigate to the platform website and register a new account. You have 1 month to (freely) evaluate whether or not Platform fits your needs, so let’s get going. I’m assuming that you can find your way through the registration and login workflow and find your self back on the “your account” page, so let’s add your SSH public key into your account and that will be all for configuring your account for now. Under “account settings” -> SSH keys you can add a public key.
Sidebar - SSH public keys
This is required for one main reason - it allows us (Platform) to securely authenticate you when you push code to a project. This is standard for most public code repos (GitHub, Bitbucket), and we use this method as well. A massive side benefit of this workflow is that it allows any Platform account holder to invite any other Platform account holder to their project. This means that agencies can invite developers to projects, users can invite other developers to help with their projects, and the overall friction of matters of authentication and authorization on projects is reduced to virtually zero. You won’t likely notice this benefit until a little later on, but when you want to share a project (or even a specific branch of a project) with another user no new account/password/validation workflow is required, and work can begin immediately.
Once that’s done, let’s go back to the main account page and “create a new platform”.
To me this workflow is pretty self explanatory and the defaults are the correct settings for now, so select which region you’d like your project to be hosted in and get through the checkout workflow. Like I said, nothing will be charged for a month, so have no fear. I have to go through this flow as well, and I work here…
After you get through that flow, you’ll be dropped into the “projects” admin of Platform.sh. This is where you’ll likely be spending the vast majority of your time.
Name your app (I’m creatively naming mine “Example Project”), and then for this project you’ll want to choose to “import your existing code”. This option will present you with a URL for a git repo to which you’ll be pushing your code. Now is the time to initialize a git repo in your codebase.
git init
Sidebar - infrastructure as code
We’ll get into the mechanics later, but this would be a good opportunity to explain the overall ethos of Platform.sh which is that you are going to be specifying your infrastructure - that is the underlying software systems on which your project will be running (MySQL, Redis, etc) - in code. You’ll be able to manipulate the infrastructure required to run your project in the same way that you manipulate the behavior of your app through writing code, and you’ll push these hardware requirements to us in the form of code.
Run
git add .
, which will add all 4 files in your project to git, and then
git commit -m "init commit"
to commit your code. After that you’ll want to cruise back over to the Platform project admin screen and copy the lines under “Push an existing repository on the command line” and drop them into your terminal. This will add the Platform git server as a remote for your project, so now you have somewhere to push your code. We’re almost there!
But we’re not totally there yet, there’s one more step. You need to tell Platform what your project needs to run or you won’t be able to push your code up to us.
All Platform.sh hosted projects require 3 files -
.platform/routes.yaml
,
.platform/services.yaml
and
.platform.app.yaml
. The routes file is just that - it’s sort of like a front controller for your entire project. What this means in practice is that you can have multiple applications running in your project (under different paths), but for now you really just need to route any request to your little example application.
This is a nice standard starting point for any given PHP project, so place this in
.platform/routes.yaml
–
#.platform/routes.yaml
“http://www.{default}/”:
type: upstream
upstream: “app:http”
“http://{default}/”:
type: redirect
to: “http://www.{default}/”
No, this is not the most beautiful file, but all you really need to know about this is that all URLs that enter this project will either have a base URL of
www.whatever.foo
and will be routed to your codebase, or they’ll bewhatever.foo
and will be redirected towww
. See step 1.
Another file that you need to have in place is the
.platform.app.yaml
file, which is a file that describes the high level requirements of this application. The most bare bones file is all that we need and it’ll look like this –
# .platform.app.yaml
The name param is linked to the “upstream” parameter in
routes.yaml. If you called the app “foo”, then the
upstream parameter would look like upstream: "foo:http"
name: app
The “type” parameter takes the form “language:version”
This could be python:3.5
for example
type: php:5.6
Look for a composer.lock (or composer.json) and download
the listed dependencies
build:
flavor: composer
How much disk space will this app need? This is primarily used for
user uploaded assets, so for this application you don’t really need
anything here, 256 would be fine. You can always grow
this later, so this is a safe starting point. (in MB)
disk: 2048
Now that a request has gotten this far, how do you want
it handled? We’ll go into more detail about these params
in a later post. This section can be thought of as
somewhat analogous to an Apache or Nginx config file
web:
locations:
“/”:
root: “app”
passthru: “/index.php”
index: - index.php
allow: true
There is more information on the documentation website about this file, and it’s all worth your time.
The services file will define what other services (this is where MySQL comes in) your app depends on but since we don’t need any yet, this can remain empty. It does need to be there however, or you won’t be allowed to push your project, so for now just create an empty file -
touch .platform/services.yaml
.
Your project’s file layout should now look like this –
├── .git
├── .gitignore
├── .platform
│ └── routes.yaml
│ └── services.yaml
├── .platform.app.yaml
├── app
│ └── index.php
├── composer.json
└── composer.lock
So with those three files in place, add them and commit them to your git repo –
git add . && git commit -m "adding platform config"
git push platform master
and you are off! If you are still looking at the dialog screen in the Platform project admin, you can click “continue” now and you will (or will shortly) see a log screen of all the relevant activity for this project - git commits and the project creation before that.
After this and every successful git push to Platform.sh those files will be analyzed to make sure that the infrastructure that your project requires and the infrastructure that is available to that project are in line. If something has changed or if this is the first time you’ve pushed code to this project, the environment will need to be set up with the services that are expected. This takes a moment, and then your code will be mounted into the environment. At this point you’ll have a running project that you can visit by going to the project admin dashboard and following the “access site” link near the top of the page.
This concludes this step! It may seem like a lot to get a 5 line PHP project going, but think of what you didn’t just have to do - spin up a server, set up a shell environment that feels home-y on that server, set up a LAMP stack, set up a build process for getting your code onto the server in a defined, runnable state, fuss with DNS or local host entries. We haven’t even touched on the aspects of Platform.sh that will completely blow your mind, so stay tuned.