How to configure Gitlab-CI to Auto-deploy your App via SSH

Jehad Nasser
DevOps Community
Published in
4 min readFeb 22, 2020
“CI/CD workflow” from gitlab.com

End Goal: Using Gitlab-CI to Deploy your project to a server via SSH. 💪🤓

My assumptions:

  • You have a Gitlab Runner with docker executor up and running(could be locally). You don’t? read this.
  • You have a Server to deploy to(could be locally too, it has to be reachable by the Runner).
  • You have a Gitlab account and already created a Repository for your project with a .gitlab-ci.yml file.

Introduction:

I don’t like introductions, but as you’re expecting one, let me show you something:

The journey of the code thru the Deployment cycle

Happy🤔?! Scroll down please 😬

Short story long

characters

The characters of our “Love💖” story are:

I say, without characters, ‘deployment’ lives long. ~William Shakespeare
  • Gitlab Repository( with a .gitlab-ci.yml file),
  • Gitlab Runner(with docker executor),
  • Server to deploy our app to, thru ssh.

Places

Our deployment story happens in at least two places(servers/clouds) depends on your setup:

  • Gitlab itself; gitlab.com in case you don’t self-host GitLab.
  • Cloud to host the Runner and the Server(could be each on a different cloud).

The only important thing here is that the Runner can reach Server so SSH will be possible, also the Runner can reach your Gitlab; so you can enable the runner for our demo project(repository) in Settings > CI/CD > Runners. By ‘reach’ I don’t mean they has to be on the same network but at least they are “pingable👻”. see 👇

“Speak so I can see you.” ~Socrates

Gitlab runner can reach/ping both; the gitlab instance host, and code’s final destination(server).

Gitlab Pipeline configuration:

Case 1: the Runner and the Server are in the same self-hosted VPC

Gitlab Runner and Sever are on the same private network

In my example here; I have used the localhost to setup:

  • A vagrant machine hosts a Gitlab runner with Docker executor(Github repo ready-to-use runner). And your repository has this Runner enabled: Settings > CI/CD > Runners
  • Another vagrant machine with static IP to simulate a server(Github repo demo server).

So I have the Runner and the Server on the localhost, so the Runner can reach the server, and of course can reach the Gitlab too.

Steps:

1- SSH to the Runner’s vagrant-machine, in case it’s not a vagrant machine skip: vagrant ssh

2- Generate an SSH key pair:
ssh-keygen -t rsa -N ‘’ -f ~/.ssh/id_rsa <<< n

3- Get the Private key of the Runner’s machine:

  • In the terminal run: cat ~/.ssh/id_rsa
  • Add this private key as a variable to your project on Gitlab,
    Settings > CI/CD > Variables and don’t ‘Masked’ it.
Add this private key as a variable to your project on Gitlab

4- SSH to the Server-simulation vagrant-machine:
vagrant ssh

5- Copy the public key of the Runner’s Machine to inside the the ~/.ssh/authorized_keys of the Server-simulation vagrant-machine.

6- Modify your .gitlab-ci.yml. according to the following example, a Debian based image is assumed. Edit to your needs:

.gitlab-ci.yml of the project

7- Commit & push .gitlab-ci.yml changes, the pipeline will start and ssh to your server and perform the demo command ls -al

Using of the Key-Pair during the CI

Case 2: the Runner is self-hosted and the Server is an EC2 instance

The only change here is you instead of using runners keypair, you need to put the key from the .pem file, which created/downloaded during the creation of the EC2 instance, to inside a Gitlab’s variable: Settings > CI/CD > Variables:

Add .pem content as a variable to your project on Gitlab

and no need to add the public key to anywhere in the Server-simulation vagrant-machine.

and the final .gitlab-ci.yml would be something like this:

That’s it. Easy breezy ha? 🙄😬

If you have a question leave it in the comments below.

--

--