How to deploy with Deployer and Github Actions
Tags: php, devops, github
Published: 2021-05-16 12:51:25

## Prologue
If you have many different projects, jumping between them, coding and pushing to production may be tedious. I know it is, because I have projects that I would rather not touch because then I would have to go through the hoops of updating the production. One project would require me to go into the production server, pull the latest commits from Github and then I would install the dependencies with Composer (yes, I would most often be doing backends with PHP so there are many shared hosting services available too ). On another project the latest changes would just directly be integrated with the production server. The difference between these two projects is that one is hosted on a shared hosting service, while the other is hosted with Heroku, a Platform as a Service (PaaS). But wouldn’t it be sweet if the deployment experience would be as easy regardless of shared hosting or PaaS? In this blog post we will be using Github Actions and Deployer to make it so!

The subject of this blog post is how to deploy a Symfony app with Github actions to a shared hosting service (*one.com is used in this tutorial*). It depends on you having set up your remote server with a public key so that it is easy to SSH into it with an identity file (See previous post about this).

To get the most out of this article I recommend you read my previous post [**Deploying a Symfony application with Deployer**](https://dev.to/andersbjorkland/deploying-a-symfony-application-with-deployer-afe). I'll be referring back to it throughout this post and it will also have your remote server properly setup for the Deployer structure.

## Github Actions
Github Actions allows you to setup custom workflows. In this post we will have Github Actions setup a file for SSH configuration and identity file, very similar to what was described in my previous post. Once these files are created, we will use the Deployer workflow and have it re-use our recipe from the same post as before. But before all this, you will have to add a few **secrets** to your project's Github repository.

### Setting repository secrets
Secrets are sensitive variables we wouldn't want to expose, such as private SSH-keys or tokens. We will see available secrets and add more in your Github repository at *github.com/example-user/example-repository/settings/secrets/actions*. 
The secrets in question are the following: PRIVATE_KEY, KNOWN_HOSTS, TARGET_HOST and TARGET_USER. These are not available until we add them ourselves. So let us do that!

The quick and dirty of it:
![Add the four secrets to the Github repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2r31bkfmxn9eh2oquce.gif)

PRIVATE_KEY will contain the content of the private key for your repository. Either reuse the one from earlier, or better, make a new one: 

Run ``ssh-keygen`` to start.
![Generate Keys](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dd2cntukz34zzoa9iz56.png)

Copy the content of the private key. This we will add to the repository secrets on Github.

Copy the contents of the public key and add it to the remote server in the file *~/.ssh/authorized_keys*.

KNOWN_HOSTS contains a hash identifying the remote server as the genuine one. You will have the hash for the server in your local .ssh directory in the file *~/.ssh/known_hosts* if you have connected to it before. If you do not have this file, then make an SSH-connection to your remote server and accept the connection as safe. This will add a hash for this connection in said file. Copy the content of known_hosts into the repository secrets.

TARGET_HOST is the url for server when connecting with SSH. On one.com it has the form ssh.example.com. Add this as a secret.

TARGET_USER is the SSH user for connecting to a remote server. On one.com the domain-name serves as the username, so it has the form of example.com. 

Having set these secrets we can now configure the workflow for Github Actions.

### Configure a workflow
Github Actions will look for workflow configurations inside your repository at */.github/workflows/*. Let's create a YAML file called *deployer.yml* inside this directory. You can name it something else if that suits your fancy better.

The workflow will use our repository secrets to configure SSH connections, then install Deployer. Then Deployer will use the recipe we have set up in the previous post when our workflow calls Deployer with the argument *mydeploy*. If you are using any other recipe a safe bet would be to change out this argument to *deploy* instead.

{% gist https://gist.github.com/andersbjorkland/363e5228106557dd5bcb644b89dfb474 %}

This workflow will trigger on every push we do to the repository. If that is not what we want, we can remove *push* from line 12 and trigger the workflow manually from within Github Actions instead.

> NOTICE
> The *secrets* used here are just examples. None of the keys glimpsed in images or GIF are in use. Be sure to keep your secrets safe too!