Nginx redirects to https://web - django

My webapp was working fine until today, when my domain stopped working. I was using example.com:8000/ to reach my Django app, but now it redirects me to https://web/. I've tried to go back to previous commits, but the issue does not disappear.
My nginx.conf looks like:
upstream web {
ip_hash;
server web:8000;
}
# portal
server {
location /static/ {
autoindex on;
alias /static/;
}
location / {
proxy_pass http://web/;
}
listen 8000;
server_name localhost;
}
docker-compose.yaml looks like:
version: '3'
services:
nginx:
image: nginx:latest
container_name: ng01
ports:
- "8000:8000"
volumes:
- ./code:/code
- ./code/nginx:/etc/nginx/conf.d
- ./static:/static
depends_on:
- web
web:
build: .
container_name: dg01
command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn fortex.wsgi -b 0.0.0.0:8000"
volumes:
- .:/code
- ./static:/static
expose:
- "8000"
depends_on:
- db
db:
image: postgres
container_name: ps01
volumes:
- pg_volume:/var/lib/postgresql/data
volumes:
pg_volume: {}
Nginx redirects without logging, but when I use incognito in chrome it logs normally but still redirects me.

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/;
}
}

NGINX and TRAEFIK staticfiles are not working with HTTPS in production

I'm developing a website for my association Here. It uses Django 3.0.7 and PostgreSQL. I follow this tutorial to make it works in good condition in development and in production.
In development mode all is good, site is working perfectly, static files and media files are served by the Django built-in web server.
I test the "vanilla" (coming from the tutorial) production on my local machine it works too. But the tutorial is not complete for me so after completing it, I decided to adapt the code to fit my needs. As I follow the tutorial I created a new docker-compose and a new dockerfile for production. But there are 2 differences between the tutorial and the site I want to set in production:
I want to Use TREAFIK to route the traffic on different URL (appli.amis-simserhof.fr) because I will have other projects in the future on the same server with others subdomains..
I want to secure the website using HTTPS. So I use CERTBOT (let's encrypt) to generate certificates. I add this certificates to TREAFFIK in order to use HTTPS and it works.
So I adapted the docker-compose file with my new stuff :
version: '3.7'
services:
**traefik:
image: traefik:v1.7.12
command: [
"--loglevel=INFO",
"--api",
"--docker",
"--docker.domain=amis-simserhof.fr",
"--entrypoints=name:https address::443 tls:/etc/certs/fullchain.pem,/etc/certs/privkey.pem",
"--entrypoints=name:http address::80 redirect.entrypoint:https",
]
ports:
- 80:80 # http
- 443:443 # https
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/letsencrypt/live/amis-simserhof.fr/fullchain.pem:/etc/certs/fullchain.pem
- /etc/letsencrypt/live/amis-simserhof.fr/privkey.pem:/etc/certs/privkey.pem**
web:
image: registry.gitlab.com/guillaumekoenigtncy/aas-web:latest
command: gunicorn aas.wsgi:application --bind 0.0.0.0:8000
expose:
- 8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
environment:
- DEBUG=0
- SECRET_KEY=change_me
- DJANGO_ALLOWED_HOSTS=localhost appli.amis-simserhof.fr
- SQL_ENGINE=django.db.backends.postgresql
- SQL_DATABASE=postgres
- SQL_USER=postgres
- SQL_PASSWORD=postgres
- SQL_HOST=db
- SQL_PORT=5432
- DATABASE=postgres
labels:
- traefik.frontend.rule=HostRegexp:appli.amis-simserhof.fr
- traefik.frontend.entryPoints=https
depends_on:
- db
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
**nginx:
image: registry.gitlab.com/guillaumekoenigtncy/aas-nginx:latest
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 80
- 443
depends_on:
- web**
volumes:
postgres_data:
static_volume:
media_volume:
I also created a dockerfile and a config file for nginx :
FROM nginx:1.19.0
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
upstream website {
server web:8000;
}
server {
listen 80;
listen [::]:80;
access_log off;
server_name appli.amis-simserhof.fr;
location / {
proxy_pass http://website;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /staticfiles/ {
alias /home/app/web/staticfiles/;
}
location /mediafiles/ {
alias /home/app/web/mediafiles/;
}
}
The problem is that now static files are not served in production (I got a 404). When I set the DEBUG to True in the setting.py of the project files are served sot that means static files are present in the correct folder that I have set in the settings.
STATIC_URL = "/staticfiles/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
MEDIA_URL = "/mediafiles/"
MEDIA_ROOT = os.path.join(BASE_DIR, "mediafiles")
In production, I have correctly run the python manage.py collectstatic command. I look inside both containers, ngnix and web, and in both the files are present in the correct directory.
So I conclude my configuration is not working but when I made changes in it, I saw this changes in the nginx logs of the containers. There are no errors...
I try everything during the last 2 days: set the ssl in the nginx config and remove it from traefik (site is not accessible), expose or not ports 80 and 443 in nginx or traefik (conflicts on open ports or too many redirect error), add or remove / at the end or at the beginning of blocks or alias in nginx configuration (change nothing), etc.
If you have any hint or tips I would be really grateful...
Have a nice day :)
I'am was able do define static path with following nginx service configuration:
version: '3.7'
services:
server:
container_name: dj
build:
context: ./server/project/
restart: unless-stopped
expose:
- 8000
volumes:
- static_volume:/app/staticfiles
- media_volume:/app/media
command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
networks:
- web
nginx:
container_name: nginx
build:
context: ./
dockerfile: Dockerfile
restart: unless-stopped
volumes:
- static_volume:/app/staticfiles
- media_volume:/app/media
labels:
- "traefik.enable=true"
- "traefik.http.routers.${SERVICE}.rule=(Host(`${DOMAIN_NAME}`) && PathPrefix(`/static`)) || (Host(`${DOMAIN_NAME}`) && PathPrefix(`/media`))"
- "traefik.http.routers.${SERVICE}.tls.certresolver=letsEncrypt"
- "traefik.http.routers.${SERVICE}.entrypoints=web-secure"
- "traefik.http.services.${SERVICE}.loadbalancer.server.port=80"
depends_on:
- server
networks:
- web
volumes:
static_volume:
media_volume:
networks:
web:
external: true
Note this line:
- "traefik.http.routers.static-http.rule=Host(`ex.example.com`) && PathPrefix(`/static`)"
change the ex.example.com to you domain
Here is part of my configuration, The "server" part is not completed yet
UPDATE
To use the same static files between django and nginx use following nxing configuration:
#default.conf
server {
listen 80;
server_name _;
ignore_invalid_headers on;
location / {
root /usr/share/nginx/html;
index index.html;
default_type application/javascript;
try_files $uri $uri/ /index.html =404;
}
location /static {
autoindex on;
alias /app/staticfiles/;
}
location /media {
autoindex on;
alias /app/media/;
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
Also note that I've updated docker-compose file and added Dockerfile below:
#Dockerfile
FROM nginx:1.19.1-alpine
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
So your Project-Structure should look like:
Project-root/
|-server/
|-nginx/
| |-default.conf
|-Dockerfile
|-docker-compose.yml

Django on docker container returns localhost as domain in production server

I have been following this tutorial here Dockerize Django to dockerize my django application with Nginx as production web server. However inside my django code get_current_site(request).domain returns localhost as a result all generated url endpoints have the domain localhost instead of the production server domain name.
my nginx.conf: here
upstream fullstack_application {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://fullstack_application;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
location /static/ {
alias /home/app/web/static/;
}
location /media/ {
alias /home/app/web/media/;
}
}
my production docker-compose.yml: here
version: "3.7"
services:
web:
build:
context: ./app
dockerfile: Dockerfile.prod
command: gunicorn fullstack_application.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/media
expose:
- 8000
env_file:
- ./.env.prod
depends_on:
- db
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.prod.db
nginx:
build: ./nginx
volumes:
- static_volume:/home/app/web/static
- media_volume:/home/app/web/media
ports:
- 1337:80
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
Pls help :(
You could try setting hostname and/or domainname for service web in your docker-compose.yml file.
See documentation.

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.

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.