I deployed a django app using CI/CD from gitlab. The app is wrapped in a docker container and uses Nginx server. The deployment is successful from git but I get the error when I visit the IP.
502 Bad Gateway
nginx/1.17.4
I checked the log of the app’s container and it outputs
no destination
no destination
no destination
no destination
no destination
no destination
no destination
Also, that of the Nginx container outputs
2020/06/06 16:49:29 [error] 6#6: *754 connect() failed (111: Connection refused) while connecting to upstream, client: 196.251.20.105, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://172.18.0.3:8000/favicon.ico", host: "18.189.11.120", referrer: "http://18.189.11.120/"
196.251.20.105 - - [06/Jun/2020:16:49:29 +0000] "GET /favicon.ico HTTP/1.1" 502 559 "http://18.189.11.120/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" "-"
For some additional context, I will post the content of some of my files
Dockerfile
FROM python:3.6-slim
# create the appropriate directories
ENV APP_HOME=/web
RUN mkdir $APP_HOME
RUN mkdir $APP_HOME/static
RUN mkdir $APP_HOME/mediafiles
WORKDIR $APP_HOME
ENV PYTHONUNBUFFERED=1
# Add unstable repo to allow us to access latest GDAL builds
# Existing binutils causes a dependency conflict, correct version will be installed when GDAL gets intalled
RUN echo deb http://deb.debian.org/debian testing main contrib non-free >> /etc/apt/sources.list &&
apt-get update &&
apt-get remove -y binutils &&
apt-get autoremove -y
# Install GDAL dependencies
RUN apt-get install -y libgdal-dev g++ --no-install-recommends &&
pip install pipenv &&
pip install whitenoise &&
pip install gunicorn &&
apt-get clean -y
# Update C env vars so compiler can find gdal
ENV CPLUS_INCLUDE_PATH=/usr/include/gdal
ENV C_INCLUDE_PATH=/usr/include/gdal
ENV LC_ALL="C.UTF-8"
ENV LC_CTYPE="C.UTF-8"
# -- Adding Pipfiles
# COPY Pipfile Pipfile
# COPY Pipfile.lock Pipfile.lock
# COPY package.json package.json
# -- Install dependencies:
RUN pip install --upgrade pip
COPY ./requirements.txt /web/requirements.txt
RUN pip install -r requirements.txt
RUN apt-get update -yq
&& apt-get install curl gnupg -yq
&& apt-get install -y netcat
&& curl -sL https://deb.nodesource.com/setup_8.x | bash
&& apt-get install nodejs -yq
# copy entrypoint.sh
COPY ./entrypoint.prod.sh /web/entrypoint.prod.sh
# copy project
COPY . /web/
# run entrypoint.sh
ENTRYPOINT ["/web/entrypoint.prod.sh"]
entrypoint.prod.sh
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
exec "$@"
docker-compose.yml
version: '3.7'
services:
web:
image: "${WEB_IMAGE}"
command: gunicorn web.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/web/staticfiles
- media_volume:/web/mediafiles
ports:
- 8000:8000
env_file: .env
depends_on:
- db
nginx:
image: "${NGINX_IMAGE}"
volumes:
- static_volume:/web/staticfiles
- media_volume:/web/mediafiles
ports:
- 80:80
depends_on:
- web
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file: .env
volumes:
postgres_data:
static_volume:
media_volume:
Nginx Dockerfile
FROM nginx:1.17.4-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
nginx.conf
upstream web {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://web;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /web/static/;
}
location /mediafiles/ {
alias /web/mediafiles/;
}
}
2
Answers
you should make link from web to nginx in docker-compose.yml,
Your nginx don`t see upstream web.
more info :
https://docs.docker.com/compose/compose-file/#links
This should not be your case, but I had a similar problem and the error was due to the connection of my application to an external database.
One way to try to find the problem is to access the web container and run
curl localhost:8000
to see if it works locally.Another attempt you can make is to use networks, something like this: