<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matt Thompson</title>
    <description>The latest articles on DEV Community by Matt Thompson (@matttea).</description>
    <link>https://dev.to/matttea</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F106386%2F9fc79e4f-6a5e-4a59-9e62-6c5b75a06961.png</url>
      <title>DEV Community: Matt Thompson</title>
      <link>https://dev.to/matttea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matttea"/>
    <language>en</language>
    <item>
      <title>The Tacit Knowledge Series</title>
      <dc:creator>Matt Thompson</dc:creator>
      <pubDate>Wed, 15 Sep 2021 08:04:23 +0000</pubDate>
      <link>https://dev.to/matttea/the-tacit-knowledge-series-54gb</link>
      <guid>https://dev.to/matttea/the-tacit-knowledge-series-54gb</guid>
      <description>&lt;p&gt;From a personal and professional standpoint I'm interested in what is required to keep engineers moving from being experienced and competent to being expert.&lt;/p&gt;

&lt;p&gt;Many views point to &lt;code&gt;tacit knowledge&lt;/code&gt;. But by its very nature tacit knowledge is hard to define and even harder to share.&lt;/p&gt;

&lt;p&gt;Shawn Wang describes the problem perfectly in his excellent book &lt;strong&gt;The Coding Career Handbook&lt;/strong&gt;...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Much of your learning from Junior to Senior involves gaining tacit knowledge. You can read all the programming books in the world, but, by definition, you are still limited to things that people can write down. That is explicit knowledge, and it is only the tip of the iceberg.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We see tacit knowledge in action every day - when a doctor is able to make a prognosis during a crazy short appointment, or, hopefully more commonly, when an expert engineer looks at a design for all of 5 seconds and can immediately tell you her concerns or questions.&lt;/p&gt;

&lt;p&gt;In trying to understand how they reached these conclusions so quickly, explanations might start with some principles, then move on to the exceptions and caveats to these principles, and may often ends with something like "&lt;em&gt;it just feels right&lt;/em&gt;". It's these natural judgements that are made that can't be simply explained so that others could reach the exact same outcome.&lt;/p&gt;

&lt;p&gt;For an excellent breakdown of this, with detailed examples in software engineering and other knowledge fields, I highly recommend Cedric Chin's Commonplace article - &lt;a href="https://commoncog.com/blog/tacit-knowledge-is-a-real-thing/"&gt;Tacit Knowledge is a Real Thing&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;So I want to tap into the tacit knowledge of those around me. I know I can't replace gaining the experience that will build this knowledge myself, but I hope that by being in tune with it I can see the situations, ask the questions, and hopefully understand the thought processes behind these judgements.&lt;/p&gt;

&lt;p&gt;My plan is to pick up on scenarios where experienced engineers might have taken a path through a situation or problem that wasn't obvious to me, pin them down to walk through how they approached it; what experience, principles and ideas they drew on, and then write it down and share it here...&lt;/p&gt;




&lt;h3&gt;
  
  
  The Tacit Knowledge Series so far
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://logical-progression.matttea.com/post/tacit-vulnerabilities/"&gt;Dependency vulnerabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://logical-progression.matttea.com/post/tacit-bigger-picture-recall/"&gt;Bigger picture recall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://logical-progression.matttea.com/post/tacit-context-switching/"&gt;Calm context switching&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://logical-progression.matttea.com"&gt;https://logical-progression.matttea.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>learning</category>
    </item>
    <item>
      <title>Adding a Custom Domain to a GitLab Pages Site</title>
      <dc:creator>Matt Thompson</dc:creator>
      <pubDate>Mon, 31 Aug 2020 11:48:20 +0000</pubDate>
      <link>https://dev.to/matttea/adding-a-custom-domain-to-a-gitlab-pages-site-3hok</link>
      <guid>https://dev.to/matttea/adding-a-custom-domain-to-a-gitlab-pages-site-3hok</guid>
      <description>&lt;p&gt;My &lt;code&gt;logical-progression&lt;/code&gt; blog site is built using the Hugo static site generator and is hosted on GitLab Pages. With GitLab Pages custom domains are possible, and I was keen to use the logical-progression alias.&lt;/p&gt;

