Nginx not serving my Flask website - python

I am following this example and this answer on stackoverflow and I am stuck.
I am running this example on a digitalocean VPS. My file structure is as follows:
project structure
docker-compose.yml
mainweb/
nginx/
README
docker-compose.yml
version: '2'
services:
app:
restart: always
build: ./mainweb
command: gunicorn -w 2 -b :5000 wsgi:app
networks:
- mainnet
expose:
- "5000"
ports:
- "5000:5000"
nginx:
restart: always
build: ./nginx
networks:
- mainnet
links:
- app
volumes:
- /www/static
expose:
- 8080
ports:
- "8880:8080"
networks:
mainnet:
mainweb/
app.py
Dockerfile
requirements.txt
templates/
wsgi.py
mainweb/app.py
from flask import Flask, render_template
app=Flask(__name__)
#app.route('/')
def home()():
return render_template('templates/home.html')
if __name__=="__main__":
app.run(host="0.0.0.0", port=5000)
mainweb/Dockerfile
FROM python:3.5
MAINTAINER castellanprime
RUN mkdir /mainweb
COPY . /mainweb
WORKDIR /mainweb
RUN pip install -r requirements.txt
mainweb/templates/
home.html
mainweb/templates/home.html
<!doctype html>
<html>
<head>
<title> My website </title>
</head>
<body>
<h1> I am here </h1>
</body>
</html>
mainweb/wsgi.py
from app import app
if __name__=="__main__":
app.run()
nginx
Dockerfile
sites-enabled.conf
static/
nginx/Dockerfile
FROM nginx:1.13.1-alpine
MAINTAINER castellanprime
ADD sites-enabled.conf /etc/nginx/conf.d/sites-enabled.conf
ADD static/ /www/static/
nginx/sites-enabled.conf
server{
listen 8080;
server_name app; # Should I put my actual www.XXXXXX.XXXXX address here
charset utf-8;
location /static{
alias /www/static/;
}
location / {
proxy_pass http://app:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X_Forwared-For $proxy_add_x_forwarded_for;
}
}
nginx/static
css/
js/
After I run the command docker-compose up -d, I check the www.XXXXXX.com:8880, or www.XXXXXX.com:8080 from another web client on another system.
I get the standard nginx web page.
How do I redirect it to the home.html?

Take a step back and run the Flask app alone.
You have some syntax errors.
from flask import Flask, render_template
app=Flask(__name__)
#app.route('/')
def home(): # Remove double brackets
return render_template('home.html') # The templates folder is already picked up
if __name__=="__main__":
app.run(host="0.0.0.0", port=5000)
Then in a Docker container, and without gunicorn
FROM python:3.5
RUN mkdir /mainweb
COPY . /mainweb
WORKDIR /mainweb
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["python3","/mainweb/app.py"]
And run it, and see if it works.
cd mainapp
docker build -t flask:test .
docker run --rm -p 5000:5000 flask:test
Open http://server:5000
Then start on docker-compose with just that container and define nginx if you want.
nginx/Dockerfile
FROM nginx:1.13.1-alpine
ADD flask.conf /etc/nginx/conf.d/
EXPOSE 8080
nginx/flask.conf (I changed this based on a file that I have in a project)
server {
listen 8080; # This is the port to EXPOSE in nginx container
server_name app; # You can change this, but not necessary
charset utf-8;
location ^~ /static/ {
alias /usr/share/nginx/html/;
}
location / {
try_files $uri $uri/ #flask;
}
location #flask {
proxy_pass http://app:5000; # This is the port Flask container EXPOSE'd
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X_Forwared-For $proxy_add_x_forwarded_for;
}
}
And finally, the compose. You don't want to have your site exposing both 5000 and 80 (you don't want people to bypass nginx), so just don't expose 5000
version: '2'
services:
app:
restart: always
build: ./mainweb
networks:
- mainnet
nginx:
restart: always
build: ./nginx
networks:
- mainnet
links:
- app
volumes:
- ./mainweb/static:/usr/share/nginx/html
ports:
- "80:8080"
networks:
mainnet:

Related

nginx django static cannot fully serve my files(403 permission denied)

