PHP Deployment with Deployer to AWS via Bitbucket Pipeline

Muharrem Tığdemir
4 min readApr 13, 2018

Hey!

Continuously deployment should be an easy task with all autonomous services around us. If you have resources, time and money it is of course easy peasy… But sometimes, you just need time saver, quicker and problem solver services to solve it.

After my researches and test the functionalities with different tools, I’ve started to use Deployer, Bitbucket Pipeline and AWS for all of my production and pet projects to deploy my applications painless.

As an example, I’m going to use Laravel 5.6 Application and Bitnami LAMP Stack on AWS. We’ve Application and Server ready to deploy, let’s see the configurations!

Configure Bitbucket Repository and Remote Host

You need to go the Project -> Settings -> Pipeline Settings then Enable Pipelines as below.

This is the part what I love, thanks to Bitbucket we are no longer need to create ssh by ourself and inject into the pipeline as old school. It is pretty easy to deploy our application on our server, we just need to define remote host authorized_keys that’s it. Let’s copy the ~/.ssh/authorized_keys at the remote server.

Once you successfully added public key it is time to fetch host fingerprint. Just add remote IP address then, fetch it. If everything is correct you will see fingerprint as below. With this change we allowed our repository container to connect remote host via ssh to our server.

Configure Deployer

hosts.yml file allows us easily separate the test and production environment with different hosts or paths. For more configuration, you can check this link.

  • hostname: IP or domain
  • stage: The name what we call in the pipeline for specific branch deployment
  • deploy_path: This part is important, we will see at below structure after deployment in our deploy_path. You need to configure apache or nginx

Our environment file, logs and caches will be located under shared folder.

Folder structure after successful deployment

Let’s prepare our deployment script, actually one of the most important parts of the Deployer is reusable recipes. you can check them from this link or directly use the common deployment scripts. I’ve used laravel main task recipe for this example.

Prepare Bitbucket Pipeline Script

Finally, we are in the latest step. To successfully complete the deployment we need ssh client, rsync and composer in our container.

  1. Install SSH Client and Rsync into the container
  2. Install Composer into the container
  3. Globally install deployer executable library
  4. Globally install deployer reusable recipes
1)apt-get update && apt-get install -y unzip openssh-client rsync            2)curl -sS https://getcomposer.org/installer | php -- --install-
dir=/usr/local/bin --filename=composer
3)composer global require deployer/deployer
4)composer global require deployer/recipes --dev
  1. Install project depencies with composer (for production build don’t forget to add no-dev)
  2. Run tests!
  3. Run deployer from composer bin folder. If you have problem while deployment process you can debug with verbose (-vvv tag)
1) composer install                     
2) vendor/bin/phpunit
3) /root/.composer/vendor/bin/dep deploy -vvv test ## Remove -vvv after your successful deployment

Caching is Important

When you add at the below part into the pipeline, composer dependencies will be install from the cache, it will save too much time! Be aware that, default cache path is ~/.composer/cache but thanks to bitbucket they support custom path caching, yummy!

caches:
- composer

I’ve configured my pipeline to work only master branch but what if I’ve two different environments with different branches and configurations should we duplicate all the script lines and messy script lines?

Wait wait, do you still have time for better code and performance bare with me?

The key is our best friend Docker! I’ve prepared at the below Dockerfile to deploy PHP applications and push it to Docher Hub. One of the best thing is bitbucket directly reach to public Docker Hub images.

Now, we can deploy our application with 2 lines of script and we are no longer need to wait for container dependencies, yummy! You can create your own or use mtigdemir/deployer-pipeline as pipeline image.

Let’s see Benchmarks! :)

Default PHP Container and no cache

Pipeline based on PHP container with dependencies installation.

composer install takes 12s not bad actually

composer dependencies cached

I added composer cache line into pipeline script.

composer install takes 2s it looks better

Customized Docker Container and cache dependencies

I’ve used my own docker container and totally it takes 35s to build, install and deploy.

WE LOVE DOCKER, HAPPY CODING!

Note: Additionally, you can add deployer package into your project as a dependency but it will unnecessarily increase your project files.

Thanks to Anton for Deployer and Aykut Aras, Gulistan Boylu due to their valuable contribution,

Muharrem

--

--