{"id":5551,"date":"2019-09-12T10:24:58","date_gmt":"2019-09-12T15:24:58","guid":{"rendered":"https:\/\/www.rushworth.us\/lisa\/?p=5551"},"modified":"2019-09-12T10:44:35","modified_gmt":"2019-09-12T15:44:35","slug":"5551","status":"publish","type":"post","link":"https:\/\/www.rushworth.us\/lisa\/?p=5551","title":{"rendered":"GitLab SSH Deployment Setup"},"content":{"rendered":"<p>Preliminary stuff \u2013 before setting up SSH deployment in your pipeline, you\u2019ll need a user on the target box with permission to write to the files being published. You will need a public\/private key pair.<\/p>\n<p>On the target server, the project needs to be cloned into the deployment directory. The public key will need to be added to authorized_keys (or authorized_keys2 on older versions of Linux) file so the private key can be used for authentication.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"901\" height=\"258\" class=\"wp-image-5552\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-4.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-4.png 901w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-4-300x86.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-4-768x220.png 768w\" sizes=\"auto, (max-width: 901px) 100vw, 901px\" \/><\/p>\n<p>To set up your GitLab project for SSH-based deployment, you need to add some variables to the project. In the project, navigate to Settings ==&gt; CI\/CD<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"383\" height=\"887\" class=\"wp-image-5553\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-5.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-5.png 383w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-5-130x300.png 130w\" sizes=\"auto, (max-width: 383px) 100vw, 383px\" \/><\/p>\n<p>Expand the \u201cVariables\u201d section. You will need to add the following key\/value variable pairs:<\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>Key<\/strong><\/td>\n<td><strong>Value<\/strong><\/td>\n<\/tr>\n<tr>\n<td>SSH_KNOWN_HOSTS<\/td>\n<td>Output of ssh-keyscan targetserver.example.com<\/td>\n<\/tr>\n<tr>\n<td>SSH_PRIVATE_KEY<\/td>\n<td>Content of your private key<\/td>\n<\/tr>\n<tr>\n<td>DEPLOYMENT_HOST<\/td>\n<td>Target hostname, e.g. targetserver.example.com<\/td>\n<\/tr>\n<tr>\n<td>DEPLOYMENT_USER<\/td>\n<td>Username on target server<\/td>\n<\/tr>\n<tr>\n<td>DEPLOYMENT_PATH<\/td>\n<td>Path to which project will be deployed on target server<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Save the variables<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"722\" class=\"wp-image-5554\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-6.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-6.png 1024w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-6-300x212.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-6-768x542.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>I am managing both a production and development deployment within the pipeline, so I\u2019ve got prod and dev specific variables. We use the same username for prod and dev; but the hostname, path, and target server public key are different.<\/p>\n<p>If your repository is publicly readable, this is sufficient. If you have a private repository, you\u2019ll need a way to authenticate and fetch the data. In this example, I am using a deployment token. Under Settings Repository, expand the \u201cDeployment Tokens\u201d section and create a deployment token. On my target servers, the remote is added as https:\/\/TokenUser:TokenSecret@gitlab.example.com\/path\/to\/project.git instead of just https:\/\/gitlab.example.com\/path\/to\/project.git<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1054\" height=\"558\" class=\"wp-image-5555\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-7.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-7.png 1054w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-7-300x159.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-7-768x407.png 768w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-7-1024x542.png 1024w\" sizes=\"auto, (max-width: 1054px) 100vw, 1054px\" \/><\/p>\n<p>Once you have defined these variables within the project, use the variables in your CI\/CD YAML. In this example, I am deploying PHP code to a web server. Changes to the development branch are deployed to the dev server, and changes to the master branch are deployed to the production server.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"885\" height=\"761\" class=\"wp-image-5556\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-8.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-8.png 885w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-8-300x258.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-8-768x660.png 768w\" sizes=\"auto, (max-width: 885px) 100vw, 885px\" \/><\/p>\n<p>In the before_script, I set up the key-based authentication by adding the private key to my runner environment and adding the prod and dev target server\u2019s public key to the runner environment.<\/p>\n<pre>-\u00a0'which\u00a0ssh-agent\u00a0||\u00a0(\u00a0apt-get\u00a0update\u00a0-y\u00a0&amp;&amp;\u00a0apt-get\u00a0install\u00a0openssh-client\u00a0-y\u00a0)'\r\n-\u00a0eval\u00a0$(ssh-agent\u00a0-s)\r\n-\u00a0echo\u00a0\"$SSH_PRIVATE_KEY\"\u00a0|\u00a0tr\u00a0-d\u00a0'\\r'\u00a0|\u00a0ssh-add\u00a0-\u00a0&gt;\u00a0\/dev\/null\r\n-\u00a0mkdir\u00a0-p\u00a0~\/.ssh\r\n-\u00a0chmod\u00a0700\u00a0~\/.ssh\r\n-\u00a0echo\u00a0\"$SSH_KNOWN_HOSTS_DEV\"\u00a0&gt;\u00a0~\/.ssh\/known_hosts\r\n-\u00a0echo\u00a0\"$SSH_KNOWN_HOSTS_PROD\"\u00a0&gt;&gt;\u00a0~\/.ssh\/known_hosts\r\n-\u00a0chmod\u00a0644\u00a0~\/.ssh\/known_hosts<\/pre>\n<p>In the deployment component, username and host variables are used to connect to the target server via SSH. The commands run over that SSH session change directory into the deployment target path and use \u201cgit pull\u201d to fetch and merge the updated code. This ensures the proper branch is pulled to the production and down-level environments.<\/p>\n<pre>production-deployment:\r\n stage: deploy\r\n  script:\r\n    - ssh $DEPLOYMENT_USER@$DEPLOYMENT_HOST_PROD \"cd '$DEPLOYMENT_PATH_PROD'; git pull origin master\"\r\n  only:\r\n    - master\r\n\r\ndevelopment-deployment:\r\n stage: deploy\r\n script:\r\n   - ssh $DEPLOYMENT_USER@$DEPLOYMENT_HOST_DEV \"cd '$DEPLOYMENT_PATH_DEV'; git pull origin development\"\r\n only:\r\n   - development<\/pre>\n<p>Now when I make changes to the project code,<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"979\" height=\"369\" class=\"wp-image-5557\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-9.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-9.png 979w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-9-300x113.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-9-768x289.png 768w\" sizes=\"auto, (max-width: 979px) 100vw, 979px\" \/><\/p>\n<p>Assuming the tests still pass, the deployment will run<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"834\" height=\"555\" class=\"wp-image-5558\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-10.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-10.png 834w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-10-300x200.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-10-768x511.png 768w\" sizes=\"auto, (max-width: 834px) 100vw, 834px\" \/><\/p>\n<p>If you click on the deployment component, you can see what changes were pulled to the target server<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1045\" height=\"749\" class=\"wp-image-5559\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-11.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-11.png 1045w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-11-300x215.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-11-768x550.png 768w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-11-1024x734.png 1024w\" sizes=\"auto, (max-width: 1045px) 100vw, 1045px\" \/><\/p>\n<p>And, yes, the updated files are on my target server.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1245\" height=\"354\" class=\"wp-image-5560\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-12.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-12.png 1245w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-12-300x85.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-12-768x218.png 768w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-12-1024x291.png 1024w\" sizes=\"auto, (max-width: 1245px) 100vw, 1245px\" \/><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Preliminary stuff \u2013 before setting up SSH deployment in your pipeline, you\u2019ll need a user on the target box with permission to write to the files being published. You will need a public\/private key pair. On the target server, the project needs to be cloned into the deployment directory. The public key will need to &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,30],"tags":[660,232],"class_list":["post-5551","post","type-post","status-publish","format-standard","hentry","category-coding","category-system-administration","tag-ci-cd","tag-gitlab"],"_links":{"self":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/5551","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5551"}],"version-history":[{"count":3,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/5551\/revisions"}],"predecessor-version":[{"id":5563,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/5551\/revisions\/5563"}],"wp:attachment":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5551"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5551"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}