I try to put build of react app on localhost/ using nginx. As far as i understand this, i need to build app with "npm run build" and then serve build dir with static content. After many hours i managed to get it into work with docker and my django service as a api under localhost/api/. But what is not working is css and js on this sites. On any page neither is it react or django endpoints there is only raw html with attached css but not working. After many attempts with changing configs etc. I ended with same raw html. Why on nginx there is no styling on sites even if with inspecting these pages there is linked css to them.
This is my nginx.conf
http {
server {
listen 80;
listen [::]:80;
root /var/www/html;
server_name localhost;
index index.html index.htm;
location /api/ {
proxy_pass "http://web:8000/";
}
location / {
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
root /var/www/html;
expires 1M;
access_log off;
add_header Cache-Control "public";
}
}
}
This is part of docker-compose
nginx:
image: nginx:latest
ports:
- 80:80
- 443:443
volumes:
- ./nginx_conf/:/etc/nginx/
- ./frontend/build/:/var/www/html/
depends_on:
- web
When i run this app with npm start : image
When i enter localhost/ with nginx running : image
Ok i don't understand why. But i was messing with inspector and i clicked by accident disable http cache AND bootstrap loaded!? I really have no idea how but now it works.
i add 2 include into server and it's worked:
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
Related
I'm trying to setup an app on my Digital Ocean production server, I've followed these instructions, testing gunicorn and nginx,I could access the app in gunicorn and both services start fine with no errors logged. However when I go to the site it does not show anything. This is a subdomain of my main site. Mostly I'm looking to find a place to start troubleshooting this especially since everything looks fine.
Configs:
Nginx config for subdomain (Django) site:
server {
# use 'listen 80 deferred;' for Linux
# use 'listen 80 accept_filter=httpready;' for FreeBSD
listen 80;
# set the correct host(s) for your site
server_name subdomain.domain_name.com www.subdomain.domain_name.com;
location = /favicon.ico {access_log off; log_not_found off;}
location /static/ {
root /path/to/static/files;
}
location / {
include proxy_params;
proxy_pass http://unix:/path/to/.sock/file;
}
}
Nginx config for main (static) site:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/main_site_folder;
index index.html index.htm index.nginx-debian.html;
server_name domain_name www.domain_name;
location / {
try_files $uri $uri/ =404;
}
}
[Unit]
Description=Description of the app
After=network.target
[Service]
User=MyUserName
Group=www-data
WorkingDirectory=/var/www/app_directory/
ExecStart=/path/to/venv/and/gunicorn --access-logfile - --workers 3 --bind unix:/var/www/app_dir/.sock_filename app_name.wsgi:application
[Install]
WantedBy=multi-user.target
You could start by changing ALLOWED_HOSTS = ["*"] in settings.py. Also try accessing your URL through CURL.
Solved by adding an A record for the sub-domain 🙄, this was a classic case of not being able to find the answer because it was right in front of my face. 😅
I have built and successfully deployed a django rest framework using gunicorn and nginx on Ubuntu 18.04. However, the static files are not being pulled up.
Django web app without loaded static files
Here is my nginx configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name [my_server_domain_or_IP];
#root /var/www/html;
location = /favicon.ico { access_log off; log_not_found off; }
location = /static/ {
root /home/ubuntu/myprojectdir;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
And in my settings.py file:
STATIC_URL = '/static/'
import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
I have checked that DEBUG is set to False.
I have also already run collectstatic and the static files are located in a folder called static in: /home/ubuntu/myprojectdir/static.
Every change I tried to make in the nginx configuration, I restarted nginx with the following command: sudo systemctl restart nginx.
I mainly followed this tutorial, the only difference is that I edited the default nginx configuration instead of creating a new one because it wasn't deploying my django application this way.
I can't seem to figure out what's wrong and have been trying to solve it for days. Am I missing something here?
You don't need equals sign here:
location = /static/ {
root /home/ubuntu/myprojectdir;
}
Instead try this:
location /static/ {
root /home/ubuntu/myprojectdir;
}
Try to giving permissions to your home folder
chmod a+x /home/ubuntu -R
I was following this tutorial to create a backend and it worked.
I made simple a Django REST admin panel to upload images, it worked.
Then I created Vue frontend app, run npm run serve while in 'VScode remote' and it worked (images are fetched from Django and styled by Vue in my localhost).
The PROBLEM is it's not obvious how to make all this work in the production VPS server (i mean from Vue 'dist' folder after vue run build).
Everything I tried just gives me a 404 error or ruins the Django admin panel.
Here are my NGINX settings :
server {
server_name kruglovks.xyz www.kruglovks.xyz;
client_max_body_size 100m;
location = /favicon.ico { access_log off; log_not_found off; }
location /static {
root /home/kirill/myprojectdir/myproject;
}
location /media {
root /home/kirill/myprojectdir/myproject;
}
location /dist {
try_files $uri $uri/ /index.html;
alias /home/kirill/myprojectdir/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
Vue router is set to history mode.
Please, I need some info on how to make Vue work in this configuration.
P.S. Maybe there is an alternative way of using Vue alongside Django?
Thank you so much and have a nice day!
That was a huge step forward, not a 404 but blank page called 'frontend' and browser refused to find css and js.
Later with a friends help and thisguide i could reconfigure nginx settings to this :
server {
listen 80;
server_name kruglovks.xyz www.kruglovks.xyz;
root /home/sasha/myprojectdir/myproject/dist/;
client_max_body_size 100m;
location = /favicon.ico { access_log off; log_not_found off; }
location /static {
alias /home/sasha/myprojectdir/myproject/static;
}
location /media {
alias /home/sasha/myprojectdir/myproject/media;
}
location / {
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /admin {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
and it works now !
Thank you so muck #Danizavtz, you saved me like weeks of life ...
You are not listening to any ports.
Notice that in location /dist you also have to change the order of operations
Try to change your default to this configuration:
server {
listen 80;
server_name kruglovks.xyz www.kruglovks.xyz;
root /var/www;
#... configurations
location /dist {
alias /home/kirill/myprojectdir/myproject;
try_files $uri $uri/ /index.html;
}
And the vuejs application will be served in www.kruglovks.xyz/dist.
This is for production, not intended for development environment. Django application deployed using Guncorn
# settings.py
ALLOWED_HOSTS=['yourdomain.com', 'localhost'] # 'localhost' is optional
...
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
If using 'corsheaders' then add yourdomain.com
# settings.py
CORS_ALLOWED_ORIGINS = `[`
"https://yourdomain.com",
"http://yourdomain.com", # Use this if SSL in not configured
"http://localhost"
]
Update 'urls.py' for the project, and choose path for your application; mine is 'app/api/' so it will direct to http://yourdomain.com/app/api/
urlpatterns = [
path('app/api/', include('api.urls')),
path('app/admin/', admin.site.urls),
]
NGINX Configurations
# /etc/nginx/sites-available/yourdomain.com.conf
server {
root /var/www/app/dist; # Vue app production build
index index.html index.htm index.nginx.debian.html;
server_name yourdomain.com www.yourdomain.com;
# Django folder
location /static/ {
root /path/to/django/project/folder;
}
# Django web requests handled here
location /app/ {
# Gunicorn and other configurations
...
}
# Everything else handled by Vue
location / {
try_files /$uri /$uri/ /index.html$args;
}
...
}
You can also use Nginx to serve Vue and another Nginx instance to work as reverse proxy to serve Django statics (Gunicorn will serve Django dynamic content i.e API calls/ responses) - you will get faster serving of static content and improved security layer on the way.
Here is why tu use Nginx -> https://djangoadventures.com/what-is-the-point-of-using-nginx-in-front-of-a-django-application/
Nice example here for Docker, Django, Postres, Nginx -> https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/
For Vue - Nginx can also serve that. Remember to edit settings.py with Cors and allowed hosts.
If you want incorporate nginx proxy to the frontend then you can do that by 2 separate nginx files like:
frontend file -> nginx.conf
server {
listen 8080;
location / {
root /code;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
backend file -> default.conf
upstream backend {
server backend:8000;
}
upstream frontend {
server frontend:8080;
}
server {
listen 80;
root /usr/share/nginx/html;
include /etc/nginx/mime.types;
# Vue frontend.
location / {
proxy_pass http://frontend;
}
# Django API.
location /api {
proxy_pass http://backend;
autoindex off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
# Django static assests.
location /static/ {
autoindex on;
alias /code/staticfiles/;
}
}
Dockerfile for Django
# Build from minimal image for speed and security
FROM python:3.10.2-slim-bullseye
ENV WORKDIR=/code
ENV USER=code
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR $WORKDIR
COPY requirements.txt $WORKDIR
# make static files dirs in order to avoid error from collectstatic
RUN mkdir $WORKDIR/staticfiles && \
mkdir $WORKDIR/staticfiles/admin && \
mkdir $WORKDIR/staticfiles/rest_framework
RUN pip install --upgrade pip && \
pip install -r requirements.txt && \
adduser --system --group $USER && \
chown -R $USER:$USER $WORKDIR
COPY ./app/backend $WORKDIR
USER $USER
EXPOSE 8000
Dockerfile for vue
FROM node:lts-alpine as build-stage
ENV WORKDIR=/code
WORKDIR $WORKDIR
# copy both 'package.json' and 'package-lock.json' (if available) from you project dir
COPY app/frontend/package*.json $WORKDIR/
# install project dependencies
RUN npm install --legacy-peer-deps
COPY app/frontend $WORKDIR
RUN npm run build
# Serve Vue
FROM nginx:alpine as production-stage
RUN mkdir $WORKDIR
COPY app/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build-stage $WORKDIR/dist $WORKDIR
EXPOSE 8080
Then Docker compose
version: "3.5"
volumes:
postgres_data:
static_volume:
services:
backend:
container_name: django_backend
env_file:
- .env
build:
context: .
dockerfile: Dockerfile.django
restart: unless-stopped
# Should go into separate *.sh file but for simplicity - you starting Gunicorn to serve Django
command: >
sh -c "python manage.py wait_for_db &&
python manage.py migrate --noinput &&
python manage.py collectstatic --no-input &&
gunicorn your_project.wsgi:application --bind 0.0.0.0:8000"
volumes:
- static_volume:/code/staticfiles
depends_on:
- database
frontend:
container_name: vue_frontend
build:
context: .
dockerfile: Dockerfile.vue
restart: unless-stopped
nginx:
container_name: nginx_proxy_server
build:
context: .
dockerfile: Dockerfile.nginx_proxy
restart: unless-stopped
ports:
- 80:80
volumes:
- static_volume:/code/staticfiles
depends_on:
- frontend
- backend
database:
container_name: postgres_db
build:
context: .
dockerfile: Dockerfile.postgres
volumes:
- postgres_data:/var/lib/postgresql/data/
# from .env
environment:
- POSTGRES_HOST=${DATABASE_HOST}
- POSTGRES_USER=${DATABASE_USER}
- POSTGRES_PASSWORD=${DATABASE_PASSWORD}
- POSTGRES_DB=${DATABASE_NAME}
I am setting up a production server with Angular serving the front end and Django on the back. I got Nginx serving Angular properly but any requests to the backend dont go through and just time out.
I have Nginx serving Angular on port 80 and then Django on port 8800
This is the code I have in place for Django
server {
listen 8800;
server_name ADDRESS;
location = /favicon.ico {access_log off;log_not_found off;}
location = /static/ {
root /home/ubuntu/django/dbsystem;
}
location = /media/ {
root /home/ubuntu/django/dbsystem;
}
location = / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/django/dbsystem/dbsystem.sock;
}
}
This is the code I have in place for Angular
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ /index.html;
}
}
This is the code for Gunicorn
[Unit]
Description=gunicorn service
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/django/dbsystem/
ExecStart=/home/ubuntu/django/bin/gunicorn --access-logfile - --workers 3 -- bind unix:/home/ubuntu/django/dbsystem/dbsystem.sock dbsystem.wsgi:application
[Install]
WantedBy=multi-user.target
If I go to ADDRESS it pulls up Angular which is expected
If I go to ADDRESS/suburl it pulls up the appropriate Angular Route as expected
If I go to ADDRESS:8800 it loads up the Django (Not found) page since its in debug mode which is expected
If I go to ADDRESS:8800/suburl it waits a bit and goes into timeout which is the issue I am trying to solve. This is for both the /media route and all other routes. I dont have/use the static folder route I defined
There is a problem with location = in you nginx configuration. Please remove = and it would work.
I have a problem understanding how to run my Django app with Nginx (server is Ubuntu).
So, I have a site which allows for user accounts, and it currently has a problem, where both "www" and non-"www" URLs load. This is problematic, because logging-in to one, will not reflect to the other. Besides that, it's also confusing. I want to keep the non-"www" variant.
I followed the instructions here on how to do it using Ngnix:
https://www.digitalocean.com/community/tutorials/how-to-redirect-www-to-non-www-with-nginx-on-ubuntu-14-04
And it worked when I tried to load the domain. But when I started the Django app, it stopped working.
I'm really confused on how to get it working, is there some way of running my django app through Nginx?
Thanks!
EDIT: I've included the server config thing (I think)
default
server {
server_name www.nilly.com;
return 301 $scheme://nilly.com$request_uri;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}