Unable to deploy Django/Docker/Nginx/Gunicorn/Celery/RabbitMQ/SSL on AWS Lightsail - django

I have been trying for more than a week few hours daily.
Needless to say, I'm beginner in most of these things, but I have tried hundreds of configurations and nothing worked.
That's why I am finally coming here for help.
I am currently getting 502 Bad Gateway.
My suspicion is that either Nginx can't find staticfiles (if that's a reason for a 50x error) or nginx upstream doesn't know what is web (in config), or something with permissions on nginx.
Nginx error logs are printing this:
connect() failed (111: Connection refused) while connecting to upstream...upstream: "https://some-ip-address-here?:443" (this might be that nginx doesn't know about the web)
Dockerfile
# Pull base image
FROM python:3.10.2-slim-bullseye
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Create and set work directory called `app`
RUN mkdir -p /app
RUN mkdir -p /app/staticfiles
WORKDIR /app
# Install dependencies
COPY requirements.txt /tmp/requirements.txt
RUN set -ex && \
pip install --upgrade pip && \
pip install -r /tmp/requirements.txt && \
apt-get -y update && \
apt-get -y upgrade && \
apt-get install -y ffmpeg && \
rm -rf /root/.cache/
# Copy local project
COPY . /app/
COPY wait-for-it.sh /wait-for-it.sh
RUN chmod +x /wait-for-it.sh
docker-compose.yml
version: '3.7'
services:
web:
container_name: web
build: .
restart: always
command: ["/wait-for-it.sh", "db:5432", "--", "gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "my_project.wsgi"]
volumes:
- .:/app
ports:
- "8000:8000"
- "443"
env_file: .env
depends_on:
- db
nginx:
container_name: nginx
restart: always
image: jonasal/nginx-certbot:4.2.0-nginx1.23.3
env_file:
- .env.nginx
volumes:
- nginx_secrets:/etc/letsencrypt
- ./nginx/user_conf.d:/etc/nginx/user_conf.d
- .:/app
ports:
- 80:80
- 443:443
depends_on:
- web
- db
db:
container_name: db
image: postgres:13
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file: .env
celery:
container_name: celery
restart: always
build:
context: .
command: celery -A my_project worker -l info -B
volumes:
- .:/app
env_file:
- .env
depends_on:
- web
- rabbitmq3
rabbitmq3:
container_name: rabbitmq
image: rabbitmq:3-management-alpine
ports:
- 5672:5672
- 15672:15672
volumes:
postgres_data:
nginx_secrets:
Nginx config
upstream web {
server web:443;
}
# Redirect all HTTP requests to HTTPS
server {
listen 80;
server_name myurl.com;
return 301 https://$server_name$request_uri;
location /static/ {
alias /app/staticfiles/;
}
location /media/ {
alias /app/media/;
}
}
# Pass request to the web container
server {
location / {
proxy_pass https://web/;
}
access_log /var/log/nginx/project.access.log;
error_log /var/log/nginx/project.error.log;
# Listen to port 443 on both IPv4 and IPv6.
listen 443 ssl default_server reuseport;
listen [::]:443 ssl default_server reuseport;
server_name www.myurl.com myurl.com;
# Load the certificate files
ssl_certificate /etc/letsencrypt/live/my-site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-site/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/my-site/chain.pem;
# Load the Diffie-Hellman parameter
ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem;
location /static/ {
alias /app/staticfiles/;
}
location /media/ {
alias /app/media/;
}
}

Related

Nginx frontend not calling Nginx in backend

So I am using Django + react with nginx both on backend and frontend, containerized in docker. The following image will clarify how I want to serve the whole application:
Having been googling but couldn't make sense of the solutions. Issue is that Nginx in frontend not connecting with nginx on backend on port 8082.
Following are docker, nginx and docker-compose files.
Nginx configurations for frontend:
upstream react {
server reactapp:3000;
}
server {
listen 80;
client_max_body_size 100M;
proxy_set_header X-Forwarded-Proto $scheme;
location / {
root /usr/share/nginx/html;
}
location /add-to-waiting/ {
proxy_pass http://0.0.0.0:8082;
}
}
Dockerfile for react and nginx for frontend:
# build environment
FROM node as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm i --silent
RUN npm install react-scripts#3.4.1 -g --silent
COPY . ./
RUN npm run build
# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
docker-compose.yml for frontend:
services:
frontend:
build: .
ports:
- "8090:80"
container_name: irisfrontend
Nginx configurations for backend
upstream django {
server website:8000;
}
server {
listen 80;
client_max_body_size 100M;
proxy_set_header X-Forwarded-Proto $scheme;
location / {
proxy_pass http://django;
}
location /media/ {
alias /app/media/;
}
location /static/ {
alias /app/forex/static/admin/;
}
}
Dockerfile for nginx in backend:
FROM nginx:1.19.0
COPY ./default.conf /etc/nginx/conf.d/default.conf
Dockerfile for gunicorn in backend:
FROM python:3
ADD requirements.txt /app/requirements.txt
ADD . /app
WORKDIR /app
EXPOSE 8000:8000
RUN pip install --upgrade pip && pip install -r /app/requirements.txt
RUN python manage.py collectstatic --no-input --settings=forex.settings.production
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "forex.wsgi:application", "DJANGO_SETTINGS_MODULE=forex.settings.production"]
docker-compose.yml for backend:
services:
db:
build: ./db
website:
build:
context: .
dockerfile: Dockerfile.app
env_file:
- env
container_name: website_container_8
volumes:
- static:/app/forex/static/admin/
depends_on:
- db
nginx:
build: ./nginx
volumes:
- static:/app/forex/static/admin/
ports:
- "8082:80"
depends_on:
- website
volumes:
static:
What changes do I need to make to successfully do a post request from frontend nginx to backend nginx?
Include a network for both containers so that they can communicate.
services:
db:
build: ./db
website:
build:
context: .
dockerfile: Dockerfile.app
env_file:
- env
container_name: website_container_8
volumes:
-
static:/app/forex/static/admin/
depends_on:
- db
networks:
- nettest
nginx:
build: ./nginx
volumes:
-
static:/app/forex/static/admin/
ports:
- "8082:80"
depends_on:
- website
networks:
- nettest
volumes:
static:
networks:
nettest:

Publishing Two Sites with Django/Docker/Nginx Reverse Proxy?

How can I publish two different Django projects with two domains to one host using Docker in my DigitalOcean Droplet? Should I set Nginx in the docker-compose.yml file, or should I set it on the host system (etc/nginx/…)? Or should I run nginx in a separate container?
When I search on the internet, people who publish django projects with docker usually write their nginx settings in the docker-compase.yml file, but I couldn't understand how to set the reverse proxy in this way to publish two different sites.
Nginx settings - Dockerfile, docker-compose.yml would be very appreciated if you give information about settings. Thanks in advance.
I'm sorry for my bad English :( :(
docker-compose.yml
version: '3'
services:
djangoapp:
build: .
volumes:
- .:/opt/services/djangoapp/src
- static_volume:/opt/services/djangoapp/static
- media_volume:/opt/services/djangoapp/media
networks:
- nginx_network
- database1_network
depends_on:
- database1
nginx:
image: nginx
ports:
- 8000:80
volumes:
- ./config/nginx/conf.d:/etc/nginx/conf.d
- static_volume:/opt/services/djangoapp/static
- media_volume:/opt/services/djangoapp/media
depends_on:
- djangoapp
networks:
- nginx_network
database1:
image: postgres
env_file:
- config/db/database1_env
networks:
- database1_network
volumes:
- database1_volume:/var/lib/postgresql/data
networks:
nginx_network:
driver: bridge
database1_network:
driver: bridge
volumes:
database1_volume:
static_volume:
media_volume:
Nginx - local.conf
upstream hello_server {
server djangoapp:8000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://hello_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8000;
}
location /static/ {
alias /opt/services/djangoapp/static/;
}
location /media/ {
alias /opt/services/djangoapp/media/;
}
}
Dockerfile
FROM python:3.8
RUN mkdir -p /opt/services/djangoapp/src
WORKDIR /opt/services/djangoapp/src
COPY Pipfile Pipfile.lock /opt/services/djangoapp/src/
RUN pip install pipenv && pip install --upgrade pip && pipenv install --system
RUN pip install django-ckeditor
RUN pip install Pipfile
COPY . /opt/services/djangoapp/src
EXPOSE 8000
CMD ["gunicorn", "--chdir", "hello", "--bind", ":8000", "hello.wsgi:application"]

