
Deploying GitLab CE on AWS ECS with Fargate: A Step-by-Step Guide
This article focuses on hosting a private GitLab environment on AWS using Amazon ECS with the Fargate deployment type. Fargate enables a serverless container hosting model, presenting unique challenges in integrating various components seamlessly to ensure a fully functional setup.
- Basic knowledge of AWS services (ECS, ECR, RDS, ElastiCache)
- Familiarity with Docker and Terraform
- An AWS account set up for deployment
- ECS Cluster, Service, and Task Definition
- ECR Container Registry
- VPC, Public Subnets, Private Subnets, Subnet Groups, Route Tables, Internet Gateway
- Necessary Security Groups and IAM roles & policies
- Elastic File System (EFS) Volumes
- ElastiCache Cluster for Redis
- Amazon RDS for PostgreSQL database
- Elastic Load Balancer, listeners, and target groups
- S3 Bucket for backups and required bucket policies
1
2
3
4
psql -h <RDS_ENDPOINT> -U <RDS_MASTER_USER> -d postgres
CREATE DATABASE gitlabhq_production OWNER <gitlab_user>;
CREATE USER gitlab WITH PASSWORD '<strong_password>';
GRANT ALL PRIVILEGES ON DATABASE gitlabhq_production TO gitlab;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# External URL
external_url 'https://your-load-balancer-dns.amazonaws.com'
# Redis configuration
gitlab_rails['redis_host'] = "your-redis-cluster-endpoint"
gitlab_rails['redis_port'] = 6379 # Default Redis port
gitlab_rails['redis_password'] = "your_redis_password"
# Database configuration
gitlab_rails['db_adapter'] = 'postgresql'
gitlab_rails['db_host'] = 'your-rds-endpoint.amazonaws.com'
gitlab_rails['db_port'] = 5432
gitlab_rails['db_username'] = 'gitlab'
gitlab_rails['db_password'] = 'your_database_password'
gitlab_rails['db_database'] = 'gitlabhq_production'
# Disable built-in Postgres and Redis
postgresql['enable'] = false
redis['enable'] = false
# Optional: Configure GitLab to use HTTPS
nginx['redirect_http_to_https'] = true
- Build and Push Docker Image: The workflow builds a Docker image for GitLab CE and pushes it to Amazon Elastic Container Registry (ECR).
- Update ECS Task Definition: It retrieves the current ECS task definition, updates it with the new image tag, and registers the updated task definition.
- Force New Deployment: Finally, it updates the ECS service to deploy the new version of GitLab CE.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
on:
push:
branches:
- main
workflow_dispatch:
env:
AWS_REGION: us-east-1
ECR_REPOSITORY: **********dkr.ecr.us-east-1.amazonaws.com/gitlab-runner-repo
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: arn:aws:iam::544234170512:role/GithubRole
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
working-directory: ./docker
run: |
docker build -t $ECR_REPOSITORY:$IMAGE_TAG .
docker tag $ECR_REPOSITORY:$IMAGE_TAG $ECR_REPOSITORY:latest
docker push $ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REPOSITORY:latest
- name: Get Current Task Definition
run: |
aws ecs describe-task-definition --task-definition gitlab-task --query taskDefinition --output json > task-def.json
- name: Set Image Tag
env:
IMAGE_TAG: ${{ github.sha }}
run: |
jq --arg newTag "$IMAGE_TAG" \
'del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy) |
.containerDefinitions[0].image = "544234170512.dkr.ecr.us-east-1.amazonaws.com/gitlab-runner-repo:" + $newTag' \
task-def.json > updated-task-def.json
cat updated-task-def.json
- name: Register New Task Definition
run: |
aws ecs register-task-definition --cli-input-json file://updated-task-def.json
- name: Update ECS Service
run: |
aws ecs update-service --cluster gitlab-runner-cluster --service gitlab-service --force-new-deployment
the default user is root and you can setup the initial password on the gitlab.rb file.