1

gitlab-ci.yml

cache:
  key: "$CI_COMMIT_REF_NAME node:14.4.0-alpine"
  paths:
    - node_modules/

stages:
  - release
  - deploy

variables:
  TAGGED_IMAGE: "$CI_REGISTRY_IMAGE:latest"

.release:
  stage: release
  image: docker:19.03.12
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
    DOCKER_BUILDKIT: 1
  before_script:
    - docker version
    - docker info
    - echo "$CI_JOB_TOKEN" | docker login --username $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
  script:
    - printf "REACT_APP_XXX_BACKEND_URI=$REACT_APP_XXX_BACKEND_URI" > .env
    - docker build --pull --target $CI_COMMIT_REF_NAME --tag $TAGGED_IMAGE --cache-from $TAGGED_IMAGE .
    - docker push $TAGGED_IMAGE
  after_script:
    - docker logout $CI_REGISTRY

.deploy:
  stage: deploy
  image: gitlab/dind:latest
  services:
    - docker:dind
  variables:
    DOCKER_COMPOSE_PATH: "~/docker-composes/$CI_PROJECT_PATH/docker-compose.yml"
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$DEPLOY_SERVER_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan $DEPLOYMENT_SERVER_IP >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - rsync -avR --rsync-path="mkdir -p ~/docker-composes/$CI_PROJECT_PATH/; rsync" ./docker-compose.yml root@$DEPLOYMENT_SERVER_IP:~/docker-composes/$CI_PROJECT_PATH/
    - ssh root@$DEPLOYMENT_SERVER_IP "echo "$CI_REGISTRY_PASSWORD" | docker login --username $CI_REGISTRY_USER --password-stdin $CI_REGISTRY; docker-compose -f $DOCKER_COMPOSE_PATH rm -f -s -v $CI_COMMIT_REF_NAME; docker pull $TAGGED_IMAGE; docker-compose -f $DOCKER_COMPOSE_PATH -p $CI_COMMIT_REF_NAME up -d $CI_COMMIT_REF_NAME;"

release_stage:
  extends: .release
  only:
    - stage
  environment:
    name: staging
    url: http://staging.xxx.us

deploy_stage:
  extends: .deploy
  only:
    - stage
  environment:
    name: staging
    url: http://staging.xxx.us

Dockerfile

# pull official base image
# dev stage
FROM node:14.4.0-alpine AS dev

# set working directory
WORKDIR /var/www/

# install app dependencies
COPY package.json package-lock.json ./
RUN npm ci --silent

# add app
COPY . ./

# builder stage
FROM dev AS builder

RUN npm run build:app

# stage stage
FROM nginx:1.19.1-alpine AS stage

# Remove default files created by Nginx
RUN rm -rvf /usr/share/nginx/html/*
RUN rm -vf /etc/nginx/conf.d/default.conf

COPY --from=builder /var/www/build/ /usr/share/nginx/html

CMD ["nginx-debug", "-g", "daemon off;"]

docker-compose.yml

version: '3.8'

services:
  stage:
    container_name: xxx-website-stage
    image: registry.gitlab.com/xxx.us/website:latest
    build:
      context: .
      target: stage
      dockerfile: Dockerfile
    ports:
      - '3002:80'
    restart: always

default.conf

upstream staging-xxx-us {
  server 0.0.0.0:3002;
}

server {
  listen 3002;

  server_name localhost;
  # ...
}

server {
  listen 80;

  server_name staging.xxx.us;

  location / {
    proxy_pass http://staging-xxx-us;

    proxy_http_version 1.1;
    proxy_cache_bypass $http_upgrade;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Port $server_port;
  }
}

sudo docker ps

...        ...   "/docker-entrypoint.…"   ...       ...        0.0.0.0:3002->80/tcp   xxx-website-stage

sudo ufw status numbered

Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere
[ 2] 22/tcp                     ALLOW IN    Anywhere
[ 3] 80/tcp                     ALLOW IN    Anywhere
[ 4] 443/tcp                    ALLOW IN    Anywhere
[ 5] OpenSSH (v6)               ALLOW IN    Anywhere (v6)
[ 6] 22/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 7] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 8] 443/tcp (v6)               ALLOW IN    Anywhere (v6)

sudo netstat -ltnp | grep :*

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      12088/nginx: master
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      680/systemd-resolve
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1534/sshd
tcp6       0      0 :::80                   :::*                    LISTEN      12088/nginx: master
tcp6       0      0 :::22                   :::*                    LISTEN      1534/sshd
tcp6       0      0 :::3002                 :::*                    LISTEN      28198/docker-proxy

sudo nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Everything works fine with port 3001, but nothing works with any other ports (e.g. 3002). I modify ports in docker-compose.yml to <anything>:80 and default.conf to point to <anything> in the upstream block.

Update 2

I have access to the container using docker exec and the website opens with the port 3002, I mean http://staging.xxx.us:3002 works fine, but I expect users open the website without any specific port, I mean http://staging.xxx.us

Alex
  • 121
  • 4
  • Where does this partial nginx configuration fit in to your setup? – Michael Hampton Jul 13 '20 at 20:25
  • @MichaelHampton What do you mean? – Alex Jul 13 '20 at 21:17
  • There's no context here. I don't see any nginx container in your docker-compose.yml, so why do you have this? Where does it fit into your whole system? – Michael Hampton Jul 13 '20 at 21:25
  • @MichaelHampton I built a simple CI/CD which gets done successfully. I updated my question with Dockerfile if I understood your question correctly. – Alex Jul 13 '20 at 22:08
  • You seem to be running nginx outside of Docker. Have you checked its error log? – Michael Hampton Jul 13 '20 at 22:23
  • @MichaelHampton I haven't installed Nginx on the server itself. I also checked all `.log` files exist in `/var/log/nginx` directory, including custom log files defined in the `default.conf`, and there is nothing there but `[debug] 43#43: epoll add event: fd:11 op:1 ev:00002001` – Alex Jul 13 '20 at 22:46

1 Answers1

1

I fixed the issue using nginx-proxy. If you need help, please check this out. I wrote the working configuration over there.

Alex
  • 121
  • 4