I've been dealing with nginx for about 1 week. I have 4 services that I set up with docker, django postgresql fastapi and nginx, but nginx does not serve django's static files. I'm facing 403 error. I tried the solutions of all similar error fields, but it doesn't work (file permission granting file path control) below I am sharing the files I use please help.
docker-compose.yml:
django_gunicorn:
build: .
command: gunicorn sunucu.wsgi:application --bind 0.0.0.0:7800 --workers 3
volumes:
- ./static:/root/Kodlar/kodlar/static
env_file:
- .env
environment:
- DATABASE_URL="**"
ports:
- "7800"
depends_on:
- db
nginx:
build: ./nginx
volumes:
- ./static:/root/Kodlar/kodlar/static
ports:
- "80:80"
depends_on:
- django_gunicorn
volumes:
static_files:
Django Docker File:
FROM python:3.8-slim-buster
WORKDIR /app
ENV PYTHONUNBUFFERED=1
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
RUN python manage.py migrate --no-input
RUN python manage.py collectstatic --no-input
CMD ["gunicorn", "server.wsgi:application", "--bind", "0.0.0.0:7800","--workers","3"]
Django Settings py:
STATIC_URL = '/static/'
STATIC_ROOT = '/root/Kodlar/kodlar/static/'
DEBUG = False
Nginx Docker File:
FROM nginx:1.19.0-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
Nginx Conf File:
upstream django {
server django_gunicorn:7800;
}
server {
listen 80;
server_name mydomain.com;
error_page 404 /404.html;
location = /404.html {
root /root/Kodlar/kodlar/templates;
internal;
}
if ($host != 'mydomain.com') {
return 404;
}
location / {
proxy_pass http://django;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ {
alias /root/Kodlar/kodlar/static/;
}
}
I want my django service to run actively with gunicorn and serve static files in nginx

How to make Ajax Async calls within a Flask python app running with Nginx & gunicorn