&lt;p&gt;Initially, however, I couldn't remember who my DNS host was! A problem, as resource records need to be added there to enable the alias. The problem was based on the fact that...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;matttea.com&lt;/code&gt; domain was purchased via Google Domains&lt;/li&gt;
&lt;li&gt;My webhosting was with Interserver&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My thinking was that I needed to add the relevant &lt;code&gt;CNAME&lt;/code&gt; and &lt;code&gt;TXT&lt;/code&gt; resource records to the Google Domains dashboard (as it was the clearest dashboard to work with), and by doing so I was prompted to use the Google domain nameservers. Doing this broke all my other sites, highlighting that Google obviously wasn't my DNS host!&lt;/p&gt;

&lt;p&gt;Realising that Interserver therefore was my DNS host I created the &lt;code&gt;CNAME&lt;/code&gt; and &lt;code&gt;TXT&lt;/code&gt; records in the correct place, and reset the nameservers (so that my other sites worked again)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;CNAME&lt;/code&gt; or 'canonical name' record maps the alias name to the true or canonical domain name.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;TXT&lt;/code&gt; record is required to verify ownership of the domain, giving a gitlab verification code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The place to add these records on the Interserver site is via the &lt;code&gt;cPanel &amp;gt; Domains &amp;gt; Zone Editor&lt;/code&gt;, and then by clicking the &lt;code&gt;MANAGE&lt;/code&gt; option for the domain you want to add a subdomain alias to. In this case &lt;code&gt;matttea.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As DNS changes can take anything from a few minutes to a few days to propagate, it can be useful to use sites such as &lt;code&gt;whatsmydns.net&lt;/code&gt; to check in on whether your changes have worked.&lt;/p&gt;

&lt;p&gt;GitLab Pages also offers free certificate management with &lt;code&gt;Let's Encrypt&lt;/code&gt;, allowing you to enable HTTPS for alias names. This can be switched on in the Pages settings. This can be flaky though and I received a few &lt;code&gt;Something went wrong while obtaining the Let's Encrypt certificate&lt;/code&gt; error messages. Without this, browsers will give 'not secure' messages to visitors, so it's worth getting it working. The troubleshooting guide suggests the following...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to your project's Settings &amp;gt; Pages.&lt;/li&gt;
&lt;li&gt;Click Edit on your domain.&lt;/li&gt;
&lt;li&gt;Click Retry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This didn't work for me, so the guide continues with...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure you have properly set only one CNAME or A DNS record for your domain. ✔️&lt;/li&gt;
&lt;li&gt;Make sure your domain doesn't have an AAAA DNS record. ✔️&lt;/li&gt;
&lt;li&gt;If you have a CAA DNS record for your domain or any higher level domains, make sure it includes letsencrypt.org. ✔️&lt;/li&gt;
&lt;li&gt;Make sure your domain is verified. ✔️&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Turns out I just needed to retry on the first part quite a good few times.&lt;/p&gt;

&lt;p&gt;The final step to set up the new alias is to change the &lt;code&gt;baseUrl&lt;/code&gt; in the Hugo config to the new domain, this enable CSS on the page amongst other things.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Originally posted on &lt;a href="https://logical-progression.matttea.com"&gt;https://logical-progression.matttea.com&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dns</category>
      <category>staticsite</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>The Joy of People Management</title>
      <dc:creator>Matt Thompson</dc:creator>
      <pubDate>Tue, 25 Aug 2020 19:28:05 +0000</pubDate>
      <link>https://dev.to/matttea/the-joy-of-people-management-51af</link>
      <guid>https://dev.to/matttea/the-joy-of-people-management-51af</guid>
      <description>&lt;p&gt;We can certainly be forgiven for fearing the worst and focusing on the negatives right now - a global pandemic that shows no signs of disappearing, Brexit just around the corner, and strategic reviews all around us at work - but being, or becoming a people manager shouldn't be one of them.&lt;/p&gt;

