We recently launched Peggy and in this post I will walk you though how to use it deploy your PHP apps: focusing on WordPress, Craft CMS and Laravel.
Below is a diagram to explain the relationships in Peggy, don’t worry about this for now but you may wish to refer back to it at a later date.

Visit https://getpeggy.com/ and click “Sign up” — once signed in you will see the screen below.

So, let’s click “Create project” and complete the details; for this example, I will use my wedding site.

Now we’re in the project it will ask you to create an endpoint — these are environments or stages for that project. For example, development, staging, production, etc.

Click “Create endpoint” and you will be asked to add a server where an endpoint can live. So let’s click “Manage servers”.

For this project we want to build a server on DigitalOcean, let’s click “Build server”.

It will then ask us to connect a DigitalOcean account, so make sure you’re logged into the correct DigitalOcean account and click “Connect my account”.
Once this is complete you will see the following screen.

Let’s go back to building the server, click Servers > Build Server.

I’m going to build my development server first, and then one for production. While it’s building you should see the following screen.

We then need to wait until the server status says “ready”.

Now let’s go back to Projects > Wedding Site and click “Create endpoint”. I’m going to use the server’s IP as a domain for this example. We will use a demo WordPress repo I have in Github:
And my details will be:
Name: production
Domain: 178.62.112.223
Remote: git@github.com:jasonagnew/wordpress-starter-kit.git
Branch: master
Server: Production Server

That should take us to the following screen, where we can manage the production endpoint.

For your new server to access your repo, you’ll need to copy the public key and add it to your repo permissions.

Once that’s pasted in, we can now click deploy.

…and then view the site.

It’s important to understand how Peggy deploys apps. Each deploy in pulled into a {app}/releases/{timestamp} and once everything is ready it’s symbolically linked to {app}/current. This is great for allowing zero downtime between deploys, however it poses a problem with persistent storage.
To handle persistent storage, folder permissions and any commands like composer install or npm install, your app needs a deploy.json; see example:
{
"commands": [
"composer install",
"npm install",
"gulp build"
],
"storage": {
"public/content/uploads": 774,
"public/content/plugins": 774
},
"permissions": {
"public/.htaccess": 644
}
}
WordPress
If you plan to use the standard WordPress file structure without any modifications (exactly as it comes in the zip from https://wordpress.org). You will need to put into a repo with the contents inside a public folder like so:
public/
wp-admin/
wp-content/
wp-includes/
wp-config.php
...
deploy.json
Then your deploy.json would look this:
{
"commands": [],
"storage": {
"public/wp-content/uploads": 774,
"public/wp-content/plugins": 774,
"public/wp-content/themes": 774,
},
"permissions": {
"public/.htaccess": 644
}
}
I would however recommend using this starter layout for future projects: https://github.com/jasonagnew/wordpress-starter-kit
Craft CMS
Using the standard Craft file structure your repo should look like this:
craft/
app/
config/
plugins/
storage/
templates/
web.config
public/
.htaccess
index.php
robots.txt
web.config
deploy.json
Then your deploy.json would look this:
{
"commands": [],
"storage": {
"craft/app": 774,
"craft/config": 774,
"craft/storage": 774,
},
"permissions": {
"public/.htaccess": 644
}
}
Laravel
Using the standard Laravel file structure your repo should look like this:
app/
bootstrap/
config/
database/
public/
resources/
storage/
tests/
composer.json
...
deploy.json
Then your deploy.json would look this:
{
"commands": [
"composer install"
],
"storage": {
"storage": 774
},
"permissions": {
"public/.htaccess": 644
}
}
Much more
In your endpoint you can manage:
- Environment variables: Easiest way to provide per-environment (development/production) API keys, etc.
- Domains: Decided to buy that extra domain extension? you can add it to your endpoint in seconds.
- Cron: No need to use `crontab -e` — it’s all handled by the dashboard.
- Workers: If you need the power of Supervisor, you can add workers without messy `.conf` files.
On your server you can manage:
- SSH Keys: Manage who has access to that server.
- PHP Errors: If something goes wrong with a deployment, you can quickly toggle PHP error visibility to help debug.
Thanks for giving Peggy a go!