<?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>Forem: Dima</title>
    <description>The latest articles on Forem by Dima (@dimot9).</description>
    <link>https://forem.com/dimot9</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%2F389231%2Fc7edcffa-196c-4f51-af09-ea55f2bc44cc.png</url>
      <title>Forem: Dima</title>
      <link>https://forem.com/dimot9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dimot9"/>
    <language>en</language>
    <item>
      <title>Jak jsem si za pár večerů postavil nástroj na ověření názvu projektu</title>
      <dc:creator>Dima</dc:creator>
      <pubDate>Wed, 28 Jan 2026 17:35:53 +0000</pubDate>
      <link>https://forem.com/dimot9/jak-jsem-si-za-par-veceru-postavil-nastroj-na-overeni-nazvu-projektu-309p</link>
      <guid>https://forem.com/dimot9/jak-jsem-si-za-par-veceru-postavil-nastroj-na-overeni-nazvu-projektu-309p</guid>
      <description>&lt;p&gt;&lt;em&gt;Tento článek byl původně publikovaný na &lt;a href="https://medium.com/@dimot9/jak-jsem-si-za-p%C3%A1r-ve%C4%8Der%C5%AF-postavil-n%C3%A1stroj-na-ov%C4%9B%C5%99en%C3%AD-n%C3%A1zvu-projektu-38e36a0c29a1" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Postavil jsem si jednoduchý nástroj, který řeší jeden konkrétní problém – ověření dostupnosti názvu projektu na víc platformách najednou.&lt;/p&gt;

&lt;p&gt;Zaměřuju se na český trh (ARES, české platformy), ale proces budování by mohl být zajímavý pro kohokoliv, kdo dělá side project s nulovým rozpočtem.&lt;/p&gt;

&lt;p&gt;Tady je příběh, jak to vzniklo.&lt;/p&gt;




&lt;p&gt;Pokaždé, když začínám nový projekt, řeším to samé — je název volný? A nemyslím jen doménu. Myslím všechno: obchodní rejstřík, .cz, .com, sociální sítě, platformy kde chci být.&lt;/p&gt;

&lt;p&gt;Obvykle to vypadá takhle: otevřu ARES, zadám název. Pak některýho z doménových registrátorů, oveřím volné koncovky. Pak Instagram, LinkedIn, případně další platformy podle typu projektu. Celý proces zabere klidně 30 minut. A to jen pro jeden název. Když testuji víc variant, násobí se to.&lt;/p&gt;

&lt;p&gt;Po několikáté jsem si řekl: tohle musí jít udělat líp.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scratch your own itch
&lt;/h3&gt;

&lt;p&gt;Vzniklo Seberio — jednoduchý nástroj, kam zadáte název jednou a hned vidíte, kde je volný a kde ne.&lt;/p&gt;

&lt;p&gt;Momentálně kontroluje:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ARES&lt;/strong&gt; (obchodní rejstřík) — jestli podobná firma už neexistuje&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domény&lt;/strong&gt;  — .cz, .com, .eu&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flixy.cz&lt;/strong&gt;  — pro ty, kdo prodávají digitální produkty a potřebují název obchodu&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sociální sítě&lt;/strong&gt;  — LinkedIn, YouTube&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Proč lokální trh?
&lt;/h3&gt;

&lt;p&gt;Existují globální nástroje na kontrolu názvů — Namechk, Knowem a podobné. Jenže žádný z nich neřeší česká specifika. ARES nikde nenajdete. Flixy taky ne. A přitom právě tahle lokální kontrola je pro českého podnikatele nebo freelancera často nejdůležitější.&lt;/p&gt;

&lt;p&gt;Rozhodl jsem se zaměřit na jeden trh a udělat to pořádně, místo aby nástroj uměl všechno polovičatě.&lt;/p&gt;

&lt;h3&gt;
  
  
  Jak to vzniklo
&lt;/h3&gt;

&lt;p&gt;Seberio je side project. Dělám ho ve volném čase vedle svého hlavního jobu, kde působím jako tech leader v HR startupu TRIBEE.&lt;/p&gt;

