Nginix configuration for django nuxt app with docker hosted on ec2 - django

I have a dockerized app that works fine in development mode on my host machine. I'm trying to figure out how I can host my app on ec2 using the default ip address created when I launch my instance.
My folder structure is as follows.
backend
|---projectname
|---Dockerfile
|---requirements.txt
|---wait-for-it.sh
config/nginx
|---app.conf
frontend
|---nuxt folders
|---Dockerfile
This is my current docker compose file I'm using
docker-compose.yml
version: '3.4'
services:
db:
restart: always
image: postgres
volumes:
- pgdata:/var/lib/postgresql/data
env_file: .env
ports:
- "5432:5432"
expose:
- 5432
redis:
restart: always
image: redis
volumes:
- redisdata:/data
django:
build:
context: ./backend
env_file: .env
command: >
sh -c "./wait-for-it.sh db:5432 &&
cd autobets && python manage.py collectstatic --noinput &&
gunicorn --workers=2 --bind=0.0.0.0:8000 autobets.wsgi:application"
ports:
- "8000:8000"
volumes:
- ./backend:/app
depends_on:
- db
restart: on-failure
nuxt:
build:
context: ./frontend
environment:
- API_URI=http://django:8000/api
command: bash -c "npm install && npm run dev"
volumes:
- ./frontend:/app
ports:
- "3000:3000"
depends_on:
- django
- redis
volumes:
pgdata:
redisdata:
config/nginx/app.config
upstream django {
ip_hash;
server django:8000;
}
upstream nuxt {
ip_hash;
server nuxt:3000;
}
server {
location ~ /(api|admin|static)/ {
proxy_pass http://django;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
}
location / {
proxy_pass http://nuxt;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
}
listen 8000;
server_name localhost;
}
Say if my ec2 domain name pointer is ec2-52-204-122-132.compute-1.amazonaws.com
How do I set nginx up in my app to accept http connections to the frontend of my app?
On the backend localhost:8000/admin is my admin page I'd like to access this also using the ec2 domain name too.
What's the best way to alter my config so when I push my app after add the domain name pointer I can access my app hosted on ec2?
I've been reading documentation but can't find any helpful info for a dockerized django vue type app running on ec2.

firstly you need to make sure the security group attach to your box is open for incoming connection on port that NGinx listen
For each container you want to put on NGinx config you will need to find their do to so do:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
NGinx is not inside a container,docker-compose so, nginx.conf
upstream django {
ip_hash;
server <container IP>:8000; # <-- Change this, with container IP
}
upstream nuxt {
ip_hash;
server <container IP>:3000; # <-- Change this, with container IP
}
server {
location ~ /(api|admin|static)/ {
proxy_pass #django # <-- Change this, with container IP
proxy_pass <container IP>:8000; # <-- OR Change this, with container IP
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
}
location / {
proxy_pass #nuxt # <-- Change this, add port
proxy_pass <container IP>:3000 # <-- OR Change this, add port
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
}
listen 8000; # <-- Change port number, django already use this host port
server_name localhost ec2-52-204-122-132.compute-1.amazonaws.com; # <-- change this line, add EC2 public domain
}
docker-compose.yml
version: '3.4'
services:
db:
restart: always
image: postgres
volumes:
- pgdata:/var/lib/postgresql/data
env_file: .env
ports:
- "5432:5432"
expose:
- 5432
networks: # <-- Add this
- random_name # <-- Add this
redis:
restart: always
image: redis
volumes:
- redisdata:/data
networks: # <-- Add this
- random_name # <-- Add this
django:
build:
context: ./backend
env_file: .env
command: >
sh -c "./wait-for-it.sh db:5432 &&
cd autobets && python manage.py collectstatic --noinput &&
gunicorn --workers=2 --bind=0.0.0.0:8000 autobets.wsgi:application"
ports:
- "8000:8000"
volumes:
- ./backend:/app
depends_on:
- db
restart: on-failure
networks: # <-- Add this
- random_name # <-- Add this
nuxt:
build:
context: ./frontend
environment:
- API_URI=http://django:8000/api # <-- Wrong
# From you Javascript on the client point of view,
# you will request the public server, not the internal name of
# you backend inside a container, that the public will never see
- API_URI=http://ec2-52-204-122-132.compute-1.amazonaws.com/api # <-- Right
command: bash -c "npm install && npm run dev"
volumes:
- ./frontend:/app
ports:
- "3000:3000"
depends_on:
- django # <-- will become useless if change API_URI=
- redis # <-- bad design
networks: # <-- Add this
- random_name # <-- Add this
volumes:
pgdata:
redisdata:
networks: # <-- Add this
- random_name: # <-- Add this wanto make sure container can communicate
Security group on AWS should be open on the port you'll use for listening on NGinx, host 8000 is already used by django, so use another on
From app architecture POV, your backend should do the cache stuff with Redis, not the Frontend. Complexity or backend response caching should be cache on the backend somewhere on the controllers. You client should cache only statis assets. but you here to make you have working on a server, not to speak archi.

