A simple Go web application that serves a "Hello from Go!" message. This project includes Dockerization, Kubernetes deployment manifests for dev and prod environments, and a GitLab CI/CD pipeline with automated testing and deployment.
k8s-project
├── main.go
├── Dockerfile
├── test.sh
├── gitlab-ci.yml
├── .gitignore
├── .dockerignore
├── test/
│ └── gitlab-test.yml
├── k8s/
│ ├── dev/
│ │ ├── ConfigMap.yaml
│ │ ├── Service.yaml
│ │ ├── Deployment.yaml
│ │ └── Ingress.yaml
│ └── prod/
│ ├── ConfigMap.yaml
│ ├── Service.yaml
│ ├── Deployment.yaml
│ └── Ingress.yaml
└── README.md
Before you begin, ensure you have the following:
- A GitLab account and project repository.
- Access to a private Docker registry (e.g., Nexus, Harbor) at
docker.registry.local. - A Kubernetes cluster with
kubectlconfigured. - GitLab CI/CD variables set:
NEXUS_USER: Username for Docker registry.NEXUS_PASSWORD: Password for Docker registry.KUBE_CONFIG: Base64-encoded kubeconfig file for cluster access.
You can set these variables in GitLab > Settings > CI/CD > Variables.
Since your images are pushed to a private registry (docker.registry.local), you must configure containerd on all Kubernetes worker nodes to trust this registry.
On each worker node, edit /etc/containerd/config.toml:
sudo vim /etc/containerd/config.toml[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
Then create this directory
mkdir /etc/containerd/certs.d
In there you will always need a new directory for every registry that you want to mirror. Examples would be registry.k8s.io or docker.io.
mkdir /etc/containerd/certs.d/registry.k8s.io
mkdir /etc/containerd/certs.d/docker.io
In this directory you need to create a hosts.toml with the following content
[host."http://docker.registry.local"]
capabilities = ["pull", "resolve"]kubectl create secret docker-registry regcred \
--docker-server=docker.registry.local \
--docker-username=$NEXUS_USER \
--docker-password=$NEXUS_PASSWORD \
--docker-email=your-email@example.com \
-n dev
kubectl create secret docker-registry regcred \
--docker-server=docker.registry.local \
--docker-username=$NEXUS_USER \
--docker-password=$NEXUS_PASSWORD \
--docker-email=your-email@example.com \
-n prodAdd imagePullSecrets to Your Deployments:
Update your k8s/dev/Deployment.yaml and k8s/prod/Deployment.yaml files to include:
spec:
template:
spec:
imagePullSecrets:
- name: regcredStep 2: Restart containerd
sudo systemctl restart containerd- Make sure you have Go installed (
go version). - Run the test script:
chmod +x test.sh
./test.shThis will start the Go server locally on port 80 and verify it returns "Hello from Go!".
kubectl apply -f k8s/dev/kubectl apply -f k8s/prod/Ensure namespaces
devandprodexist:
kubectl create namespace dev
kubectl create namespace prodThe pipeline has 5 stages:
| Stage | Description | Trigger Condition |
|---|---|---|
build_dev |
Builds and pushes image tagged with $CI_PIPELINE_ID |
On dev branch |
test |
Runs unit/integration tests via test/gitlab-test.yml |
On dev, master, tags |
deploy_dev |
Deploys to dev namespace |
On dev branch |
build_prod |
Builds and pushes image tagged with $CI_COMMIT_TAG |
On master or tags |
deploy_prod |
Deploys to prod namespace (manual trigger) |
On tags only |
- Every commit to the
devbranch triggers:- Build → Test → Deploy to
devnamespace.
- Build → Test → Deploy to
- Create a Git tag (e.g.,
v1.0.0) and push it:
git tag v1.0.0
git push origin v1.0.0- In GitLab, go to CI/CD > Pipelines, find the pipeline for the tag, and manually trigger the
deploy_prodjob.
- All Docker images are pushed to the private registry:
docker.registry.local/go-k8s-project:<tag>. - The
teststage is modular and defined intest/gitlab-test.yml(as requested).