&lt;p&gt;Pro vývoj hodně využívám Claude Code v kombinaci se Zed editorem. Rutinní práci — psaní boilerplate kódu, základní implementace — deleguji na AI. Já pak vymýšlím, kontroluji a upravuji. Tahle workflow mi ušetřila spoustu času a umožnila dotáhnout projekt do použitelného stavu během pár večerů.&lt;/p&gt;

&lt;p&gt;Tech stack je jednoduchý: Astro a Cloudflare pro infra.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fak8pg3js2vzk3rueovk4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fak8pg3js2vzk3rueovk4.png" alt="Screenshot z webu Seberio.cz" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot z webu Seberio.cz&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Co jsem se zatím naučil
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lokální trh není nevýhoda&lt;/strong&gt;
Zpočátku jsem měl pocit, že dělat něco jen pro Česko je omezující. Ale právě díky tomu mám jasnou výhodu — nikdo jiný tohle neřeší. Menší trh znamená menší konkurenci a jasnější positioning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-budget marketing je pomalý, ale funguje&lt;/strong&gt;
Nemám rozpočet na reklamu. Spoléhám na SEO, občasné posty na Threads a teď i články tady na Medium. Roste to pomalu, ale organicky. A hlavně — lidi, kteří přijdou, jsou relevantní.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nejdřív doručit, pak vylepšovat&lt;/strong&gt;
Původně jsem chtěl mít všechno hotové — sociální sítě, pokročilé filtrování, hezčí UI. Nakonec jsem to vypustil s tím, co bylo funkční. Lepší live a nedokonalé než dokonalé v šuplíku.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Co dál
&lt;/h3&gt;

&lt;p&gt;V nejbližší době chci rozšířit kontrolu od další sociální sítě — Facebook, Instagram, případně další. Přidat návrh alternativních názvů. A průběžně vylepšovat na základě feedbacku od uživatelů.&lt;/p&gt;

&lt;p&gt;Jestli zrovna řešíte název pro firmu, projekt nebo e-shop, zkuste to:&lt;br&gt;&lt;br&gt;
&lt;a href="https://seberio.cz" rel="noopener noreferrer"&gt;seberio.cz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A pokud máte zpětnou vazbu nebo nápady co přidat, napište mi na &lt;a href="https://threads.net/@dimot9" rel="noopener noreferrer"&gt;Threads&lt;/a&gt; nebo tady. ✌️&lt;/p&gt;

</description>
      <category>sideprojects</category>
      <category>czechrepublic</category>
      <category>startup</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>Nuxt Tailwind Breakpoint Helper</title>
      <dc:creator>Dima</dc:creator>
      <pubDate>Mon, 15 Mar 2021 14:42:25 +0000</pubDate>
      <link>https://forem.com/dasher/nuxt-tailwind-breakpoint-helper-2a62</link>
      <guid>https://forem.com/dasher/nuxt-tailwind-breakpoint-helper-2a62</guid>
      <description>&lt;p&gt;In &lt;em&gt;Dasher&lt;/em&gt; we do a lot of web front-end. We use &lt;strong&gt;Vue, Nuxt and Tailwind CSS&lt;/strong&gt; for it. We really love fast prototyping and quality outputs. We wanted to make our development experience even more enjoyable and effective ⚡.&lt;/p&gt;

&lt;p&gt;Further, I will write why we created our small and really simple module &lt;a href="https://www.npmjs.com/package/@dashers/nuxt-tailwind-breakpoint-helper" rel="noopener noreferrer"&gt;&lt;strong&gt;Nuxt Tailwind breakpoint helper&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Once upon a time
&lt;/h1&gt;

&lt;p&gt;Our front-end developer, while testing responsive Vue component in a browser, said that he would like to see current screen size, which is defined in Tailwind config file.&lt;/p&gt;

&lt;p&gt;As you know, when you change screen size in an inspect mode in a browser you see real viewport size in pixels. But when you write responsive styles in Tailwind it looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-w-full sm:max-w-md md:max-w-2xl"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;paragraph...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you see &lt;code&gt;sm&lt;/code&gt; (min-width: 640px) and &lt;code&gt;md&lt;/code&gt; (min-width: 768px) screen sizes, which are defaults in &lt;a href="https://tailwindcss.com/docs/breakpoints" rel="noopener noreferrer"&gt;Tailwind config&lt;/a&gt;. But you can re-write them or extend to have your own values such as &lt;code&gt;super-extra-big-screen-size&lt;/code&gt; and it could have value &lt;code&gt;min-width: 4000px&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Lot of us have some issues with a memory (now I mean human memory 🧠). There are times when we can't quite remember if &lt;code&gt;md&lt;/code&gt; screen size starts from 768px or some other value, &lt;strong&gt;but we want to see which Tailwind screen size is applied right now.&lt;/strong&gt; Also, we don't want to open inspect mode everytime.&lt;/p&gt;