&lt;p&gt;So, with all the change going on right now I'd like to share a few, maybe less obvious reasons why people management has been an overwhelmingly positive experience throughout my career.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time saving
&lt;/h2&gt;

&lt;p&gt;This may sound completely counter-intuitive, but being a manager &lt;em&gt;saves&lt;/em&gt; me time.&lt;/p&gt;

&lt;p&gt;Being a people manager, even to only a handful of people, immediately gives you access to a network that extends into each of their product areas and domains, and gives you an extremely candid insight into the personalities, the decisions, the challenges and most importantly the work in each of those areas.&lt;/p&gt;

&lt;p&gt;For the last 18 months I've been fortunate enough to manage anywhere between 16 and 22 engineers across almost as many product teams, and far from this taking up all my time, it's provided me with so much insight into what's going on around our business that I rarely have to do any digging to determine who to speak to, or what the current goals or priorities are for a specific area.&lt;/p&gt;

&lt;p&gt;A great recent example of this was when my own product team was trying to align priorities and roadmaps with others in our wider 'Findability' product domain, those of us in my People Management team who work in this domain were quickly able to get together and openly share our thoughts (and dare I say, our secrets!) and get to a great level of understanding far easier than we'd otherwise have been able to do.&lt;/p&gt;

&lt;p&gt;This has proved even more valuable during lockdown and this 'new (ab)normal', because I now no longer have the luxury of walking around an area to catch conversations or people.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning
&lt;/h2&gt;

&lt;p&gt;I make no joke when I say I have learnt infinitely more from the people I've managed than they have from me.&lt;/p&gt;

&lt;p&gt;Those whom I've managed have always been and will always be far better developers, analysts and engineers than I'll ever dream of being, but through working with, and coaching people to be even better I've been able to more clearly focus on areas for my own improvement. When working with other skilled professionals and working through their objectives and targets, you quickly become very attuned to what good looks like, and this is a huge benefit for your own career development.&lt;/p&gt;

&lt;p&gt;At an individual skill level, you're surrounded by and regularly meeting the people in your team who are used to showing you what they can do and showing off their skills. It's far from a one way street, and I am equally coached on my problems and challenges by my team. There is no better example here than my own continuing journey in backend web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  A safe place to try things
&lt;/h2&gt;

&lt;p&gt;The teams I've worked with have been wonderful at letting me try things out, they've not only been a safe space to get things wrong, they've also been amazingly honest at giving feedback and ideas - in many respects you represent your team, so they don't want you to look bad!&lt;/p&gt;

&lt;p&gt;My team have been on the receiving end of draft versions of pretty much everything I've delivered at Practice meetings or external conferences, and have always been completely on point with the feedback they've given - thank you!&lt;/p&gt;

&lt;h2&gt;
  
  
  People Management and individual team contribution are not mutually exclusive
&lt;/h2&gt;

&lt;p&gt;The last point I'd like to share is that I've never felt that being a people manager and being a contributor in a team have ever been mutually exclusive parts of my job. I have many examples of where people management conversations have helped me unblock stuff in my team assignments and vice versa. My delivery team (hopefully!) benefit from having me as a person, the combined engineer and people manager that I am, and from me bringing all my skills to the team.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Originally posted on &lt;a href="https://logical-progression.matttea.com"&gt;https://logical-progression.matttea.com&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>management</category>
      <category>people</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Containerising and Deploying with k8s</title>
      <dc:creator>Matt Thompson</dc:creator>
      <pubDate>Sat, 25 Jul 2020 15:55:18 +0000</pubDate>
      <link>https://dev.to/matttea/jib-gitlab-ci-and-the-kubernetes-cluster-5b7b</link>
      <guid>https://dev.to/matttea/jib-gitlab-ci-and-the-kubernetes-cluster-5b7b</guid>
      <description>&lt;p&gt;This started less an article or blog, more a journal of my many failed attempts at containerising and deploying a small app. I was keen to practice with the technologies I use every day, but without the guardrails of a fantastic platform team with all the tools and support they provide.&lt;/p&gt;