nginx: [emerg] host not found in upstream when dockerizing a django/react project

I'm trying to dockerize a django/react project but i'm running into this error when running docker-compose up.
i don't understand where the error come from.
i'm new to docker.
my goal is to deploy the frontend and the backend separately in one server.
nginx: [emerg] host not found in upstream
[emerg] 1#1: host not found in upstream "backend:8000" in /etc/nginx/conf.d/default.conf:2
nginx_1 | nginx: [emerg] host not found in upstream "backend:8000" in /etc/nginx/conf.d/default.conf:2
here is my code
django's Dockerfile
ENV DJANGO_SECRET_KEY $DJANGO_SECRET_KEY
ENV DJANGO_CORS_ORIGIN_WHITELIST $DJANGO_CORS_ORIGIN_WHITELIST
RUN mkdir /backend
WORKDIR /backend
COPY requirements.txt /backend/
EXPOSE 8000
RUN pip install -r requirements.txt
COPY . /backend/
RUN python manage.py makemigrations
RUN python manage.py migrate
react's Dockerfile
FROM node
USER root
WORKDIR /frontend
COPY . /frontend
ARG API_URL
ENV REACT_APP_HOST_IP_ADDRESS $API_URL
RUN yarn
RUN yarn config set ignore-engines true
RUN yarn build
server's config
upstream api {
server backend:8000;
}
server {
listen 8080;
location /api/ {
proxy_pass http://api$request_uri;
}
# ignore cache frontend
location ~* (service-worker\.js)$ {
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
expires off;
proxy_no_cache 1;
}
location / {
root /var/www/frontend;
try_files $uri $uri/ /index.html;
}
}
docker-copose.yml
version: '3'
services:
backend:
build:
context: ./ruelle_backend
args:
DJANGO_ALLOWED_HOSTS: http://ruelle-online.fr
DJANGO_SECRET_KEY: anis1807
DJANGO_CORS_ORIGIN_WHITELIST: http://ruelle-online.fr
command: gunicorn ivan_backend.wsgi --bind 0.0.0.0:8000
ports:
- "8000:8000"
frontend:
build:
context: ./ruelle_frontend
args:
API_URL: http://ruelle-online.fr
volumes:
- build_folder:/frontend/build
nginx:
image: nginx:latest
ports:
- 80:8080
volumes:
- ./webserver/nginx-proxy.conf:/etc/nginx/conf.d/default.conf:ro
- build_folder:/var/www/frontend
depends_on:
- backend
- frontend
volumes:
build_folder:

