Responsive staging server based on Dokku post
Foreword
In order to speed up a build process we have to automate. But this requires from us a devops knowledge and experience which we often don’t have. What would it be if we could do that much simpler than it is expected? In the article I will show you how to setup your app on the dokku which is installed on the server. I’m not able to cover the whole topic, so feel free to update this instructions as needed or ask using comments.
Introduction
What is dokku?
Docker powered mini-Heroku. The smallest PaaS implementation you've ever seen. Sponsored by our friends at Deis.
More info:
- https://github.com/progrium/dokku - Repository
- http://progrium.viewdocs.io/dokku/ - Documentation
So… Dokku is a service which runs your app for you using docker and linux containers.
How does it work?
In order to run your app on the dokku/heroku you have to customize configuration. Please read the instructions below. It’s so simple!
Getting started
This example is based on PHP project using symfony2 app. Of course you can run any other frameworks and technologies.
Step 1
Visit a heroku page with PHP instructions: https://devcenter.heroku.com/articles/buildpacks There you can find an instruction how to configure the environment. I’ll guide you through this process.
By default dokku is choosing a buildpack based on your project structure e.g. if composer.json
file exists, then PHP is chosen.
In some cases it can cause problem if your project is written in PHP but uses NodeJS. How to resolve this issue? You have to choose buildpack from official list: https://devcenter.heroku.com/articles/buildpacks
Step 2 - choose buildpack
In our case it’s a PHP buildpack (buildpack is kind of automated build process manager),
If you want to use PHP with NodeJS (like bower, npm etc.), you have to use multi-buildpack.
In order to configure that, you have to create .env
file with the following content:
export BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-php#v75
An extra configuration for advanced app using two technologies like php, nodejs once
Or if you want to use PHP with nodejs (bower etc.) then .env
should look like
export BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-multi
and an extra file with buildpacks order .buildpacks
https://github.com/heroku/heroku-buildpack-nodejs
https://github.com/heroku/heroku-buildpack-php#v75
Remember that the last buildpack is responsible for publishing.
Step 3 - configure vhost, webserver
In order to choose between nginx/apache server you have to create Procfile file in root directory with the following content
Apache:
web: vendor/bin/heroku-php-apache2 web/
Nginx:
web: bin/heroku-php-nginx -C nginx_app.conf web/
and sample nginx_app.conf
:
location / {
# try to serve file directly, fallback to rewrite
try_files $uri @rewriteapp;
}
location @rewriteapp {
# rewrite all to app.php, you can replace app.php with index.php
rewrite ^(.*)$ /app.php/$1 last;
}
Step 4 - updatating composer.json
The last thing which you have to configure is composer.json
First of all, you should know which PHP extensions you need. More info here: https://devcenter.heroku.com/articles/php-support#extensions
First, add to a require
section following dependencies:
"php": ">=5.6.*",
"ext-mbstring": "*",
"ext-intl": "*",
"ext-apcu": "*",
"ext-gd": "*"
These extensions enable:
- mbstring,
- intl,
- apcu and
- GD
After adding extensions we have to update post-install-cmd
, and post-update-cmd
tasks.
Replace the post-install-cmd
and post-update-cmd
sections by:
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::removeSymfonyStandardFiles",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache"
If you want to run some custom scripts after install/update, you should add compile
section under a scripts
section e.g.
[
"php app/console doctrine:schema:update --force --env=prod",
"php app/console doctrine:fixture:load --env=prod --no-debug",
"rm -rf app/cache/prod/*"
]
The last section which should be configured is extra
. We will configure what should happen during the build process e.g. env mapping, etc.
It should look like that:
"extra": {
"symfony-app-dir": "app",
"symfony-web-dir": "web",
"symfony-assets-install": "relative",
"incenteev-parameters": {
"file": "app/config/parameters.yml",
"env-map": {
"database_host": "DB_HOST",
"database_user": "DB_USER",
"database_password": "DB_PASS",
"database_name": "DB_NAME",
"database_port": "DB_PORT"
}
},
"branch-alias": {
"dev-master": "2.7"
},
"heroku": {
"php-config": [
"date.timezone=UTC",
"output_buffering=16384",
"opcache.fast_shutdown=0"
]
}
}
Step 5 - how to publish the app
Before you start, you should configure ssh for staging server. You can find SSH key in the /etc dir under app root
ssh staging.dev apps:create "demo-app"
ssh staging.dev mysql:delete "demo-app"
ssh staging.dev mysql:create "demo-app"
ssh staging.dev mysql:link "demo-app"
ssh staging.dev config:set "demo-app" COMPOSER_GITHUB_OAUTH_TOKEN=YOUR_GITHUB_TOKEN SYMFONY_ENV=prod WEB_CONCURRENCY=1
git remote add staging
git push --force staging master