&lt;p&gt;The following describes the (eventual!) successful steps to...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Package a &lt;code&gt;Kotlin&lt;/code&gt; web application with environment secrets in a &lt;code&gt;Docker&lt;/code&gt; image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upload the image to a container registry, and run both manually and as part of a &lt;code&gt;CI build pipeline&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code&gt;Kubernetes&lt;/code&gt; (k8s) cluster and deploy the app, both manually and as part of the CI build pipeline&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expose the application to the internet&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code for the Tempo-Valence application used can be &lt;a href="https://gitlab.com/matt34Tea/tempo-valence"&gt;seen here&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Package app in a docker image
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Google Kubernetes Engine (GKE) accepts Docker images as the application deployment format.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using &lt;code&gt;gcr.io&lt;/code&gt; container registry (after failing with other registry providers - see out takes below!)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable &lt;code&gt;Cloud Registry API&lt;/code&gt; in Google Cloud Platform (GCP) console&lt;/li&gt;
&lt;li&gt;Set up Service Account in GCP &lt;code&gt;Service Accounts - IAM &amp;amp; Admin&lt;/code&gt; so that this can be used to access the Google container registry (gcr). This service account will need to have a &lt;code&gt;Storage Admin&lt;/code&gt; role&lt;/li&gt;
&lt;li&gt;Download &lt;code&gt;key&lt;/code&gt; from created GCP service account and add it to a gitlab-ci variable - called &lt;code&gt;GOOGLE_CREDENTIALS&lt;/code&gt; in my example, which is accessed in the gitlab-ci.yml file below&lt;/li&gt;
&lt;li&gt;(The key can also be saved to a local, non-committed keyfile somewhere if you wish to run the jib docker image locally to check)&lt;/li&gt;
&lt;li&gt;Update build step of &lt;code&gt;gitlab-ci.yml&lt;/code&gt; to...
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*gradle-image&lt;/span&gt;
    &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
    &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;CLIENT_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$CLIENT_KEY&lt;/span&gt;
        &lt;span class="na"&gt;GOOGLE_CREDENTIALS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$GOOGLE_CREDENTIALS&lt;/span&gt;
    &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "$GOOGLE_CREDENTIALS" &amp;gt; keyfile.json&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export CLIENT_KEY="$CLIENT_KEY"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gradle jib -Djib.console=plain&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gradle clean build&lt;/span&gt;
    &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;jib&lt;/code&gt; config in &lt;code&gt;build.gradle.kts&lt;/code&gt; of the project as follows...
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;jib&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;mainClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mainClassName&lt;/span&gt;
        &lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pair&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"CLIENT_KEY"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"CLIENT_KEY"&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
        &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"8000"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"openjdk:11"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"gcr.io/&amp;lt;gcp-project-name&amp;gt;/tempo-valence:latest"&lt;/span&gt;
        &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"_json_key"&lt;/span&gt;
            &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"keyfile.json"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;readText&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(The &lt;code&gt;CLIENT_KEY&lt;/code&gt; environment variable above refers to a secret env var required to access an external api from the application. The value of this env var is stored as a Variable in Gitlab CI so the pipeline can access to run the app.)&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Upload docker image to a container registry
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;See previous step&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To run locally...&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 9000:9000 gcr.io/&amp;lt;gcp-project-name&amp;gt;/tempo-valence:latest

&lt;span class="c"&gt;# in new terminal tab&lt;/span&gt;
curl http://localhost:9090
&lt;span class="c"&gt;# Welcome to TempoValence!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Create a k8s container cluster
&lt;/h2&gt;

&lt;p&gt;Following manual commands create cluster, deploy application and expose on an external IP&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud auth list

gcloud config &lt;span class="nb"&gt;set &lt;/span&gt;account m.........@gmail.com

gcloud config &lt;span class="nb"&gt;set &lt;/span&gt;project &amp;lt;gcp-project-name&amp;gt;