nginx port is not accessible with django docker

I'm dockerizing a Django 2.x app
Dockerfile
FROM python:3-alpine
RUN apk --update add libxml2-dev libxslt-dev libffi-dev gcc musl-dev libgcc curl
RUN apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev postgresql-dev
RUN apk add --no-cache bash
ENV PYTHONUNBUFFERED 1
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8
RUN set -ex && mkdir /app
COPY Pipfile /app
COPY Pipfile.lock /app
WORKDIR /app
RUN pip install pipenv
RUN pipenv install --system --deploy
ADD . /app/
RUN chmod +x start.sh
RUN chmod +x wait-for-it.sh
EXPOSE 9010
docker-compose.yml
version: '3'
services:
nginx:
image: nginx:alpine
container_name: "originor-nginx"
ports:
- "10080:9010"
- "10443:43"
volumes:
- .:/app
- ./config/nginx:/etc/nginx/conf.d
- ./app/static_cdn/static_root:/app/static_cdn/static_root
- originor_media_volume:/app/static_cdn/media_root
depends_on:
- web
networks:
- originor_web_network
web:
build: .
container_name: "originor-web"
command: ["./wait-for-it.sh", "db:5432", "--", "./start.sh"]
volumes:
- .:/app
- ./app/static_cdn/static_root:/app/static_cdn/static_root
- originor_media_volume:/app/static_cdn/media_root
ports:
- "9010:9010"
depends_on:
- db
networks:
- originor_web_network
- originor_db_network
db:
image: postgres:11
container_name: "originor-postgres-schema"
volumes:
- originor_database:/var/lib/postgresql/data
networks:
- originor_db_network
env_file:
- config/db/originor_database.env
ports:
- "5432:5432"
networks:
originor_web_network:
driver: bridge
originor_db_network:
driver: bridge
volumes:
originor_database:
originor_static_volume:
originor_media_volume:
nginx.conf
error_log /var/log/nginx/error.log;
include /etc/nginx/conf.d/proxy.conf;
upstream web {
ip_hash;
server web:9010 fail_timeout=0;
}
server {
listen 10080;
server_name localhost;
access_log /var/log/nginx/localhost.access.log combined;
location /static/ {
autoindex on;
alias /app/static_cdn/static_root/;
}
location /media/ {
alias /app/static_cdn/media_root/;
}
location / {
proxy_pass http://web/;
}
}
The server is started using gunicorn
gunicorn --pythonpath src originor.wsgi:application \
--bind 0.0.0.0:9010 \
--workers 3
Since, nginx is listening to port 10080 and Django server is running on 9010.
When I visit http://localhost:10080 it does not load while visiting http://localhost:9010 is accessible.
There is no log in the docker-compose console regarding nginx.
Running command docker-compose logs nginx gives only
Attaching to originor-nginx
Use proxy_pass
location / {
proxy_pass http://web:10080/;
proxy_redirect off;
proxy_intercept_errors on;
proxy_next_upstream error timeout http_502 http_504;
}