&lt;h1&gt;
  
  
  How we helped ourselves
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgitlab.com%2Fdashers%2Fpublic%2Fbreakpoint-helper%2F-%2Fraw%2Fmaster%2Fpublic%2Fimages%2Fexample2.gif%3Fv1" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgitlab.com%2Fdashers%2Fpublic%2Fbreakpoint-helper%2F-%2Fraw%2Fmaster%2Fpublic%2Fimages%2Fexample2.gif%3Fv1" alt="NTBH gif example" width="760" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created our own NuxtJS module, which embeds a small "widget" to the left bottom corner of a browser's viewport and shows current Tailwind screen size (sm, md,...) and actual viewport height and width in pixels. Module is injected only in development mode. You can also style it as you need using module options in &lt;code&gt;nuxt.config.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, we can debug and tune up our components even faster and have an actual Tailwind screen size everytime!&lt;/p&gt;

&lt;h1&gt;
  
  
  In the end
&lt;/h1&gt;

&lt;p&gt;We would appreciate any comments, feedback or contribution to the module if you want to use it, but missing something ✌.&lt;/p&gt;

&lt;p&gt;Thanks for reading! The Dasher Team ⚡&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;a href="https://www.npmjs.com/package/@dashers/nuxt-tailwind-breakpoint-helper" rel="noopener noreferrer"&gt;NPM package of the module&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://gitlab.com/dashers/public/breakpoint-helper" rel="noopener noreferrer"&gt;Gitlab Repo of the module&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://www.dasher.cz/" rel="noopener noreferrer"&gt;Dasher website&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nuxt</category>
      <category>tailwindcss</category>
      <category>package</category>
      <category>dx</category>
    </item>
    <item>
      <title>Go, Docker and Gitlab easy config</title>
      <dc:creator>Dima</dc:creator>
      <pubDate>Tue, 22 Sep 2020 20:50:33 +0000</pubDate>
      <link>https://forem.com/dimot9/go-docker-and-gitlab-easy-config-20be</link>
      <guid>https://forem.com/dimot9/go-docker-and-gitlab-easy-config-20be</guid>
      <description>&lt;h1&gt;
  
  
  What it is about?
&lt;/h1&gt;

&lt;p&gt;I've started to learn Go language few days ago, because of one service that I needed to prepare for one project. The service is about some image processing and delivery as static server. I'm gonna write short case study about this service later too. 👌&lt;/p&gt;

&lt;p&gt;As I am a fan of containers I put development environment in Docker containers. I like Go language a lot and was able to write MVP really fast. When I was done I decided to get some inspiration about publishing Docker image of my app using Gitlab CI. To get some best practices or caveats maybe. &lt;/p&gt;

&lt;p&gt;And I was really surprised how complicated (or outdated) configs I found.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fozx8fvgw06iwxhv070fy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fozx8fvgw06iwxhv070fy.gif" alt="Alt Text" width="275" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I thought why I'm loosing time with those? The app is running in Docker container so I don't need to make platform-specific builds, inject ENVs to Gitlab PATH or other similar weird things...&lt;/p&gt;

&lt;p&gt;I wrote it for myself and gonna show it here. I hope it will be useful for those who are interested in Go, Docker or microservices. ✌️&lt;/p&gt;

&lt;h1&gt;
  
  
  Simple Go app in Docker
&lt;/h1&gt;

&lt;p&gt;I assume you guys have some basic knowledge about Docker or &lt;em&gt;containerization&lt;/em&gt; as a whole at least. But I think many of you beginners will manage too. 💪&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Firstly, I will show project stucture so you get the context.&lt;/li&gt;
&lt;li&gt;Then I'm going to write how I prepared development docker environment for Go app.&lt;/li&gt;
&lt;li&gt;Finally I will demonstrate building production Go app docker image using Gitlab CI.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;