gcloud config &lt;span class="nb"&gt;set &lt;/span&gt;compute/zone europe-west2-a

gcloud container clusters create tempo-valence-cluster

gcloud compute instances list

kubectl create deployment tempo-valence &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gcr.io/&amp;lt;gcp-project-name&amp;gt;/tempo-valence:latest

kubectl get deployment

kubectl get pods

kubectl scale deployment tempo-valence &lt;span class="nt"&gt;--replicas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2

kubectl autoscale deployment tempo-valence &lt;span class="nt"&gt;--cpu-percent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80 &lt;span class="nt"&gt;--min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;--max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5

kubectl expose deployment tempo-valence &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tempo-valence-service &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;LoadBalancer &lt;span class="nt"&gt;--port&lt;/span&gt; 9000 &lt;span class="nt"&gt;--target-port&lt;/span&gt; 9000
&lt;span class="c"&gt;# the ports here matter - think it has something to do with how we've set up the application in the image&lt;/span&gt;

kubectl get service

&lt;span class="c"&gt;# and use the EXTERNAL_IP of tempo-valence-service to access, e.g...&lt;/span&gt;
http://35.234.150.122:9000/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Deploy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;See step 3 for manual deployment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In order to deploy from the gitlab-ci pipeline, the &lt;code&gt;gitlab-ci.yml&lt;/code&gt; looked like this for the deploy stage...&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;CI_SERVICE_ACCOUNT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$CI_SERVICE_ACCOUNT&lt;/span&gt;
&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kiwigrid/gcloud-kubectl-helm&lt;/span&gt;
&lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "$CI_SERVICE_ACCOUNT" &amp;gt; key.json&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gcloud auth activate-service-account --key-file=key.json&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gcloud config set project &amp;lt;gcp-project-name&amp;gt;&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gcloud config set container/cluster tempo-valence-cluster&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gcloud config set compute/zone europe-west2-a&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gcloud container clusters get-credentials tempo-valence-cluster --zone europe-west2-a&lt;/span&gt;
&lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;kubectl create deployment tempo-valence --image=gcr.io/&amp;lt;gcp-project-name&amp;gt;/tempo-valence:latest&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;kubectl expose deployment tempo-valence --name=tempo-valence-service --type=LoadBalancer --port 9000 --target-port &lt;/span&gt;&lt;span class="m"&gt;9000&lt;/span&gt;
    &lt;span class="c1"&gt;# Wait for the deployment to be applied&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;kubectl rollout status deployment tempo-valence --watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Few things to note here!
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Set up another service account in GCP, to be used by gitlab ci to authenticate against both the container registry and k8s cluster (may be possible just to amend the roles of previous service account, but I added a new one to keep it separate)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give the service account 2 project roles -&amp;gt; &lt;code&gt;Kubernetes Engine Developer&lt;/code&gt; and &lt;code&gt;Storage Object Admin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Download the key associated to the account and add in to a new CI variable in gitlab&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;image&lt;/code&gt; is the image used to run the deployment - bit of trial and error here, as this image needed to have both &lt;code&gt;kubectl&lt;/code&gt; and &lt;code&gt;gcloud&lt;/code&gt; cli tools loaded (and I couldn't be bothered to create one and store it somewhere that didn't need authentication!) The image included above is open and does the job.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For this to work, the &lt;code&gt;tempo-valence-cluster&lt;/code&gt; of course needs to be up and running &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;







&lt;h2&gt;
  
  
  Steps to run
&lt;/h2&gt;

&lt;p&gt;As this will not be continually running here are the steps needed before this will be available on the internet&lt;/p&gt;




&lt;h3&gt;
  
  
  To setup
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud container clusters create tempo-valence-cluster

&lt;span class="c"&gt;# Run ci pipeline, or...&lt;/span&gt;
kubectl create deployment tempo-valence &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gcr.io/&amp;lt;gcp-project-name&amp;gt;/tempo-valence:latest

kubectl scale deployment tempo-valence &lt;span class="nt"&gt;--replicas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2