Django Nginx Docker Gunicorn cant reach

Sorry if it the answer seems obvious, but I've been bashing my head for the past couple of hours.
I've been following multiple tutorials trying to dockerize my application. No matter what combination of url:port or just url I tried I can't access the pages.
I have zero clue what am I doing wrong. I am assuming the following:
NGINX config plain wrong. How can upstream web know what's web? I assume docker exposes it, but unsure whether this is correct.
web container not exposing address and port properly?
I tried multipled settings, but non work.
I have the following:
Dockerfile
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
ADD ./django.conf /etc/nginx/conf.d/default.conf
#COPY ./django.conf /etc/nginx/sites-available/
#RUN ln -s /etc/nginx/sites-available/django.conf /etc/nginx/sites-enabled
docker-compose.yml
version: '3'
services:
db:
image: postgres:9.6
ports:
- "5432:5432"
environment:
- POSTGRES_USER=random_user
- POSTGRES_PASSWORD=random_password
redis:
restart: always
image: redis:4.0
expose:
- "6379"
nginx:
image: nginx:1.14.0
container_name: nginx01
ports:
- "8000:8000"
volumes:
- ./code
depends_on:
- web
web:
build: .
container_name: backend-api
command: bash -c "python manage.py migrate && python manage.py collectstatic --noinput && gunicorn ops4_backend.wsgi -b 0.0.0.0:8000"
depends_on:
- db
volumes:
- ./code
expose:
- "8000"
restart: always
django.conf
upstream web {
ip_hash;
server web:8000;
}
# portal
server {
location / {
proxy_pass http://web:8000;
}
listen 8000;
server_name localhost;
location /static {
autoindex on;
alias /src/static/;
}
}
docker ps -a
I was doing almost the same task yesterday, and the only valuable difference I see is that you include django.conf in Django container, not in nginx one. I have following volume in nginx section of docker-compose.yml:
- ./nginx:/etc/nginx/conf.d (where ./nginx is the folder with django.conf)
EDIT: here is my docker-compose.yml:
version: '3'
services:
nginx:
image: nginx
restart: always
ports:
- "80:8000"
volumes:
- ./nginx:/etc/nginx/conf.d
- ./static_cdn:/static
depends_on:
- web
db:
image: postgres
restart: always
web:
build: .
restart: always
command: bash -c "python3 manage.py makemigrations && python3 manage.py migrate && python3 manage.py collectstatic --no-input && gunicorn core.wsgi -b 0.0.0.0:8000"
volumes:
- .:/code
expose:
- "8000"
depends_on:
- db
django.conf:
upstream web {
ip_hash;
server web:8000;
}
server {
location /static/ {
alias /static/;
}
location / {
proxy_pass http://web/;
}
listen 8000;
server_name localhost;
}
With this setup nginx is available at 127.0.0.1:80 or just 127.0.0.1 as 80 is default http port.
There are so many wrong things, please use this configuration. and then change it step by step toward your specific needs.
also checkout this page that talks about Nginx Docker Configurations because one of your main problems is that you are not exposing django nginx conf that you make:
ADD ./django.conf /etc/nginx/conf.d/default.conf
to nginx container.
so nginx does not know how to map your configs.