DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

FULL DEVOPS CI CD LAB gitlab

🏗️ FINAL ARCHITECTURE

Developer (Mac)
      ↓
GitLab CI Runner
      ↓
GitLab Container Registry
      ↓
EC2 (Production Server)
      ↓
nginx (Port 80)
      ↓
Docker Container (Port 8081)
Enter fullscreen mode Exit fullscreen mode

Jenkins runs separately on 8080.


🧱 STEP 1 — EC2 PREPARATION

Install Docker

sudo apt update
sudo apt install docker.io -y
sudo usermod -aG docker ubuntu
Enter fullscreen mode Exit fullscreen mode

Log out and back in.


Install nginx

sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
Enter fullscreen mode Exit fullscreen mode

🧠 TROUBLESHOOTING #1 — Port 80 Conflict

Problem:

bind() to 0.0.0.0:80 failed (98: Address already in use)
Enter fullscreen mode Exit fullscreen mode

Cause:

Docker container was running on 80.

Fix:

docker ps
docker stop web
docker rm web
sudo lsof -i :80
Enter fullscreen mode Exit fullscreen mode

Then start nginx:

sudo systemctl start nginx
Enter fullscreen mode Exit fullscreen mode

🧱 STEP 2 — Configure nginx Reverse Proxy

Edit:

sudo nano /etc/nginx/sites-available/default
Enter fullscreen mode Exit fullscreen mode

Replace server block with:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    location / {
        proxy_pass http://localhost:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
Enter fullscreen mode Exit fullscreen mode

Test:

sudo nginx -t
sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

🧠 TROUBLESHOOTING #2 — Port 8080 Conflict

Problem:

failed to bind host port 8080: address already in use
Enter fullscreen mode Exit fullscreen mode

Cause:

Jenkins running on 8080.

Check:

sudo lsof -i :8080
Enter fullscreen mode Exit fullscreen mode

Result:

java jenkins 8080
Enter fullscreen mode Exit fullscreen mode

Fix:

Use port 8081 for Docker container.


🧱 STEP 3 — Dockerfile

Create Dockerfile in project root:

FROM nginx:alpine
COPY public /usr/share/nginx/html
EXPOSE 80
Enter fullscreen mode Exit fullscreen mode

🧱 STEP 4 — FINAL .gitlab-ci.yml

stages:
  - build
  - deploy

variables:
  IMAGE_NAME: registry.gitlab.com/$CI_PROJECT_PATH:latest

build_and_push:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  script:
    - docker build -t $IMAGE_NAME .
    - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
    - docker push $IMAGE_NAME
  only:
    - master

deploy_ec2:
  stage: deploy
  image: alpine:latest
  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 8081:80 --name web --restart always $IMAGE_NAME
      "
  only:
    - master
Enter fullscreen mode Exit fullscreen mode

🧠 TROUBLESHOOTING #3 — Image Not Found

Error:

An image does not exist locally with the tag
Enter fullscreen mode Exit fullscreen mode

Cause:

Build and push were in separate jobs.

Fix:

Combine build + push in same job (done above).


🧠 TROUBLESHOOTING #4 — Port 8081 Already Used

If this happens:

sudo lsof -i :8081
Enter fullscreen mode Exit fullscreen mode

Clean:

docker stop $(docker ps -q)
docker rm $(docker ps -aq)
Enter fullscreen mode Exit fullscreen mode

🧠 TROUBLESHOOTING #5 — SSH Host Not Resolved

Error:

Could not resolve hostname
Enter fullscreen mode Exit fullscreen mode

Cause:
EC2_HOST variable missing.

Fix:
Add in GitLab → Settings → CI/CD → Variables:

EC2_HOST = 3.131.97.47
EC2_KEY  = (full private key content)
Enter fullscreen mode Exit fullscreen mode

Visible, not masked.


🧠 TROUBLESHOOTING #6 — Public Key Error

Error:

Permission denied (publickey)
Enter fullscreen mode Exit fullscreen mode

Fix:

On EC2:

nano ~/.ssh/authorized_keys
Enter fullscreen mode Exit fullscreen mode

Add your public key.


🧠 TROUBLESHOOTING #7 — CI Jobs Isolation

Problem:
Image built but not available in push stage.

Reason:
Each GitLab job runs in separate container.

Fix:
Combine stages.


🔥 FINAL WORKING DEPLOYMENT

After successful pipeline:

On EC2:

docker ps
Enter fullscreen mode Exit fullscreen mode

You must see:

0.0.0.0:8081->80/tcp
Enter fullscreen mode Exit fullscreen mode

Test:

http://3.131.97.47
Enter fullscreen mode Exit fullscreen mode

🧠 WHAT YOU BUILT

You now have:

✔ CI/CD automation
✔ Docker image build
✔ GitLab registry integration
✔ SSH deployment
✔ nginx reverse proxy
✔ Port conflict resolution
✔ Jenkins coexistence
✔ Idempotent deployment
✔ Production-style architecture


🎓 THIS IS REAL DEVOPS

You debugged:

  • Port conflicts
  • CI isolation
  • Reverse proxy
  • SSH variables
  • Docker container lifecycle
  • Registry authentication
  • Production deployment flow

This is senior-level debugging.

Top comments (0)