<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Continuous-Delivery on Janik von Rotz</title>
    <link>https://janikvonrotz.ch/tags/continuous-delivery/</link>
    <description>Recent content in Continuous-Delivery on Janik von Rotz</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Tue, 06 Nov 2018 12:11:01 +0200</lastBuildDate>
    <atom:link href="https://janikvonrotz.ch/tags/continuous-delivery/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Setup GoCD environment using docker</title>
      <link>https://janikvonrotz.ch/2018/11/06/setup-gocd-environment-using-docker/</link>
      <pubDate>Tue, 06 Nov 2018 12:11:01 +0200</pubDate>
      <guid>https://janikvonrotz.ch/2018/11/06/setup-gocd-environment-using-docker/</guid>
      <description>&lt;p&gt;At &lt;a href=&#34;https://www.adnovum.ch/&#34;&gt;AdNovum&lt;/a&gt; we are running &lt;a href=&#34;https://www.gocd.org/&#34;&gt;GoCD&lt;/a&gt; for automating the continuous delivery (CD) of our software products. GoCD has become the de facto standard for running CD pipelines.&lt;/p&gt;&#xA;&lt;p&gt;In this post I will give you a short introduction into GoCD using &lt;a href=&#34;https://www.docker.com/&#34;&gt;docker&lt;/a&gt;. We are going to setup a GoCD environment consisting of a server, an agent and deployable material. Further we are going to configure a deployment pipeline and build an node.js application.&lt;/p&gt;&#xA;&lt;h2 id=&#34;gocd-environment&#34;&gt;GoCD environment&lt;/h2&gt;&#xA;&lt;p&gt;The GoCD server provides an interface for configuring pipelines, environments and agents. The agent does the actual work if a deployment pipeline is triggered. Workload is managed by the GoCD server and shared among multiple agents.&lt;/p&gt;&#xA;&lt;p&gt;In order setup our GoCD environment you need to install &lt;a href=&#34;https://www.docker.com/get-started&#34;&gt;docker&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;If docker is available, start by downloading the official GoCD server image.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;docker pull gocd/gocd-server:v18.10.0&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Next start a new GoCD server container.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;docker run -d --name gocd-server -p8153:8153 -p8154:8154 gocd/gocd-server:v18.10.0&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;In your browser open &lt;a href=&#34;https://localhost:8154&#34;&gt;https://localhost:8154&lt;/a&gt;. In this interface you can manage the GoCD server.&lt;/p&gt;&#xA;&lt;p&gt;In order to run a pipeline we need a GoCD agent.&lt;/p&gt;&#xA;&lt;p&gt;Pull the official GoCD alpine image.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;docker pull gocd/gocd-agent-alpine-3.8:v18.10.0&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Run the command below to start a new GoCD agent container.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;docker run -itd  --name gocd-agent -e CI=true -e GO_SERVER_URL=https://$(docker inspect --format=&#39;{{(index (index .NetworkSettings.IPAddress))}}&#39; gocd-server):8154/go gocd/gocd-agent-alpine-3.8:v18.10.0&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Make sure that server and agent have successfully been started.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;The agent is registering itself ùsing the &lt;code&gt;GO_SERVER_URL&lt;/code&gt; variable and should be listed in the management interface  &lt;a href=&#34;https://localhost:8154/go/agents#!/agentState/asc/&#34;&gt;https://localhost:8154/go/agents#!/agentState/asc/&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;If the GoCD agent entered the state pending, select it and click on &lt;em&gt;Enable&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;h1 id=&#34;agent-configuration&#34;&gt;Agent configuration&lt;/h1&gt;&#xA;&lt;p&gt;Materials are the input for a build pipeline in GoCD. A material can be anything, an svn repo, folder, file or as in most cases a git repo. We are going to use the &lt;a href=&#34;https://codeberg.org/janikvonrotz/gocd-node-material&#34;&gt;gocd-node-example&lt;/a&gt; app as our material.&lt;/p&gt;&#xA;&lt;p&gt;Building the application requires two binaries:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;yarn&lt;/li&gt;&#xA;&lt;li&gt;node&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;These binaries are not installed on the image by default, so we need to update the image.&lt;/p&gt;&#xA;&lt;p&gt;Log into the &lt;code&gt;gocd-agent&lt;/code&gt; container.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;docker exec -it gocd-agent bash&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Install the binaries using the alpine package manager.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;apk add --no-cache nodejs yarn&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Logout and update the container image.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker stop gocd-agent&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker commit gocd-agent gocd-node-agent&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker start gocd-agent&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker images&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The commited image should be listed. If you spin up a GoCD agent again, use the new image.&lt;/p&gt;&#xA;&lt;h1 id=&#34;pipeline-configuration&#34;&gt;Pipeline configuration&lt;/h1&gt;&#xA;&lt;p&gt;Now we are ready to configure and run a GoCD pipeline.&lt;/p&gt;&#xA;&lt;p&gt;In the management interface create a new pipeline with the name &lt;code&gt;gocd-node-example&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Select &lt;em&gt;Git&lt;/em&gt; as material type and enter this url: &lt;code&gt;https://codeberg.org/janikvonrotz/gocd-node-material.git&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;A pipeline passes a material and its resulting artifacts through multiple stages. Each stage performs a build procedure or performs checks on the artifact. Here is an example of a 4-stage pipeline:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;build&lt;/li&gt;&#xA;&lt;li&gt;test&lt;/li&gt;&#xA;&lt;li&gt;analyze&lt;/li&gt;&#xA;&lt;li&gt;publish&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;We are going to have configure a build stage with two tasks and a test stage with one task.&lt;/p&gt;&#xA;&lt;p&gt;Name the current stage &lt;em&gt;build&lt;/em&gt; and the job name &lt;em&gt;build&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Select &lt;em&gt;More&amp;hellip;&lt;/em&gt; as task type and enter &lt;code&gt;/bin/bash&lt;/code&gt; in the command field.&lt;/p&gt;&#xA;&lt;p&gt;In the argument field add:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-c&#xA;yarn&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finish the wizard and open the tab &lt;em&gt;Stages&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Select the &lt;em&gt;build&lt;/em&gt; stage, then the &lt;em&gt;build&lt;/em&gt; job and add a new task.&lt;/p&gt;&#xA;&lt;p&gt;task type: &lt;em&gt;More&amp;hellip;&lt;/em&gt;&lt;br&gt;&#xA;command: &lt;code&gt;/bin/bash&lt;/code&gt;&lt;br&gt;&#xA;argument:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-c&#xA;yarn build&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Add one more stage with the following details:&lt;/p&gt;&#xA;&lt;p&gt;stage name: &lt;em&gt;test&lt;/em&gt;&lt;br&gt;&#xA;job name: &lt;em&gt;test&lt;/em&gt;&lt;br&gt;&#xA;task type: &lt;em&gt;More&amp;hellip;&lt;/em&gt;&lt;br&gt;&#xA;command: &lt;code&gt;/bin/bash&lt;/code&gt;&lt;br&gt;&#xA;argument:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-c&#xA;yarn test&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once all stages have been created, unpause and run the pipeline.&lt;/p&gt;&#xA;&lt;p&gt;![gocd pipeline in progress](/images/gocd pipeline in progress.PNG)&lt;/p&gt;&#xA;&lt;p&gt;GoCD will poll the master branch for changes. Whenver a change is committed GoCD will trigger the pipeline.&lt;/p&gt;&#xA;&lt;h2 id=&#34;troubleshooting&#34;&gt;Troubleshooting&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;proxy settings&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;In case the docker host runs behind a proxy and GoCD cannot connect to the git repository, make sure to set the git config proxy withing the docker container.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;docker exec -it _CONTAINER_NAME_ bash&#xA;su go&#xA;git config --global http.proxy https://_PROXY_HOST_:_PROXY_PORT_&#xA;git config --global https.proxy HTTP_PROXY=http://_PROXY_HOST_:_PROXY_PORT_&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For other outbound connection you can also pass the proxy env vars via docker.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;docker run -e HTTPS_PROXY=https://_PROXY_HOST_:_PROXY_PORT_ -e HTTP_PROXY=http://_PROXY_HOST_:_PROXY_PORT_ ...&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;github connection refused&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;If you cannot connect with the github repository and get this fatal error:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;fatal: unable to access &#39;https://codeberg.org/janikvonrotz/gocd-node-material.git/&#39;: Failed to connect to github.com port 443: Connection refused&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;It is most likely a proxy related problem.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;wrong version number&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Assuming the proxy env vars have been and you get this error:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;STDERR: fatal: unable to access &#39;https://codeberg.org/janikvonrotz/gocd-node-material.git/&#39;: error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Make sure to set the git proxy config for the go user:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;docker exec -it _CONTAINER_NAME_ bash&#xA;su go&#xA;git config --global http.proxy https://_PROXY_HOST_:_PROXY_PORT_&#xA;git config --global https.proxy HTTP_PROXY=http://_PROXY_HOST_:_PROXY_PORT_&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;GoCD agent pending&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;If the GoCD agent entered the state pending, select it and click on &lt;em&gt;Enable&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;yarn install job fails&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Assuming the following error occurs during the install stage:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...&#xA;[1/4] Resolving packages...&#xA;info If you think this is a bug, please open a bug report with the information provided in &amp;#34;/godata/pipelines/build/yarn-error.log&amp;#34;.&#xA;...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You need to set the yarn proxy settings in the &lt;code&gt;gocd-agent&lt;/code&gt; container.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;yarn config set proxy http://_PROXY_HOST_:_PROXY_PORT_&#xA;yarn config set https-proxy https://_PROXY_HOST_:_PROXY_PORT_&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
  </channel>
</rss>