Related

Docker, Django, Gunicorn, Nginx, and a 502 bad gateway error

I am relatively new to Docker and have run into a problem that I can't seem to find a solution for. I have two Docker stacks that are running Nginx and Django however, one of the stacks is reachable via web browser, and the other times out with a bad gateway error. Both stacks are running on the same server but on different ports, the stack that runs on port 8000 is reachable the stack that runs on 8010 throws the 502 error. I have verified that the ports are open on the host and that I can ping from the Nginx container to the Django container. I have also spun up each stack separately which ended with the same results. I am running out of ideas so, any insight would be appreciated.
Server: VM - Red Hat Enterprise Linux Server release 7.9 (Maipo)
Docker version 20.10.3, build 48d30b5
Working Docker-compose file
version: '3.3'
services:
web:
build:
context: ./
dockerfile: Dockerfile
command: sh -c "python manage.py makemigrations &&
python manage.py migrate &&
gunicorn laitteiden_saatavuus.wsgi:application -w 3 --bind 0.0.0.0:8000"
volumes:
- static_volume:/home/app/web/static
expose:
- 8000
- 1433
env_file:
- ./laitteiden_saatavuus/.env
networks:
- database
- nginx_network
depends_on:
- db
db:
image: postgres:latest
volumes:
- postgres_data:/var/lib/postgresql/data/
- ./laitteiden_db.sql:/docker-entrypoint-initdb.d/laitteiden_db.sql
networks:
- database
nginx:
build: ./nginx
volumes:
- static_volume:/home/app/web/static
ports:
- 8000:80
networks:
- nginx_network
depends_on:
- web
networks:
database:
driver: bridge
nginx_network:
driver: bridge
volumes:
postgres_data:
static_volume:
Working Nginx conf
upstream laitteiden_saatavuus {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://laitteiden_saatavuus;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /home/app/web/static/;
}
}
Non working docker-compose file
version: '3.3'
services:
web:
build:
context: ./
dockerfile: Dockerfile
command: sh -c "gunicorn eq_allocation.wsgi:application -w 3 --bind 0.0.0.0:8000"
volumes:
- static_volume:/home/equipment_drill/web/static
expose:
- 8000
- 1433
env_file:
- ./eq_allocation/.env
networks:
- eq_network
nginx:
build: ./nginx
volumes:
- static_volume:/home/equipment_drill/web/static
ports:
- 8010:80
networks:
- eq_network
depends_on:
- web
networks:
eq_network:
driver: bridge
volumes:
static_volume:
Non working Nginx conf
upstream eq_allocation {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://eq_allocation;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /home/equipment_drill/web/static/;
}
}

Combine network host and bridge for Nginx and Django

I am dockerizing a Django application, using also Nginx as proxy.
My problems is that the DB is running (non dockerized) on the same machine of the where the dockers are hosted.
Therefore, i have to use network_mode: "host" for the django app in order to connect to the db using localhost.
On the other side, if I do so, the nginx image is not able to reach the Django app anymore and gives
nginx: [emerg] host not found in upstream
My docker compose file is the following:
version: '3.4'
services:
web:
build: .
command: sh /start.sh
networks:
- db_network
- web_network
volumes:
- static_volume:/allarmi/src/AllarmiWs/static
expose:
- 8001
environment:
- DEBUG=0
- DJANGO_SETTINGS_MODULE=AllarmiWs.settings.deploy
nginx:
build: ./nginx
ports:
- 8000:80
depends_on:
- web
volumes:
- static_volume:/allarmi/src/AllarmiWs/static
networks:
- web_network
volumes:
static_volume:
networks:
web_network:
driver: bridge
db_network:
driver: host
This is my nginx.conf file
upstream allarmi {
server web:8001;
}
server {
listen 80;
location / {
proxy_pass http://allarmi;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /allarmi/src/AllarmiWs/static/;
}
}
How can I do it

Dockerized Nginx, Domain not working properly

