Tools
Tools: LAB: GitLab CI/CD Docker Deploy to AWS EC2
2026-02-21
0 views
admin
π― Lab Objective ## ποΈ Architecture ## πΉ STEP 1 β GitLab Pages Basic Pipeline ## πΉ STEP 2 β Add Docker Build Stage ## πΉ STEP 5 β Push to GitLab Container Registry ## π΄ ERROR #1 β Image Not Found ## πΉ STEP 6 β Deploy to AWS EC2 ## π΄ ERROR #2 β SSH Hostname Not Resolved ## Variable 1 ## Variable 2 ## π΄ ERROR #3 β Port 80 Already in Use ## πΉ Final Result ## π§ Real DevOps Troubleshooting Lessons ## π Interview Explanation Version Build a full CI/CD pipeline that: Create Dockerfile (ROOT of project): Update .gitlab-ci.yml: Fix:
Make sure build and push stages use SAME $IMAGE_NAME. Cause:
CI/CD variables not set. Settings β CI/CD β Variables Key: EC2_HOST
Value: EC2 Public IP Key: EC2_KEY
Value: FULL .pem file content Re-run pipeline β SUCCESS. This is REAL production debugging. "How would you deploy using GitLab CI/CD to EC2?" That is senior-level answer. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK:
Mac Terminal β
GitLab Repo β
GitLab CI/CD Pipeline β
Docker Image Build β
Push to GitLab Container Registry β
SSH to AWS EC2 β
Docker Pull & Run β
Application Live on Port 80 Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
Mac Terminal β
GitLab Repo β
GitLab CI/CD Pipeline β
Docker Image Build β
Push to GitLab Container Registry β
SSH to AWS EC2 β
Docker Pull & Run β
Application Live on Port 80 CODE_BLOCK:
Mac Terminal β
GitLab Repo β
GitLab CI/CD Pipeline β
Docker Image Build β
Push to GitLab Container Registry β
SSH to AWS EC2 β
Docker Pull & Run β
Application Live on Port 80 CODE_BLOCK:
image: busybox pages: stage: deploy script: - echo "The site will be deployed" artifacts: paths: - public rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
image: busybox pages: stage: deploy script: - echo "The site will be deployed" artifacts: paths: - public rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH CODE_BLOCK:
image: busybox pages: stage: deploy script: - echo "The site will be deployed" artifacts: paths: - public rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH COMMAND_BLOCK:
git commit --allow-empty -m "Trigger pipeline"
git push origin master Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
git commit --allow-empty -m "Trigger pipeline"
git push origin master COMMAND_BLOCK:
git commit --allow-empty -m "Trigger pipeline"
git push origin master CODE_BLOCK:
FROM nginx:alpine
COPY public /usr/share/nginx/html
EXPOSE 80 Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
FROM nginx:alpine
COPY public /usr/share/nginx/html
EXPOSE 80 CODE_BLOCK:
FROM nginx:alpine
COPY public /usr/share/nginx/html
EXPOSE 80 CODE_BLOCK:
stages: - build - push - deploy variables: IMAGE_NAME: registry.gitlab.com/$CI_PROJECT_PATH:latest build_image: stage: build image: docker:24 services: - docker:24-dind script: - docker build -t $IMAGE_NAME . Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
stages: - build - push - deploy variables: IMAGE_NAME: registry.gitlab.com/$CI_PROJECT_PATH:latest build_image: stage: build image: docker:24 services: - docker:24-dind script: - docker build -t $IMAGE_NAME . CODE_BLOCK:
stages: - build - push - deploy variables: IMAGE_NAME: registry.gitlab.com/$CI_PROJECT_PATH:latest build_image: stage: build image: docker:24 services: - docker:24-dind script: - docker build -t $IMAGE_NAME . CODE_BLOCK:
push_image: stage: push image: docker:24 services: - docker:24-dind script: - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY - docker push $IMAGE_NAME Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
push_image: stage: push image: docker:24 services: - docker:24-dind script: - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY - docker push $IMAGE_NAME CODE_BLOCK:
push_image: stage: push image: docker:24 services: - docker:24-dind script: - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY - docker push $IMAGE_NAME CODE_BLOCK:
An image does not exist locally with the tag Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
An image does not exist locally with the tag CODE_BLOCK:
An image does not exist locally with the tag COMMAND_BLOCK:
deploy_ec2: stage: deploy image: alpine before_script: - apk add --no-cache openssh script: - echo "$EC2_KEY" > key.pem - chmod 600 key.pem - ssh -o StrictHostKeyChecking=no -i key.pem ubuntu@$EC2_HOST " docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY && docker pull $IMAGE_NAME && docker stop web || true && docker rm web || true && docker run -d -p 80:80 --name web $IMAGE_NAME " Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
deploy_ec2: stage: deploy image: alpine before_script: - apk add --no-cache openssh script: - echo "$EC2_KEY" > key.pem - chmod 600 key.pem - ssh -o StrictHostKeyChecking=no -i key.pem ubuntu@$EC2_HOST " docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY && docker pull $IMAGE_NAME && docker stop web || true && docker rm web || true && docker run -d -p 80:80 --name web $IMAGE_NAME " COMMAND_BLOCK:
deploy_ec2: stage: deploy image: alpine before_script: - apk add --no-cache openssh script: - echo "$EC2_KEY" > key.pem - chmod 600 key.pem - ssh -o StrictHostKeyChecking=no -i key.pem ubuntu@$EC2_HOST " docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY && docker pull $IMAGE_NAME && docker stop web || true && docker rm web || true && docker run -d -p 80:80 --name web $IMAGE_NAME " CODE_BLOCK:
failed to bind host port 80
address already in use Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
failed to bind host port 80
address already in use CODE_BLOCK:
failed to bind host port 80
address already in use COMMAND_BLOCK:
sudo lsof -i :80 Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
sudo lsof -i :80 COMMAND_BLOCK:
sudo lsof -i :80 CODE_BLOCK:
nginx running Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
nginx running CODE_BLOCK:
nginx running COMMAND_BLOCK:
sudo systemctl stop nginx
sudo systemctl disable nginx Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
sudo systemctl stop nginx
sudo systemctl disable nginx COMMAND_BLOCK:
sudo systemctl stop nginx
sudo systemctl disable nginx CODE_BLOCK:
http://EC2_PUBLIC_IP Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
http://EC2_PUBLIC_IP CODE_BLOCK:
http://EC2_PUBLIC_IP - Connects GitLab to Mac terminal
- Builds Docker image
- Pushes image to GitLab Registry
- SSH into EC2
- Deploys container
- Handles real-world production errors - NOT protected
- Separate variables - Create Dockerfile
- Configure multi-stage pipeline
- Build image
- Push to registry
- Store SSH key & host as CI variables
- Use SSH in deploy stage
- Handle container replacement safely
- Troubleshoot port conflicts
- Ensure idempotent deployment
how-totutorialguidedev.toaimlubuntunginxdockergit