{"id":150,"date":"2021-05-18T20:45:10","date_gmt":"2021-05-18T20:45:10","guid":{"rendered":"https:\/\/agileleaf.com\/blog\/set-up-gitlab-for-continous-deployments\/"},"modified":"2024-04-13T12:23:25","modified_gmt":"2024-04-13T07:23:25","slug":"set-up-gitlab-for-continous-deployments","status":"publish","type":"post","link":"https:\/\/agileleaf.com\/blog\/set-up-gitlab-for-continous-deployments\/","title":{"rendered":"Set up GitLab for Continuous Deployments"},"content":{"rendered":"<h2 id=\"summary\">Summary:<\/h2>\n<p>This article lays out the steps needed for setting up Continuous Deployment(CD) from a GitLab Repository to a Ubuntu server. You will need basic knowledge about servers and GitLab to keep up. For me personally, I was linking a simple Laravel web app repo to the deployment server using the following technology stack<\/p>\n<ul>\n<li>Ubuntu Server with SSH access<\/li>\n<li>Apache2<\/li>\n<li>MySQL for Database<\/li>\n<li>GitLab Repository<\/li>\n<\/ul>\n<p>Briefly, I followed the below steps for a successful Continuous Deployment.<\/p>\n<ul>\n<li>Configuring SSH access to GitLab Repository from Ubuntu Server without password (using OpenSSH Private\/Public Keys)<\/li>\n<li>This allows the server to pull changes when new commits are pushed<\/li>\n<li>Cloning GitLab repository or Adding Remote Repository<\/li>\n<li>Configuring SSH access to Ubuntu Server from GitLab Repository without password (using OpenSSH Private\/Public Keys)<\/li>\n<li>This allows GitLab to access Ubuntu server and run commands<\/li>\n<li>Making the .gitlab-ci.yml to define Pipeline for CD. (Or steps for GitLab to follow when commits are pushed)<\/li>\n<\/ul>\n<h2 id=\"background\">Background:<\/h2>\n<p>I normally work on small scale projects as a solo developer, so using Git extensively with Continuous-Integration\/Continuous-Deployment (CI\/CD) capabilities didn\u2019t seem much beneficial in my workflow; Plus with no formal training or experience working in big teams, I never really got into the collaboration capabilities made available by Git.<\/p>\n<p>Recently I started a project on which I had to collaborate, so I thought this was a good opportunity to get my feet wet on Continuous Deployment. The project was a simple Admin Panel for a mobile application and no tests were written. The main goal was automatic deployment to my server whenever a commit was pushed to my GitLab repository.<\/p>\n<p>I did not require Testing, Continuous Integration or Docker Deployment. While there are many guides on how to do CI\/CD with varying levels of feature implementation, I wanted a bare-bones solution with minimal complexity and time required. As a total newbie in GitLab CI\/CD, with only basic knowledge of Linux, and most of the guides revolving around Docker deployments, I had some trouble figuring out how to implement Continuous Deployment.<\/p>\n<p>So, this is an article for someone looking for a basic deployment configuration with GitLab with a Ubuntu Server, and for me as future reference.<\/p>\n<h2 id=\"gitlab-repository-access-from-server-using-ssh\">GitLab Repository Access from Server using SSH<\/h2>\n<p>GitLab repository will be configured as such that it can be accessed via SSH without being prompted for a password. This way our server will be able to pull the latest changes from the repo via simple <strong>git pull<\/strong> command.<\/p>\n<p>We will go through these steps<\/p>\n<ul>\n<li>Create or Find a Public\/Private key pair<\/li>\n<li>Copy the public key to GitLab Repository<\/li>\n<li>Configure GitLab on Ubuntu Server to use the private key when accessing the GitLab Repository<\/li>\n<\/ul>\n<p><strong>Create or Find a Public\/Private key pair:<\/strong><\/p>\n<p>For this we will SSH into the Ubuntu Server to find the already generated keys or make new ones.<\/p>\n<p>Once connected to your server open the command line and go to the <strong>.ssh<\/strong> folder. The following command can be used.<\/p>\n<pre><code>cd ~\/.ssh<\/code><\/pre>\n<p>Once in the directory see if you have any key pairs available.<\/p>\n<pre><code>ls -a<\/code><\/pre>\n<p>Generally, you would be able to find two files there name \u201c<strong>id_rsa.pub<\/strong>\u201d(Public Key) and \u201c<strong>id_rsa<\/strong>\u201d(Private Key)<\/p>\n<p>In case the key pairs were not found. Use the following command to generate SSH keys<\/p>\n<pre><code>ssh-keygen -t rsa<\/code><\/pre>\n<p>When prompted for a passphrase, just press enter to keep it empty.<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" class=\"kg-image\" src=\"https:\/\/lh6.googleusercontent.com\/jnHfOVVBXUVKu5wzu6Wu2HgmYxUqKjYJFynriQJKGm6vAz2mjG3j8r1hNdSWqyyueI4Odytsw3w7l2lORFVfDGYNWHTh1jZWL2bzSZoAUoqcxitGMkIiIdeMxCNK6qcNTVlTHWjy\" alt=\"\" \/><figcaption>ssh-keygen -t rsa<\/figcaption><\/figure>\n<p>Afterwards, the key pairs will be available in the directory you specified during key creation.<\/p>\n<p><strong>Copy the public key to GitLab Repository<\/strong><\/p>\n<p>Now go to the directory where the keys were generated. Open the <strong>id_rsa.pub<\/strong>(Public Key) with any text editor and copy its content. It will look similar to this<\/p>\n<figure class=\"kg-card kg-code-card\">\n<pre><code>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQt2SKv\/H\/SGHy1VgA8mfFG+0WdZexBO24AycNilAQEJkTPkvxkAq42\/am4X9JZl\/TjCvEUKCYXeays3fq1ZD6TIJeeOhOf0YqPsrQnyC98cFEM\/f5v63oWp6cO8h+tynB7TZoT18ItwIOgWKvXO9GmUdUu7CrTAF8b2iC0r08RWxopYEQD4uWFy8iR9wmasdaWe8c\/KyeO\/GjqX+2+jmNIKe\/p8sjnPqN+ArbKeYdI3nI5GdzbfUg7Po471m4cCcWNTeUpVPxrLcwWMjC85P3FPm4BzOX2l2LU7C9+Ln+MzJaTDWBjMb5u2zSesLyx1m91QNDo0Kf1f9pMasdasdaE84C\/\/FkL0ZCiufEwmZjXRguBH+e\/SQ\/A+lM9bHu7HN14tqHL6xGGozObc5tXfbkuTeP0CAGbUT35yRPkckbxblf5wGN5eiQQIjvF6JbBP9bRwvHZUW2BbgmH4hG4HTTyXRj\/UvN1EoEtccQZYqxG9pFb3o9OxC1kk= abid1208@MSI<\/code><\/pre><figcaption>OpenSSH public key<\/figcaption><\/figure>\n<p>Login in to your GitLab account and go to your Repository. Navigate to <strong>Your-Project<\/strong> \u21fe <strong>Settings <\/strong>\u21fe <strong>Repository <\/strong>\u21fe <strong>Deploy keys<\/strong>.<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" class=\"kg-image\" src=\"https:\/\/lh5.googleusercontent.com\/ge9zOVn4pNgNpVATH_dy5TB3idxcB3D6vhoLFItAyyfrY94Z7So-fodlzgxxzMK0X_rKm3JI-ihy_dtyjFwbe67gH3rB6Aifjws0lPgkFMiZ4Pqb9cGNC28jSNLf_EPMpUcFK7ad\" alt=\"\" \/><figcaption>Deploy Key GitLab<\/figcaption><\/figure>\n<p>Give a <strong>Title<\/strong> to your key, it can be any text which you can later identify. Then paste the contents of <strong>id_rsa.pub<\/strong> in the <strong>Key <\/strong>field and save.<\/p>\n<blockquote><p><em>Note: In the case you will be deploying several web apps to the same server, and you have previously added the SSH key to that server for another repo; That key will be shown in \u201cPrivately accessible deploy keys\u201d tab, and you can just \u201c<\/em><strong><em>Enable<\/em><\/strong><em>\u201d that key for this repository.<\/em><\/p><\/blockquote>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" class=\"kg-image\" src=\"https:\/\/lh4.googleusercontent.com\/6rnF1MtICWgB359qQpFakT1Ife4kEdH_cuZcH0TfKpSofoRCszzWSF_EQrmRU6BwAwa5_HuJTzf525LfsMD9RVrMNI5HimfPyj8mcAy8TPY2CqvaJTfeWA4eVs1ISBCNtWkD8iEE\" alt=\"\" \/><figcaption>Previously added deploy keys<\/figcaption><\/figure>\n<p><strong>Configure GitLab on Ubuntu Server to use the private key when accessing the GitLab Repository<\/strong><br \/>\nNext we need to configure our Ubuntu server to use the private key we created(or was already available) whenever we try to SSH to GitLab. To do this we need to ensure that <strong>ssh-agent <\/strong>is enabled by using the following command in the terminal<\/p>\n<pre><code>eval $(ssh-agent -s)<\/code><\/pre>\n<p>Then we can add the private key to the SSH Registry by<\/p>\n<pre><code># Add your private keyssh-add ~\/.ssh\/id_rsa<\/code><\/pre>\n<p>Be sure to use the directory in which the key is placed instead of \u2018<strong>~\/.ssh<\/strong>\u2019<\/p>\n<p>We also need to save these settings in a configuration file. Usually OpenSSH clients have a config file in the <strong>~\/.ssh\/<\/strong> directory under the name of <strong>config<\/strong>. If this file is not available, you can just create it using<\/p>\n<pre><code>touch config<\/code><\/pre>\n<p>in your <strong>.ssh<\/strong> directory.<\/p>\n<blockquote><p><em>Note: if your .ssh directory is under<strong> \/home\/user_name<\/strong>, you will need to create the config file there.<\/em><\/p><\/blockquote>\n<p>Open the config file and add the following lines to it via a text editor<\/p>\n<figure class=\"kg-card kg-code-card\">\n<pre><code>#GitLab.com serverHost gitlab.comRSAAuthentication yes#Be sure to replace the ~\/.ssh with the directory in which private key is storedIdentityFile ~\/.ssh\/id_rsa<\/code><\/pre><figcaption>ssh config file<\/figcaption><\/figure>\n<p>In case you have private server for different projects you can use multiple key pairs and configure them to use separate keys<\/p>\n<figure class=\"kg-card kg-code-card\">\n<pre><code>#GitLab.com serverHost gitlab.comRSAAuthentication yesIdentityFile ~\/.ssh\/config\/private-key-name-for-project1#Private GitLab serverHost gitlab.privateserver.comRSAAuthentication yesIdentityFile ~\/.ssh\/config\/private-key-name-for-project2<\/code><\/pre><figcaption>ssh config for multiple hosts<\/figcaption><\/figure>\n<p>Now we can access our GitLab repo via SSH without password prompts. You can verify you SSH configuration by running the following command<\/p>\n<pre><code>ssh -T git@gitlab.com<\/code><\/pre>\n<p>You should see a welcome message<\/p>\n<pre><code>Welcome to GitLab, @username<\/code><\/pre>\n<h2 id=\"cloning-gitlab-repository\">Cloning GitLab repository<\/h2>\n<p>We will now clone our GitLab repository to the Server.<br \/>\nFirst login to your GitLab account and navigate to the relevant project.<\/p>\n<p>Click the clone button and then copy the SSH link under \u201c<strong>Clone with SSH<\/strong>\u201d. We will use this link to clone the Repository on our server.<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" class=\"kg-image\" src=\"https:\/\/lh3.googleusercontent.com\/HvBMnhIUGicBD8F7MdoR063mHGR6VcsWL0qBdOCl3jSDouTCobHDTxBKq2CHZakEAaRNTwQuEHmmP4BebXVScinL7qdsjlKABmGg4rxIr7Y8Zq679dro4gVLxITcPvD70Q-fh5a8\" alt=\"\" \/><figcaption>Clone with SSH on GitLab<\/figcaption><\/figure>\n<p>Now login to your Server via SSH and navigate to the web app directory. If you are using Apache2, it will usually be under \u201c<strong>\/var\/www\/html\/project-folder\/<\/strong>\u201d<\/p>\n<blockquote><p>Note if you are using custom configuration or other server than Apache2, the directory for your web apps will be different.<\/p><\/blockquote>\n<p>When in the directory run the below command.<\/p>\n<pre><code>git clone git@gitlab.com:user-name\/project.git<\/code><\/pre>\n<p>Where you will replace &#8220;<strong>git@gitlab.com:user-name\/project.git&#8221;<\/strong> with the link you copied from your project repository.<\/p>\n<p>After the project has been cloned you can run the following command in the project directory to confirm that you have access to the repository and it is pointed correctly.<\/p>\n<pre><code>git ls-remote<\/code><\/pre>\n<p>If everything is correctly configured you should see something like this<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" class=\"kg-image\" src=\"https:\/\/lh6.googleusercontent.com\/-CZxBjwy_1AdMd_OLlRq291vr9Dt2YQXqo_VTcbzHYpsT1-co46Kj_1TvK7l2hzrndSnyWFU0ukAV9U7Kgknf333gWwIqNt1iL551Q6l6LVOsBXaL7IMAgFTY-y4m6FTeEOvuM_4\" alt=\"\" \/><figcaption>git ls-remote correct message<\/figcaption><\/figure>\n<p>If you previously cloned the repository using HTTP, you can change it to SSH by running the following commands.<\/p>\n<pre><code>git remote remove origingit remote add origin git@gitlab.com:username\/projectpath.git<\/code><\/pre>\n<p>Where you will replace the &#8216;<strong>git@gitlab.com:username\/projectpath.git<\/strong>&#8216; with your project SSH link.<\/p>\n<blockquote><p>In my case, I faced a bizarre problem, when I was updating my remote URL from HTTP to SSH, the commands did not seem to change the git config file and I had to manually change its URL. If you are facing connection and permission issues with your repo, checking this file out might help. You can locate this file in &#8220;<strong>project_folder\/.git\/config<\/strong>&#8220;<\/p><\/blockquote>\n<h2 id=\"configuring-ssh-access-to-ubuntu-server-from-gitlab-repository\">Configuring SSH access to Ubuntu Server from GitLab Repository<\/h2>\n<p>To run commands on our server, GitLab needs SSH access. For this article we will be using Shared GitLab runners. For more security and control over runners, you can install a Specific Runner on your own Server as well.<\/p>\n<blockquote><p><em>Extra Info: Runners are responsible for executing the commands specified by us upon every new commit. There are several types(executors) of runners available, but we are using the default Docker one. Essentially, as I understand it, whenever a commit is pushed, the runner loads a Docker image, in our case an Alpine Linux distribution and runs the commands specified. All these configs and commands are written in the gitlab-ci.yml file in our project repo, which we will look at in the next section.<\/em><\/p><\/blockquote>\n<p>Remember the SSH keys we generated in the first step. We will now store that Key(private one) in a GitLab variable. This allows GitLab(runner) to use that key to SSH into our server and run commands.<br \/>\nIf you were following the steps and are using Ubuntu server, your private key will be in &#8220;<strong>~\/.ssh\/id_rsa&#8221;<\/strong> where <strong>id_rsa<\/strong> is the private key. Open the key in a text editor and copy its content. The content will be similar to the one shown below.<\/p>\n<pre><code>-----BEGIN OPENSSH PRIVATE KEY-----b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEAxwfaXEtDslBEe4uf9kdvFRC9YJW4W6ek6x+tX1iwtJ9LYhitoluDyaMT6NuKlLli\/thHA1g6S1t\/JkRt3G5tnLNatPWG2JHnRmxU9ydT7kVGEHXdc+CGefoeGw8LXMKQDFVJjkMWwKBJTJDL74aqkvo7bZB8JDybX9QepYrG+1NNDMtyXkL8uRXfQMTZN0p7e\/kTzfdKsdasdI\/GrEkJr0RVOz2BCtUJPCG+qzjY3lz2yt4jNNoN+ed+FigkTeOpLyJj53N+CSgP8PPLsuqrFyUjAAzo9C+aBfnZVhE2YlBE5eTZ98ej77G7\/3mecptWAftngFLudhHdipkeFXtl55XuH5PeN3FhyG+VgHK3Vyt3RBDDquLQeOR8XqUQe0Mu24l0+WP9uCO5viMdqdeYeCtAIGlbFW+3MrkvSOejA2bSpK1xY4XRk670Yq3apXfGcVYGovAOy2+qBRbx8U5HhnnxU8x+p\/7DBfPeUJQSAuoEG62PBSO3tPuggBAAAFkFN5d9FTeXfRAAAAB3NzaC1yc2EAAAGBAMcH2lxLQ7JQRHuLn\/ZHbxUQvWCVuFunpOsfrV9YsLSfS2IYraJbg8mjE+jbipS5vYtHFTasdfasoahLpoAasdscjhHas+5FRhB13XPghnn6HhsPC1zCkAxVSY5DFsCgSUyQy++GqpL6O22QfCQ8m1\/UHqWKxvtTTQzLcl5C\/LkV30DE2TdKe3v8085JpsYMRQneAJ8fNvxqxJCa9EVTs9gQrVCTwhvqs42N5c9sreIzTaDfnnfhYoJE3jqS8iY+dzfgkoD\/Dzy7LqqxclIwAM6PQvmgX52VYRNmJQROXk2ffHo++xu\/95nnKbVgH7Z4BS7nYR3YqZHhV7ZeeV7h+T3jdxYchvlYByt1crd0QQw6ri0HjkfF6lEHtDLtuJdPlj\/bgjub4jHanXmHgrQCBpWxVvtzK5L0jnowNm0qStcWOF0ZOu9GKt2qV3xnFWBqLwDstvqgUW8fFOR4Z58VPMfqf+wwXz3lCUEgLqBButjwUjt7T7oIAQAAAAMBAAEAAAGADSZdrP9kB6H6BFejR\/hMRI4IlRsPRS78XHSJVeVcN3LW3jJXNoTpXiciJ55pt43QFppfhr8LivMOoY6f25KIN3Q6J\/6Y3DI3n5WEv5efmfyFtoyzBvbsq5504sDJtWU9czMnWvjfxfZRIXfnoXm6R1+1EXYcXaCLe3deVv2mS\/CjBJdkhQnT\/L6PM45N87M+GWEI9XY0SJ2C6jX6wIilb2P2fL9gKDxxg3MGoG5Cwuls14tqhZvemTVeiaR8qdsAM1s1AR\/VzUMpIG+MzQEtQzhYvPzJlN0ZfXisYgXus4\/AFRYjdAp32xUW1bqEUzvdZe6qdG51c+eb7kEqZf\/KsgIX7Ye0dCzQwwXoedywc4bkam14+JFX8r\/b9SRJ\/XmZNJsoOtH7CV\/XI07dsVnVDTgMVI6tnOQFDIZddIn7OCXrlnAKL1453HSKrneI+9mJuyn7gAtfmTk9HU5l4lq0+PUMLoS7a75qpA9vnrrmar7iQuZNiFDxycRTWflsopYBAAAAwQCEuCcJM+NjYw1Fgg3qEboW4ltlu6JUImjWzhPTyYw30IEJCV81KSWxxnsGQ5Ve4Vfxr2B\/FOW69\/e31IHQIlyDBYnmLjZf42CSmZhCGhbaRBpueebyqfr4ttUspuL5k4kWUcSetQFK9A4WiavOR8B26io8uw7H3PgoA7XBLh\/w9SeWLpnaQQgRn6yzRoO1Og3h5JFm78FaO\/ZZK9PbiaSuPbh515Bw+G2Q7nYSxs62eCu6Liz6uw0XE0r7tlTPhxIAAADBAOLyfy985rZiaPxdhfg6m1dYiHeGOb0SkE6bXhpSfSlh2HWad5GnYwrJtD\/RdnFA99aaA3Un6+V7Og8pVMtI20\/+zXLiszYIJG3y+mqQ6hGKLCruhYq4ifmhLvCQeJEJ0Jmo9B\/5mSFzHshWR+zodMjSgVK1bDg\/oBzQOjYbRRH81keiZNXSI9YHCZpd7+AsP4DZDom5bc79iCdN9fdsYu4xCDYocn5d3NW1B62N3snU2PFUqXzSCOhwbjZrKhQMcQAAAMEA4IJ5vz3WooebFf0BJmOYLHk8h0TYtOHw\/4d436PsiN4QT9v2oXta8pv3H4Gd3evde+CyMBWQQyYwWX\/QESk\/EyGvxPu3RJA6Rp4ZmDPbU3IZ1IvtpTTEbccZA3TjtdApbkX82muPAN2AJiryo2RqgqAzDiqGXlaQiP7LAqCin6TYdQeS9NoH3Y\/iUJzRiinJ+d0R9mkX+8uVFMV3xkWXBbe1NJWbeFhmxrCzHuoXHkJD1bumVB\/97cXxmaai\/TIlaksdISDsflsLkassfnJAaspqwdSKFpdgdhaHAasfJoooASfAsfcd-----END OPENSSH PRIVATE KEY-----<\/code><\/pre>\n<p>Next, we will navigate to our GitLab Repository, <strong>Settings<\/strong> \u21fe <strong>CI\/CD<\/strong><br \/>\nThen in the variables section we will &#8220;<strong>Add a variable<\/strong>&#8220;.<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" class=\"kg-image\" src=\"https:\/\/lh6.googleusercontent.com\/HaozRBFA8NWsY64KhMOrUaE9Cdcw11znSr-pfldW8jXlJcBX9VRvKwL7FhtVxrNV9nlyDr3BMEhJ7WQ5xWKZPsPcaqYoCo6lMKhiJTdYYXai3haUh15zwEGnijedtmuEhpHk7qBu\" alt=\"\" \/><figcaption>Add variable GitLab CI\/CD<\/figcaption><\/figure>\n<p>Then in the \u201cKey\u201d field, give a name to the variable. I will be using SSH_PRIVATE_KEY. <em>Remember this variable will be referenced in other files and the Key field will be used<\/em>.<\/p>\n<p>In the \u201cValue\u201d field, paste the contents of the private SSH key and click the \u201c<strong>Add variable<\/strong>\u201d button to save.<\/p>\n<h2 id=\"making-the-gitlab-ciyml-for-defining-pipeline-for-cd\">Making the gitlab-ci.yml for defining Pipeline for CD<\/h2>\n<p>Now that we have set up all the keys and configs, our server and GitLab can communicate with each other. Our gitlab-ci.yml file contains all the instructions for GitLab(runner) on what to do when a new commit is pushed, this is called a Pipeline.<br \/>\nBelow is the code for my gitlab-ci.yml file. In short, it deploys Docker with Linux image, installs OpenSSH, adds the SSH_PRIVATE_KEY variable we stored in the previous step, and then connects to our Server to run the commands.<\/p>\n<figure class=\"kg-card kg-code-card\">\n<pre><code class=\"language-yaml\">image: alpinestages:  - deploymentdeploy:  stage: deployment  before_script:      - apk add openssh-client      - eval $(ssh-agent -s)      - echo \"$SSH_PRIVATE_KEY\" | tr -d '\\r' | ssh-add -      - mkdir -p ~\/.ssh      - '[[ -f \/.dockerenv ]] &amp;&amp; echo -e \"Host *\\n\\tStrictHostKeyChecking no\\n\\n\" &gt; ~\/.ssh\/config'  script:    - ssh root@173.199.319.91 \"cd ..\/var\/www\/html\/project-folder &amp;&amp; git checkout master &amp;&amp; git pull origin master &amp;&amp; composer dump-autoload &amp;&amp; php artisan migrate &amp;&amp; exit\"  only:    - master<\/code><\/pre><figcaption>GitLab CI file for continuous deployment on Ubuntu Server<\/figcaption><\/figure>\n<p>Now let\u2019s breakdown the script.<\/p>\n<p>The \u201c<strong>image: alpine<\/strong>\u201d is specifying which docker image to use. In our case it is Alpine, which is a very lightweight distribution of Linux.<\/p>\n<p>Next we specify the stages, a way to distribute our pipeline. We can have multiple stages which can be run sequentially or in parallel. We only have one stage of \u201cdeployment\u201d.<\/p>\n<p>Now we define what to do in the stages. We first specify what stage it is<\/p>\n<pre><code>deploy:stage: deployment<\/code><\/pre>\n<p>Then we define what commands to run in <strong>before_script<\/strong> and <strong>script<\/strong>. Commands under <strong>before_script<\/strong> runs before anything else, and here we are installing and configuring SSH Client which will allow our Docker container with Linux to connect to our server.<\/p>\n<p>In <strong>script<\/strong> we SSH into our Ubuntu server to run commands. You will have to replace the IP with the IP of your server.<\/p>\n<p>Then we run the following commands<\/p>\n<ol>\n<li>Go to the project directory<\/li>\n<li>Specify the branch of our GitLab Repository<\/li>\n<li>Pull the latest code from Project Repository<\/li>\n<li>Composer dump-autoload to ensure Laravel finds all new migration files<\/li>\n<li>Run the migrations to make changes to Database, if any<\/li>\n<li>Exit<\/li>\n<\/ol>\n<p>Note that commands 4 &amp; 5 are only applicable to Laravel applications. You can run any Linux commands here specific to your needs because we are using a Ubuntu server. We can also run commands from a file to make our gitlab-ci.yml cleaner.<\/p>\n<p>At the end we specify \u201c<strong>only: master<\/strong>\u201d so that the scripts will only run if the current branch is master.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>So this is it. Now our GitLab repository and server are connected and every new commit should be automatically deployed to the Server. Our CI file can be modified to run any command on our server.<br \/>\nThis is just a basic deployment Pipeline and you can read further in the GitLab documentation for complex scenarios including testing and integration.<\/p>\n<p><strong>GitLab Documentation<\/strong>: <a href=\"https:\/\/docs.gitlab.com\/ee\/README.html\">https:\/\/docs.gitlab.com\/ee\/README.html<\/a><br \/>\n<strong>Basics of gitlab-ci.yml<\/strong>: <a href=\"https:\/\/about.gitlab.com\/blog\/2020\/12\/10\/basics-of-gitlab-ci-updated\/\">https:\/\/about.gitlab.com\/blog\/2020\/12\/10\/basics-of-gitlab-ci-updated\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction to continuous deployments. A simple, static website is set up for CI\/CD.<\/p>\n","protected":false},"author":2,"featured_media":154,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","footnotes":""},"categories":[1],"tags":[21,18,20,19],"class_list":["post-150","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-deployment","tag-git","tag-linux","tag-servers"],"_links":{"self":[{"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/posts\/150","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/comments?post=150"}],"version-history":[{"count":2,"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/posts\/150\/revisions"}],"predecessor-version":[{"id":159,"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/posts\/150\/revisions\/159"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/media\/154"}],"wp:attachment":[{"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/media?parent=150"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/categories?post=150"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/agileleaf.com\/blog\/wp-json\/wp\/v2\/tags?post=150"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}