I'm running a flask python app, within which I make some Ajax calls.
Running it using the Flask development server works fine, the calls run in the background and I can continue using the app.
When moving to a gunicorn and Nginx reverse proxy setup the app seems to wait for that Ajax call to be processed (often ending up in a timeout). Why is that? Does this have something to do with multithreading? I'm new to gunicorn/nginx. Thanks for the help
The setup is pretty much the same as described here: https://testdriven.io/blog/dockerizing-flask-with-postgres-gunicorn-and-nginx/#docker
The nginx config:
upstream app {
server web:5000;
}
server {
listen 80;
location / {
proxy_pass http://app;
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/project/static/;
}
location /media/ {
alias /home/app/web/project/media/;
}
}
docker-compose file:
version: '3.8'
services:
web:
container_name: app
restart: always
build:
context: ./services/web
dockerfile: Dockerfile.prod
expose:
- 5005
env_file:
- ./.env.prod
command: gunicorn --bind 0.0.0.0:5005 manage:app
volumes:
- static_volume:/home/hello_flask/web/app/static
- media_volume:/home/hello_flask/web/app/media
depends_on:
- db
db:
container_name: app_prod_db
restart: always
image: postgres:13-alpine
volumes:
- postgres_data_prod:/var/lib/postgresql/data/
env_file:
- ./.env.prod.db
nginx:
container_name: nginx
restart: always
build: ./services/nginx
volumes:
- static_volume:/home/app/web/app/static
- media_volume:/home/app/web/app/start/media
image: "nginx:latest"
ports:
- "5000:80"
depends_on:
- web
volumes:
postgres_data_prod:
static_volume:
media_volume:
Don't think that Ajax call is an issue but just in case here it is:
$("#load_account").on('submit', function(event) {
$.ajax({
data : {
vmpro : $('#accountInput').val()
},
type : 'POST',
url : '/account/load_account'
})
.done(function(data) {
if (data.error) {
$('#errorAlert_accountvmproInput').text(data.error).show();
$('#successAlert_accountInput').hide();
}
else {
$('#successAlert_accountInput').text(data.overview).show();
$('#errorAlert_accountInput').hide();
}
});
Solved:
gunicorn was running 1 single worker and of the default sync class.
Increasing the number of workers to 4 solved the problem.
However I actually opted to use gevent class workers in the end.
My updated docker-compose yml includes:
command: gunicorn -k gevent -w 2 --bind 0.0.0.0:5005 manage:app
Detailed in gunicorn documentation HERE

Static files not served when using docker + django + nginx

I am trying to dockerize a django project and use nginx to serve static files. Everything seems to be working except the static files are not served. When I go to the admin page, always get Not Found: /django_static/rest_framework/css/prettify.css for files in django_static folder.
folder structure:
backend
server
apps
django_static
media
...
docker
backend
Dockerfile
wsgi-entrypoint.sh
nginx
production
default.conf
development
default.conf
Dockerfile
Here is my docker-compose:
services:
nginx:
build: ./docker/nginx
ports:
- 1234:80
volumes:
- ./docker/nginx/production:/etc/nginx/conf.d
- django_static:/app/backend/server/django_static
- media:/app/backend/server/media
depends_on:
- backend
restart: "on-failure"
backend:
build:
context: .
dockerfile: ./docker/backend/Dockerfile
entrypoint: /app/docker/backend/wsgi-entrypoint.sh
ports:
- "8001:8001"
volumes:
- django_static:/app/backend/server/django_static
- media:/app/backend/server/media
expose:
- 8001
volumes:
django_static:
media:
dockerfile for django:
FROM python:3.7-slim
WORKDIR /app
ADD ./backend/requirements.txt /app/backend/
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN pip install --upgrade pip
RUN pip install gunicorn
RUN pip install -r backend/requirements.txt
ADD ./backend /app/backend
ADD ./docker /app/docker
wsgi-entrypoint.py
#!/bin/sh
until cd /app/backend/server
do
echo "Waiting for server volume..."
done
until ./manage.py migrate
do
echo "Waiting for db to be ready..."
sleep 2
done
./manage.py collectstatic --noinput
gunicorn server.wsgi --bind 0.0.0.0:8001 --workers 1 --threads 1
#./manage.py runserver 0.0.0.0:8003
nginx docker file:
FROM nginx:1.19.0-alpine
RUN rm /etc/nginx/conf.d/default.conf
CMD ["nginx", "-g", "daemon off;"]
nginx config file:
upstream glf {
server 0.0.0.0:8001;
}
server {
listen 80;
location / {
proxy_pass http://0.0.0.0:8001;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /django_static/ {
alias /app/backend/server/django_static/;
}
location /media/ {
alias /app/backend/server/media/;
}
}
settings.py
MEDIA_URL = '/media/'
STATIC_URL = '/django_static/'
STATIC_ROOT = BASE_DIR / 'django_static'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Any hint is appreciated!

Nginx docker container not accepting and serving flask from container

So I have banging my head on this issue for the past hours, and I have got a docker-compose.yml file
version: '2'
services:
web:
restart: always
build: ./web_app
expose:
- "8000"
ports:
- "8000:8000"
volumes:
- ./web_app:/data/web
command: /usr/local/bin/gunicorn web_interface:app -w 4 -t 90 --log-level=debug -b 0.0.0.0:8000 --reload
depends_on:
- postgres
nginx:
restart: always
build: ./nginx
ports:
- "8080:80"
volumes_from:
- web
depends_on:
- web
postgres:
restart: always
image: postgres:latest
volumes_from:
- data
volumes:
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
- ./backups/postgresql:/backup
expose:
- "5432"
data:
restart: always
image: alpine
volumes:
- /var/lib/postgresql
tty: true
However, when I docker-compose up and then navigate to localhost:8880, I get nothing served. Is like the nginx server is not accepting connections through the localhost.
nginx.conf
server {
listen 80;
server_name localhost;
charset utf-8;
location /static/ {
alias /data/web/crm/web_interface;
}
location = /favicon.ico {
alias /data/web/crm/web_interface/static/favicon.ico;
}
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;
}
}
nginx/Dockerfile
FROM nginx:latest
RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx.conf /etc/nginx/conf.d/nginx.conf
And this is whats in my terminal:
I have been following this tutorial fairly closely, but it cant seem to serve the Flask App that I have created. Any ideas?
Try changing the port mapping for nginx service as below:
ports:
- "8880:80"
or make nginx listen on port 8080.

504 error with nginx and flask docker containers

Two days of work and I'm still stuck. I'm running separate nginx and application containers. The application container has a flask app that runs a gunicorn process on port 8000.
Everytime I nav to localhost:8080 which is the nginx port 80 is mapped to on localhost, I get a loading screen and a nginx 504 error.
This is what I see on the terminal:
docker-compose.yml
version: '2'
services:
web:
restart: always
build: ./web_app
expose:
- "8000"
ports:
- "8000:8000"
volumes:
- ./web_app:/data/web
command: /usr/local/bin/gunicorn web_interface:app -w 4 -t 90 --log-level=info -b :8000 --reload
depends_on:
- postgres
nginx:
restart: always
build: ./nginx
ports:
- "8080:80"
volumes_from:
- web
depends_on:
- web
postgres:
restart: always
image: postgres:latest
volumes_from:
- data
volumes:
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
- ./backups/postgresql:/backup
expose:
- "5432"
data:
restart: always
image: alpine
volumes:
- /var/lib/postgresql
tty: true
nginx.conf
server {
listen 80;
server_name localhost;
charset utf-8;
location /static/ {
alias /data/web/crm/web_interface;
}
location = /favicon.ico {
alias /data/web/crm/web_interface/static/favicon.ico;
}
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;
}
}
nginx Dockerfile
FROM nginx:latest
RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx.conf /etc/nginx/conf.d/nginx.conf
I'll provide more info if needed to get some help on this issue that Im struggling on.
NGINX response 504 indicate gateway timeout, because of NGINX can not connection the backend server. So, you can locate the issue at proxy_pass directory.
I guess NGINX can not resolve web domain name, There is two solution:
instead of IP
location / {
proxy_pass http://<real_ip>:8000;
}
use upstream
upstream web {
server <real_ip>;
}
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;
}
Ok, so after three days of bashing my head, I re-started from the ground up. Rebuilt the app container and ran gunicorn.
From there I was able to determine that the gunicorn process was timing out because the database host name was incorrect. Instead of the an error being returned through my application, the failure went silent.
I fixed this by linking the postgres container and the web container. In my code I was able to use "postgres" (the name of the container) as the postgres host name.
Check the addresses to your external hosts.

Categories

Resources