kubectl autoscale deployment tempo-valence &lt;span class="nt"&gt;--cpu-percent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80 &lt;span class="nt"&gt;--min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;--max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5

kubectl expose deployment tempo-valence &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tempo-valence-service &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;LoadBalancer &lt;span class="nt"&gt;--port&lt;/span&gt; 9000 &lt;span class="nt"&gt;--target-port&lt;/span&gt; 9000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h3&gt;
  
  
  To teardown
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete service tempo-valence-service

gcloud container clusters delete tempo-valence-cluster
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;









&lt;h2&gt;
  
  
  Links and article credits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A lot of ideas from this &lt;a href="https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app"&gt;Google k8s tutorial&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And this &lt;a href="https://cloud.google.com/run/docs/quickstarts/build-and-deploy"&gt;GCP tutorial&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of our own from Matt Dowds on &lt;a href="https://medium.com/john-lewis-software-engineering/deploying-to-google-kubernetes-engine-from-gitlab-ci-feaf51dae0c1"&gt;Kubernetes deployment form Gitlab CI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;







&lt;h2&gt;
  
  
  Outtakes - my many failed attempts at step 1!
&lt;/h2&gt;

&lt;p&gt;Package app in a docker image&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Kubernetes Engine (GKE) accepts Docker images as the application deployment format. To build a Docker image, you need to have an application and a Dockerfile (in that application)&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;Dockerfile&lt;/code&gt; to root of project. 1st attempt looked like this...
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# use base image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; openjdk:11&lt;/span&gt;

&lt;span class="c"&gt;# set working directory&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /&lt;/span&gt;

&lt;span class="c"&gt;# copy the runlocal.sh file (contains env vars and gradle run command)&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; runlocal.sh .&lt;/span&gt;

&lt;span class="c"&gt;# Inform Docker that the container is listening on the specified port at runtime&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="c"&gt;#Run the specified command within the container&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;./runlocal.sh

&lt;span class="c"&gt;# Copy the rest of your app source code from your host to your image filesystem&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run the following command to build and test docker image locally...
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker image build &lt;span class="nt"&gt;-t&lt;/span&gt; tempo-valence:1.0 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Sadly this exited in error...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;Step 5/6 : RUN ./runlocal.sh
&lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;7d1ddc474a6f
./runlocal.sh: line 5: ./gradlew: No such file or directory
The &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="s1"&gt;'/bin/sh -c ./runlocal.sh'&lt;/span&gt; returned a non-zero code: 127
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;So next I tried working with a gradle base image...
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; gradle:5.4.1-jdk11 AS build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Gradle started, but sadly a config error was returned...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;FAILURE: Build failed with an exception.

&lt;span class="k"&gt;*&lt;/span&gt; What went wrong:
A problem occurred configuring root project &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then looked in to &lt;code&gt;--env-file&lt;/code&gt; and using other ways of getting the relevant client key into the image without exposing it. Finally added the env_var to a &lt;code&gt;.env&lt;/code&gt; file and accessed in &lt;code&gt;Dockerfile&lt;/code&gt; as follows...
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; openjdk:11&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; CLIENT_KEY .env&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This successfully builds and tags the image, but my concern is now that this &lt;code&gt;.env&lt;/code&gt; file is only available locally, as it is .gitignore'd&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running the image as a container using
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container run &lt;span class="nt"&gt;--publish&lt;/span&gt; 8000:8080 &lt;span class="nt"&gt;--detach&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; tv tempo-valence:1.0

&lt;span class="c"&gt;# --publish 8000:8080 asks Docker to forward traffic incoming on the host’s port 8000, to the container’s port 8080. Containers have their own private set of ports, so if you want to reach one from the network, you have to forward traffic to it in this way. Otherwise, firewall rules will prevent all network traffic from reaching your container, as default&lt;/span&gt;

&lt;span class="c"&gt;# --detach asks Docker to run this container in the background&lt;/span&gt;

