Fahim Shariar Shoumik

Backend Engineer | Golang Specialist | Distributed Systems Architect

Dhaka, Bangladesh
Fahim Shariar Shoumik

About

Tech entrepreneur and backend specialist with 10+ years of experience building scalable systems using Golang, gRPC, and Docker-based microservices. Proven leadership in startups and developer platforms. Passionate about API-first design, plugin-based extensibility, and headless CMS architectures. Currently building Apito.io, an API development platform. Past projects include FHIR-compliant EHR systems, DevOps consulting, and open-source tooling.

Back to Blog

Continuous Integration of Golang with Gitlab Pipeline | পর্ব ১

GolangCI/CDGitLabDevOpsBengali

কিছুদিন আগে একটা প্রোজেক্টে মাইক্রোসার্ভিস নিয়ে গিয়েছিলাম—Go, ডকার, আর সার্ভিস সংখ্যা বাড়তে বাড়তে ম্যানুয়ালি বিল্ড আর পুশ আর টেকা যাচ্ছিল না। লক্ষ্য ছিল সরল: পুশ করলেই বাইনারি বিল্ড, ছোট ইমেজ বানানো, GitLab Registry-তে পুশ।

কেন GitLab Pipeline?

GitLabে পাইপলাইন + রেজিস্ট্রি এক জায়গায়—প্রাইভেট ডকার রেজিস্ট্রি বিনামূল্যে লেয়ারটা তখন অনেক জায়গায় ছিল না। পাইপলাইন এনভায়রনমেন্ট ডকার-ভিত্তিক; ডকার কেন লাগে সেটা আগের লেখায়: /blog/docker-ki-part-1

Shared Runner দিয়ে সহজ জব চলে; কিন্তু আমাদের কেসে লাগছিল নিজের রানার—বিশেষ করে Docker-in-Docker / socket শেয়ারিং যেটা শেয়ার্ড রানারে তখন যথেষ্ট নমনীয় ছিল না। তাই একটা ছোট VPS (1 vCPU, 1 GB RAM ক্লাস) এ GitLab Runner বসানো।

রানার রেজিস্টার

রিপোতে CI/CD চালু করে Settings → CI/CD → Runners থেকে registration token নিলেই হয়। VPS-এ:

sudo gitlab-runner register -n \
  --url https://gitlab.com/ \
  --registration-token CI_RUNNER_TOKEN \
  --executor docker \
  --description "Docker Runner Vultr (Rancher)" \
  --docker-image "docker:latest" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

CI_RUNNER_TOKEN-এর জায়গায় তোমার টোকেন। এরপর প্রোজেক্টে Runners activated দেখা যাবে।

.gitlab-ci.yml (সেই সময়ের সেটআপ)

নিচেরটা ঐতিহাসিক স্ন্যাপশট—Glide আজকের Go modules যুগে পুরনো; তবু ধারণা একই: বিল্ড স্টেজ, তারপর ডকার বিল্ড/পুশ।

image: restra/golang-docker-gitlabci

variables:
  DOCKER_REPO: registry.gitlab.com
  MAIN_IMAGE_NAME: sh0umik/golang-gitlab-ci

services:
  - docker:dind

stages:
  - build
  - upgrade

before_script:
  - mkdir -p /go/src/gitlab.com/sh0umik/golang-gitlab-ci
  - cp -r . /go/src/gitlab.com/sh0umik/golang-gitlab-ci
  - cd /go/src/gitlab.com/sh0umik/golang-gitlab-ci

build:
  stage: build
  script:
    - glide up
    - CGO_ENABLED=0 GOOS=linux go build -ldflags "-s" -a -installsuffix cgo .
    - docker login -u fahim.shoumik -p $ACCESS_TOKEN $DOCKER_REPO
    - docker build -t $DOCKER_REPO/$MAIN_IMAGE_NAME:latest .
    - docker build -t $DOCKER_REPO/$MAIN_IMAGE_NAME:$CI_COMMIT_REF_NAME .
    - docker push $DOCKER_REPO/$MAIN_IMAGE_NAME:latest
    - docker push $DOCKER_REPO/$MAIN_IMAGE_NAME:$CI_COMMIT_REF_NAME

upgrade:
  stage: upgrade
  script:
    - echo "upgrade here"
  • বেস ইমেজ — Go + Docker এক কনটেইনারে, যাতে কম্পাইল আর docker build এক পাইপলাইনে।
  • docker:dind — ইন-জব ডকার ডেমন।
  • CGO_ENABLED=0 … go build — স্ট্যাটিক লিনাক্স বাইনারি (কপি-পেস্টে GO_ENABLED লিখলে কাজ করবে না—এটাই সঠিক ভেরিয়েবল)।
  • $ACCESS_TOKEN — রেজিস্ট্রি লগইন; GitLab Settings → Access token থেকে সিক্রেট হিসেবে সেট করতে হয়।

পুশ করলে পাইপলাইন দৌড়ায়; লগে ইমেজ ডাউনলোড, স্ক্রিপ্ট, Job succeeded দেখলে ঠিক আছে।

রেজিস্ট্রিতে latest আর ব্রাঞ্চ-ট্যাগ দুটোই থাকে।

ছোট ইমেজ = একটা মাইক্রোসার্ভিস আর্টিফ্যাক্ট—কিন্তু প্রোডে আরও লাগে অবজারভেবিলিটি, সিকিউরিটি স্ক্যান, রোলআউট—সেটা অন্য গল্প।

আজকে আমি কী করতাম?

go mod, অফিসিয়াল golang ইমেজ, কোনো পাবলিক restra/... নির্ভরতা কমিয়ে, টোকেন কখনো YAML-এ হার্ডকোড না—শুধু CI ভেরিয়েবল। GitLab-এর UI আর runner UX তখন থেকে এগিয়েছে; মূল প্যাটার্ন অপরিবর্তিত: রানার তোমার, পাইপলাইন তোমার নিয়ম

রেপো (রেফারেন্স): https://gitlab.com/sh0umik/golang-gitlab-ci/