&lt;p&gt;Don't get me wrong, this structure is one out of thousands. And I'm not saying it's the best one or one that you should use. I just got used to this so I'm using it almost everywhere.&lt;/p&gt;

&lt;p&gt;It will just get you to configuration files context, so that you know where the paths come from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
├── bin &lt;span class="c"&gt;# helper docker-compose scripts&lt;/span&gt;
│   ├── build
│   ├── go
│   └── start
├── dev-ops
│   ├── dev.Dockerfile
│   ├── docker-compose.yml
│   └── prod.Dockerfile
├── README.md
└── &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="c"&gt;# go source files&lt;/span&gt;
    ├── crop.go
    ├── delivery.go
    ├── go.mod
    ├── go.sum
    ├── main.go
    └── vendor &lt;span class="c"&gt;# app's go dependencies source files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Go development in Docker
&lt;/h2&gt;

&lt;p&gt;We need to prepare dev image of our app.&lt;/p&gt;

&lt;p&gt;I build it from &lt;a href="https://hub.docker.com/_/golang?tab=description" rel="noopener noreferrer"&gt;golang alpine image&lt;/a&gt;, which is lighter and has everything I need.&lt;/p&gt;

&lt;p&gt;You can see &lt;code&gt;watcher&lt;/code&gt; command there. Watcher is a tool, as name says, that watches &lt;code&gt;.go&lt;/code&gt; file changes and builds code when change detected. So we don't have to do it manually in terminal each time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;## ./dev-ops/dev.Dockerfile&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; golang:1.15-alpine3.12&lt;/span&gt;

&lt;span class="c"&gt;## Make app dir for source files&lt;/span&gt;
&lt;span class="c"&gt;## Get git binary so that GO can download dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; /app &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk add git

&lt;span class="c"&gt;## Set app folder as work directory (default context in Docker container)&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;## get and install watcher&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go get github.com/canthefason/go-watcher &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/canthefason/go-watcher/cmd/watcher

&lt;span class="c"&gt;## Turn on Go modules, it allows easier dependency managment&lt;/span&gt;
&lt;span class="c"&gt;## Copy files with modules (dependencies) requirements, so that GO knows what to download&lt;/span&gt;
&lt;span class="c"&gt;## Reminds me package.json and yarn.lock in JS development&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; GO111MODULE=on&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; ./source/go.mod /app&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; ./source/go.sum /app&lt;/span&gt;

&lt;span class="c"&gt;## pull in all modules (dependencies)&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go mod download

&lt;span class="c"&gt;## Add source files to image work directory&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; ./source /app&lt;/span&gt;

&lt;span class="c"&gt;## Command which applies when container from this image runs&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["watcher"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also plenty of similar Go tools like Watcher. For example Gin or Fresh. Or you can also use Nodemon (for those who came from JS environment 🙂)&lt;/p&gt;

&lt;p&gt;And there is docker-compose file for running Docker container with our Go app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;## ./dev-ops/docker-compose.yml&lt;/span&gt;

&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;## ids is image delivery service (the service I wrote)&lt;/span&gt;
  &lt;span class="na"&gt;ids&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;## name of our image built from dev.Dockerfile above&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;registry.gitlab.com/dashers/image-delivery-service/ids:dev&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dasher_ids&lt;/span&gt;
    &lt;span class="c1"&gt;## sync your local source files with those in container&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;../source/:/app/&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Go production in Docker &amp;amp; Gitlab CI
&lt;/h2&gt;

&lt;p&gt;Now we prepare production Docker image.&lt;/p&gt;

&lt;p&gt;Again it's built from golang alpine image for same reasons as before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;## ./dev-ops/prod.Dockerfile&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; golang:1.15-alpine3.12&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add git

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /go/src/gitlab.com/dashers/image-delivery-service&lt;/span&gt;

&lt;span class="c"&gt;## same as in dev... add files with dependencies requierments&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; GO111MODULE=on&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; ./go.mod .&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; ./go.sum .&lt;/span&gt;

&lt;span class="c"&gt;## pull in any dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go mod download

&lt;span class="c"&gt;## add source files&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;## our app will now successfully build with the necessary go dependencies included&lt;/span&gt;
&lt;span class="c"&gt;## creates ./main binary executable file&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go build &lt;span class="nt"&gt;-o&lt;/span&gt; main .

