http://www.phparch.com \ May 2019 \ 5
Deploying ReactPHP Applications
DOS attacks on your application. You
can tweak all of those INI settings
and react/http respects them. If you
want more control, you can use React\
Http\StreamingServer instead, which
means you have to set up and configure
LimitConcurrentRequestsMiddleware,
RequestBodyBufferMiddleware, and
RequestBodyParserMiddleware the way
you prefer it. However React\Http\
Server should cover roughly 80% of the
use cases with some tweaking to the INI
settings. Only use React\Http\Stream-
ingServer when you need specialized
configuration with those middlewares.
Deploying
To deploy our application we need
three systems to work together: GitHub^10 ,
CircleCI^11 , and our VPS.
Preparing Your Deployment
Target
In this article, we’re going to deploy on
a VPS using Ansistrano^12 —an Ansible^13
powered deployment tool modeled
after Capistrano^14. Your deployment
tool is up to you, but make sure it can
perform the same tasks as Ansistrano.
Before we’re able to deploy we need a
few things:
- The public IP of the VPS
- A user on the VPS for the applica-
tion - SSH deploy key
- A directory to deploy to
- A place to deploy from
GitHub And CircleCI
All of my application’s code resides
in private repositories on GitHub with
CircleCI connected for automatic
testing on push/PR (just like TravisCI
for open source projects). For new
releases, a new Git tag is pushed, and
once again CircleCI kicks into motion,
first doing the same job as on push/PR
10 GitHub: https://github.com
11 CircleCI: https://circleci.com
12 Ansistrano: https://ansistrano.com
13 Ansible: https://www.ansible.com
14 Capistrano: https://capistranorb.com
to make sure all tests pass. When they
do, it starts the deployment job in the
wor k fl ow.
The following .circleci/config.yml
is a basic setup that installs dependen-
cies, runs the tests (make), and removes
all development dependencies before
saving the workspace. When deploying
we pick up the prepared code stored
in the workspace for deployment as in
Listing 1.
Before we can deploy with CircleCI
be sure to add the private part of the
SSH key^15 to it and the public part to the
.ssh/authorized_keys on the server, so
the CircleCI runner can SSH to it and
deploy your code. It is recommended
to generate an SSH key pair specifically
for this.
Ansistrano
The deployment itself is handled by
Ansistrano which is a deployment tool
based on Ansible. First, we need to
define what package Ansible Galaxy has
to install; we use .circleci/require-
ments.yml for that:
- src: ansistrano.deploy
version: 2.7.
We also need to define where Ansis-
trano should deploy to; we set up
.circleci/hosts.ini for that. This is also
15 the SSH key:
https://circleci.com/docs/2.0/add-ssh-key/
where our deployment target comes
in. In this file, we need the VPS IP
(SERVER_IP) and the user (SYSTEM_USER)
the application runs under:
[local]
127.0.0.1 ansible_connection=local
[production]
SERVER_IP ansible_user=SYSTEM_USER
The central .circleci/deploy.yml, see
Listing 2, controls the entire deploy-
ment. A few things are going on in
this file. First, the deploy from is a .tgz
created in the “before setup” tasks file.
Next, we’re setting up a few directories
the same as the Capistrano deployment
tool, which means current symlinks
to the currently active release in the
releases directory. (This allows for a
quick and easy symlink swap when
things go sour. Which is also why we
keep ten copies just in case—you can
adjust this number to the needs of your
application.) However, most impor-
tantly is PATH_TO_APP, the location where
we deploy our application.
As mentioned, we need to create
metal.tgz for a tarball deploy. One of
the reasons we use a tarball deploy is
so we don’t have to give our VPS access
to our GitHub repository, and this is a
lot faster when deploying to multiple
VPSes in parallel. We don’t have to run
Listing 2
- hosts: production
- roles:
- ansistrano.deploy
- vars:
- ansistrano_deploy_from: "{{ playbook_dir }}/metal.tgz"
- ansistrano_deploy_to: "PATH_TO_APP"
- ansistrano_shared_files:
- .env
- ansistrano_version_dir: "releases"
- ansistrano_current_dir: "current"
- ansistrano_current_via: "symlink"
- ansistrano_keep_releases: 10
- ansistrano_deploy_via: copy_unarchive
- ansistrano_before_setup_tasks_file: "{{ playbook_dir }}/before-setup.yml"
- ansistrano_after_symlink_tasks_file: "{{ playbook_dir }}/after-symlink.yml"
- ansistrano_after_cleanup_tasks_file: "{{ playbook_dir }}/after-cleanup.yml"