Question

Nginx and Docker Work Fine on Port 3001:80 but Not Anything Else (e.g. 3002:80)

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

Subscribe
Share

Submit an answer
You can type!ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Hi there @meness,

Are you running the 3001 and 3002 applications on the same server?

I think that you are trying to start 2 instances of the Nginx container on port 80, one for your 3001 app and one for the 3002 app.

Can you run docker ps -a and share the output here to verify if this is the case?

If this is the case, what you would need to do is adjust the CI/CD process so that you don’t spin up 2 instances of the Nginx container on the same port, but just spin up 1 instance with multiple server blocks for each backend application.

Let me know how it goes1 Regards, Bobby