&lt;span class="c"&gt;## runs our newly created binary executable&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["./main"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy right? Let's look at gitlab ci config.&lt;/p&gt;

&lt;p&gt;I'm showing here just one stage - &lt;strong&gt;BUILD and PUBLISH&lt;/strong&gt;. It builds our &lt;code&gt;prod.Dockerfile&lt;/code&gt; and publishes image to Gitlab container registry, where it will be available for pull.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;## ./gitlab-ci.yml&lt;/span&gt;

&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker:stable&lt;/span&gt;

&lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# SET DEFAULT BEHAVIOR FOR CI&lt;/span&gt;
  &lt;span class="c1"&gt;# Disable submodules on CI, we are not using submodules&lt;/span&gt;
  &lt;span class="na"&gt;GIT_SUBMODULE_STRATEGY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&lt;/span&gt;
&lt;span class="c1"&gt;# important! we need to say gitlab that we run docker container in docker container..&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker:dind&lt;/span&gt;

&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BUILD and PUBLISH&lt;/span&gt;

&lt;span class="c1"&gt;## template for build and publish stage&lt;/span&gt;
&lt;span class="na"&gt;.build-and-publish_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;build-and-publish_template&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 and PUBLISH&lt;/span&gt;
  &lt;span class="c1"&gt;## I version project using commit tags. &lt;/span&gt;
  &lt;span class="c1"&gt;## Here I say I want to trigger the stage only if commit tag has format ids-x.x.x&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$CI_COMMIT_TAG =~ /^(ids)-[0-9]+\.[0-9]+\.[0-9]+$/&lt;/span&gt;
      &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;never&lt;/span&gt;    
  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# accept ids-0.0.1 =&amp;gt; 0.0.1 | master =&amp;gt; master&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;VERSION=$(if [ "$CI_COMMIT_TAG" == "" ]; then echo $CI_COMMIT_REF_NAME; else echo $CI_COMMIT_TAG |awk -F- '{print $2}'; fi)&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo $VERSION&lt;/span&gt;
        &lt;span class="s"&gt;# login to gitlab container registry&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo -n $CI_REGISTRY_PASSWORD | docker login --username $CI_REGISTRY_USER --password-stdin $CI_REGISTRY&lt;/span&gt;
  &lt;span class="na"&gt;after_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# clean up&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker logout $CI_REGISTRY&lt;/span&gt;

&lt;span class="c1"&gt;## build and publish stage (using the template above)&lt;/span&gt;
&lt;span class="na"&gt;ids - build and publish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*build-and-publish_template&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# build our production image (prod.Dockerfile)&lt;/span&gt;
    &lt;span class="c1"&gt;# registry.gitlab.com/dashers/image-delivery-service/ids:x.x.x&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;docker build \&lt;/span&gt;
        &lt;span class="s"&gt;--network host \&lt;/span&gt;
        &lt;span class="s"&gt;--tag ${CI_REGISTRY}/dashers/image-delivery-service/ids:${VERSION} \&lt;/span&gt;
        &lt;span class="s"&gt;--file ${CI_PROJECT_DIR}/dev-ops/prod.Dockerfile \&lt;/span&gt;
        &lt;span class="s"&gt;--rm \&lt;/span&gt;
        &lt;span class="s"&gt;${CI_PROJECT_DIR}/source&lt;/span&gt;

    &lt;span class="c1"&gt;# publish into docker registry&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker push ${CI_REGISTRY}/dashers/image-delivery-service/ids:${VERSION}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! 🎉&lt;/p&gt;

&lt;p&gt;Now you can create docker-compose similar to that I've shown you (just without volume section) in your production server, use image from gitlab registry, run container and your Go app is ready and running.&lt;/p&gt;

&lt;p&gt;If you want to see the whole project's configuration or maybe even use our service, you can find it in our Gitlab repo &lt;a href="https://gitlab.com/dashers/image-delivery-service" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Feel free to comment, feedback or question ✌️&lt;/p&gt;

&lt;p&gt;Have a nice day!&lt;/p&gt;

</description>
      <category>go</category>
      <category>docker</category>
      <category>gitlab</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