&lt;span class="c"&gt;# --name specifies a name with which you can refer to your container in subsequent commands, in this case tv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;didn't run the app, as we have no current run command in the &lt;code&gt;Dockerfile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, added a couple of bits back in the &lt;code&gt;Dockerfile&lt;/code&gt;...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; gradle:5.4.1-jdk11&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; CLIENT_KEY $CLIENT_KEY&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; [ "gradle", "run" ]&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This successfully runs the container, but I cannot access the app via the browser on &lt;code&gt;http://localhost:8000&lt;/code&gt; as expected&lt;/p&gt;

&lt;p&gt;Some links being used so far...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/get-started/part2/"&gt;https://docs.docker.com/get-started/part2/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/docker/comments/7dhszj/dockercompose_how_do_i_expose_a_port_to_my/"&gt;https://www.reddit.com/r/docker/comments/7dhszj/dockercompose_how_do_i_expose_a_port_to_my/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some useful commands...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker exec tv env&lt;/code&gt; (lists env vars set in the container)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;New attempts... (13.03.20)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tried using &lt;a href="https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin"&gt;&lt;code&gt;jib&lt;/code&gt;&lt;/a&gt; to containerise the app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Added the following into &lt;code&gt;build.gradle&lt;/code&gt; file...&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'com.google.cloud.tools.jib'&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'2.1.0'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;jib&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;mainClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mainClassName&lt;/span&gt;
        &lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nl"&gt;CLIENT_KEY:&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"CLIENT_KEY"&lt;/span&gt;&lt;span class="o"&gt;)]&lt;/span&gt;
        &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'8000'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"openjdk:11"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"matttea/matttea-images/tempo-valence:latest"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run the following commands to build...
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CLIENT_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;client_key_value&amp;gt;

gradle jib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Returned error related to authentication...
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;Containerizing application to matttea/matttea-images/tempo-valence...
Base image &lt;span class="s1"&gt;'openjdk:11'&lt;/span&gt; does not use a specific image digest - build may not be reproducible
The credential helper &lt;span class="o"&gt;(&lt;/span&gt;docker-credential-desktop&lt;span class="o"&gt;)&lt;/span&gt; has nothing &lt;span class="k"&gt;for &lt;/span&gt;server URL: registry-1.docker.io

Got output:

credentials not found &lt;span class="k"&gt;in &lt;/span&gt;native keychain

...

FAILURE: Build failed with an exception.

&lt;span class="k"&gt;*&lt;/span&gt; What went wrong:
Execution failed &lt;span class="k"&gt;for &lt;/span&gt;task &lt;span class="s1"&gt;':jib'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: Build image failed, perhaps you should make sure your credentials &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s1"&gt;'registry-1.docker.io/matttea/matttea-images/tempo-valence'&lt;/span&gt; are &lt;span class="nb"&gt;set &lt;/span&gt;up correctly. See https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#what-should-i-do-when-the-registry-responds-with-unauthorized &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Using &lt;a href="https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#authentication-methods"&gt;this link&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;See also &lt;a href="https://github.com/mattTea/journal/blob/master/2020/03-March/2020-03-14.md"&gt;this journal entry on docker credentials helper&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;New attempts... (25.05.2020)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;tried changing job image to detail to &lt;code&gt;image  = "https://index.docker.io/v1//matttea/matttea-images/tempo-valence:latest"&lt;/code&gt; based on &lt;code&gt;docker logout&lt;/code&gt; command url response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;didn't work...&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Task :jib FAILED

FAILURE: Build failed with an exception.

&lt;span class="k"&gt;*&lt;/span&gt; What went wrong:
Execution failed &lt;span class="k"&gt;for &lt;/span&gt;task &lt;span class="s1"&gt;':jib'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Invalid image reference https://index.docker.io/v1//matttea/matttea-images/tempo-valence:latest, perhaps you should check that the reference is formatted correctly according to https://docs.docker.com/engine/reference/commandline/tag/#extended-description
For example, slash-separated name components cannot have uppercase letters
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(Originally posted on &lt;a href="https://logical-progression.matttea.com"&gt;https://logical-progression.matttea.com&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kubernetes</category>
      <category>ci</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