I managed to dockerized my django app. With docker-compose I can run django,postgresql and nginx but Nginx not working well. I can access my app and it works fine but when I tried to connect to my domain, always work at port 8000. I want to run my app at testapp.org but I can only access wtih testapp.org. How can I solve this? What changed do I need to use in my configuration file? Did I missed something?
docker-compose:
version: '3'
services:
db:
container_name: db.postgres
image: postgres:10
environment:
- POSTGRES_DB=testdb
- POSTGRES_USER=test
- POSTGRES_PASSWORD=password
ports:
- '5432:5432'
volumes:
- ./pgdata:/var/lib/postgresql/data
web:
restart: always
build: .
image: djangoapp
command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn fatihkocnet.wsgi -b 0.0.0.0:8000"
depends_on:
- db
volumes:
- ./fatihkocnet:/fatihkocnet
- ./config/nginx:/etc/nginx/conf.d
expose:
- "8000"
nginx:
restart: always
image: nginx:latest
ports:
- "8000:8000"
volumes:
- ./fatihkocnet:/fatihkocnet
- ./config/nginx:/etc/nginx/conf.d
depends_on:
- web
nginx/test.conf
upstream web {
ip_hash;
server web:8000;
}
# portal
server {
location / {
proxy_pass http://web;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
listen 8000;
server_name testapp.org;
}
You need to map Docker Hosts port (80 if you want to host service on HTTP port) to your ngnix docker service.
e.g.
ports:
- "80:8000"
You need to map your HOST servers IP into DNS to your testapp.org address.

nginx doesn't forward to django app in docker-compose in ubuntu but it all works in docker-machine in Mac

I have a django backend where I use docker-compose to deploy. This django application uses a nginx proxy in the front.
When I deploy it in a docker-machine and I go to the docker-machine ip I am redirected to the django site properly.
But when i deploy it in a ubuntu machine on docker, when i go to the ip of the nginx container I am given the default nginx page, I am not redirected to the django application. The nginx container doesn't log any error too. All services are running in docker without any error.
I am sharing the config file of nginx, docker-compose files below
nginx.conf
server {
listen 80;
server_name omaha;
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/ssl.crt;
ssl_certificate_key /etc/nginx/ssl/ssl.key;
charset utf-8;
client_max_body_size 200M;
location / {
proxy_pass http://web:8000;
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;
}
}
nginx dockerfile
FROM nginx
COPY conf/nginx.conf /etc/nginx/conf.d/nginx.conf
COPY certs/ /etc/nginx/ssl
docker-compose.yml
version: '2'
services:
nginx:
restart: always
build:
context: ./nginx/
ports:
- "80:80"
- "443:443"
volumes_from:
- web
web:
restart: always
build:
context: ./web
depends_on:
- web_ffmpeg
- postgres
- redis
- rabbitmq
expose:
- "8000"
environment:
- DEBUG=True
command: /usr/local/bin/gunicorn wsgi:application -w 2 -b :8000
web_ffmpeg:
restart: always
build:
context: ./web
depends_on:
- postgres
- redis
- rabbitmq
expose:
- "8000"
command: /usr/local/bin/celery -A trigger worker -l info
postgres:
restart: always
image: postgres:latest
expose:
- "5432"
volumes:
- pgdata:/var/lib/postgresql/data/
redis:
restart: always
image: redis:latest
expose:
- "6379"
volumes:
- redisdata:/data
rabbitmq:
restart: always
image: rabbitmq:3-management
environment:
RABBITMQ_DEFAULT_USER: 'adminuser'
RABBITMQ_DEFAULT_PASS: 'xxxxxxxxx'
RABBITMQ_DEFAULT_VHOST: 'myvhost'
ports:
- "15672:15672"
expose:
- "5672"
volumes:
elk-data:
pgdata:
redisdata:
web-data:
web-ffmpeg-data:
software versions:
I even matched all the version in between the two workstation. The versions are
docker 1.12.5, 1.13.0
docker-compose 1.11.0, 1.11.1
I tried all combinations of the versions and still same problem exists.
What is different between using docker-compose in a docker-machine and directly on a ubuntu machine.
the problem was in gunicorn config.
I didnt bind it to 0.0.0.0:8000 instead I had just binded it to :8000. this was the problem. I still dont know why it worked in machine

Why isn't nginx handling requests in this docker-compose/django setup?

I'm trying to learn docker and docker-compose, and have run into a roadblock.
The stack is a python:2.7 base image serving up django pages, and this part works fine. I now want to put nginx in front of it as a reverse proxy. When I access localhost:8000 I get django pages as expected. When I load up localhost with no port, I get nothing ("Problem loading page"). I assume the connection between django container's port 8080 and nginx port 80 isn't happening, and I'm so new to docker that it's probably something simple that I'm not seeing.
docker-compose.yml
version: '2'
services:
web:
build: ./app/
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ./app/:/code
ports:
- "8000:8000"
depends_on:
- db
nginx:
restart: always
build: ./nginx/
ports:
- "80:80"
volumes:
- /www/static
volumes_from:
- web
links:
- web:web
# probably not relevant to my issue
db:
image: postgres
redis:
restart: always
image: redis:latest
ports:
- "6380:6380"
volumes:
- ./redisdata/:/data
nginx config:
server {
listen 80;
server_name 127.0.0.1;
charset utf-8;
location /static {
alias /code/static;
}
location / {
proxy_pass http://web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
The nginx service starts successfully and appears to be running. I checked it's log using
docker-compose logs nginx
And it was empty.