Deploying GitLab on a Kubernetes Cluster

Environment Setup

  • Kubernetes cluster (e.g., Alibaba Cloud Professional Edition)
  • PostgreSQL database
  • Redis cache service
  • GitLab application

For PostgreSQL and Redis deployments, refer to relevant documentation.

GitLab Deployment

Version: GitLab Chinese Edition 11.1.4

GitLab is a stateless application, but its repositories, configuration, and other files require persistent storage. The container directoreis used are:

/home/git/data
/etc/gitlab/
/var/opt/gitlab
/var/log/gitlab (optional)

Create the deployment manifest file gitlab.yaml. PersistentVolumeClaims (PVCs) such as datadir-gitlab must be pre-created; this example uses Alibaba Cloud NAS as the storage backend. When configuring GitLab, replace example.com with your actual domain. Adjust email settings as needed. The SSH port is exposed as a NodePort (32222) and can be routed through a LoadBalancer on port 22.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: datadir-gitlab
  namespace: gitlab-cicd
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nas
  resources:
    requests:
      storage: 50Gi
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: gitlab
  namespace: gitlab-cicd
  labels:
    name: gitlab
spec:
  replicas: 1
  template:
    metadata:
      name: gitlab
      labels:
        name: gitlab
    spec:
      containers:
      - name: gitlab
        image: twang2218/gitlab-ce-zh:11.1.4
        imagePullPolicy: IfNotPresent
        env:
        - name: TZ
          value: Asia/Shanghai
        - name: GITLAB_TIMEZONE
          value: Beijing
        - name: GITLAB_SECRETS_DB_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_SECRETS_SECRET_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_SECRETS_OTP_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_ROOT_PASSWORD
          value: admin123456
        - name: GITLAB_ROOT_EMAIL
          value: xxx@xx.com
        - name: GITLAB_HOST
          value: xxx.example.com
        - name: GITLAB_PORT
          value: "80"
        - name: GITLAB_SSH_PORT
          value: "22"
        - name: GITLAB_NOTIFY_ON_BROKEN_BUILDS
          value: "true"
        - name: GITLAB_NOTIFY_PUSHER
          value: "false"
        - name: GITLAB_BACKUP_SCHEDULE
          value: daily
        - name: GITLAB_BACKUP_TIME
          value: 01:00
        - name: GITLAB_OMNIBUS_CONFIG
          value: |
            ## time_zone
            gitlab_rails['time_zone'] = 'Asia/Shanghai'
            ## postgres
            postgresql['enable'] = false
            gitlab_rails['db_adapter'] = "postgresql"
            gitlab_rails['db_encoding'] = "utf-8"
            gitlab_rails['db_database'] = "gitlab"
            gitlab_rails['db_username'] = "postgres"
            gitlab_rails['db_password'] = "xxx"
            gitlab_rails['db_host'] = "postgres-svc"
            gitlab_rails['db_port'] = 5432
            ## redis
            redis['enable'] = false
            gitlab_rails['redis_host'] = "redis"
            gitlab_rails['redis_port'] = 6379
            gitlab_rails['redis_database'] = 0
            ## pages
            pages_external_url "http://page.example.com/"
            gitlab_pages['enable'] = true
            gitlab_rails['pages_path'] = "/var/opt/gitlab/pages"
            gitlab_pages['external_http'] = ['1.1.1.2:80']
            ## gitlab ssh,http clone url, defaults to hostname
            external_url "http://gitlab.example.com/"
            ## email setting
            gitlab_rails['smtp_enable'] = true
            gitlab_rails['smtp_address'] = "smtp.qq.com"
            gitlab_rails['smtp_port'] = 465
            gitlab_rails['smtp_user_name'] = "xxx@xx.com"
            gitlab_rails['smtp_password'] = "xxx"
            gitlab_rails['smtp_authentication'] = "login"
            gitlab_rails['smtp_enable_starttls_auto'] = true
            gitlab_rails['smtp_tls'] = true
            gitlab_rails['gitlab_email_from'] = 'xx@xx.com'
            gitlab_rails['smtp_domain'] = "smtp.qq.com"
            postgresql['enable'] = false
            postgres_exporter['enable'] = false
            redis['enable'] = false
            prometheus['enable'] = false
            alertmanager['enable'] = false
            node_exporter['enable'] = false
            redis_exporter['enable'] = false
            prometheus_monitoring['enable'] = false
        ports:
        - name: http
          containerPort: 80
        - name: ssh
          containerPort: 22
        volumeMounts:
        - mountPath: /home/git/data
          name: data
        - mountPath: /etc/gitlab
          name: etc-gitlab
        - mountPath: /var/opt/gitlab    
          name: opt-gitlab
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 900
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
      volumes:
      - name: data
        persistentVolumeClaim:
            claimName: datadir-gitlab
      - name: etc-gitlab
        persistentVolumeClaim:
            claimName: etc-gitlab
      - name: opt-gitlab
        persistentVolumeClaim:
            claimName: opt-gitlab
---
apiVersion: v1
kind: Service
metadata:
  name: gitlab
  namespace: gitlab-cicd
  labels:
    name: gitlab
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: ssh
      port: 22
      targetPort: ssh
      nodePort: 32222
  selector:
    name: gitlab
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gitlab
  namespace: gitlab-cicd
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
spec:
  rules:
  - host: gitlab.example.com
    http:
      paths:
      - backend:
          serviceName: gitlab
          servicePort: http
        path: /

Note: Ensure the data services (PostgreSQL and Redis) are deployed before applying this manifest. Service endpoints can be referenced using the format svc-name.namespace.svc. Modify database credentials as needed.

Apply the deployment:

$ kubectl apply -f gitlab.yaml
persistentvolumeclaim/datadir-gitlab configured
deployment.apps/gitlab configured
service/gitlab configured
ingress.extensions/gitlab configured

Check Pod status:

$ kubectl get pod -n gitlab-cicd
NAME                              READY   STATUS    RESTARTS   AGE
gitlab-54548c6969-ghvff           1/1     Running   0          2h
gitlab-ci-runner-0                1/1     Running   0          2h
gitlab-ci-runner-1                1/1     Running   0          2h
redis-8477595b9c-qh6th            1/1     Running   0          77d
stolon-keeper-0                   1/1     Running   0          1d
stolon-keeper-1                   1/1     Running   0          1d
stolon-keeper-2                   1/1     Running   0          1d
stolon-proxy-db976479d-5r6qs      1/1     Running   0          1d
stolon-proxy-db976479d-8x46s      1/1     Running   0          1d
stolon-sentinel-54579c7dd-bk76h   1/1     Running   0          1d
stolon-sentinel-54579c7dd-cwtm2   1/1     Running   0          1d

Once running, access http://gitlab.example.com and log in with the initial root credentials (user: root, password: admin123456). Verify stability by creating a project, cloning a repository, and uploading files. Configure email verification to disable public registration, and test the email service by performing a password reset.

Additional Notes:

  • In the GITLAB_OMNIBUS_CONFIG environment variable, bundled services such as Grafana, Alertmanager, and Prometheus are disabled by default. The GitLab Pages service is enabled with its own external URL (page.example.com); do not reuse the main gitlab.example.com subdomain.
  • To enable custom domain support for Pages, configure the gitlab_pages['external_http'] parameter.
  • Refer too the official GitLab documentation for further configuration options.

Tags: kubernetes gitlab devops CI/CD deployment

Posted on Thu, 20 Aug 2026 16:47:33 +0000 by ChrisFlynn