Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save perfecto25/877b629e93cf2a4619cb7b92a76b9c6d to your computer and use it in GitHub Desktop.
Save perfecto25/877b629e93cf2a4619cb7b92a76b9c6d to your computer and use it in GitHub Desktop.
Django sample prod deployment
SECRET_KEY="django-insecure-qtx7exsxxxxx"
DB_NAME="mydb"
DB_USER="dbuser"
DB_PW="xxx"
RECAPTCHA_PRIVATE_KEY="xxx"
RECAPTCHA_PUBLIC_KEY="xxxx"
EMAIL_HOST_USER="[email protected]"
EMAIL_HOST_PASSWORD="xxxx"
DEBUG=True
# /etc/iptables/rules.v4
# Generated by iptables-save v1.8.7 on Thu Nov 23 15:00:36 2023
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
################ block spammers
-A INPUT -p tcp -m tcp -s 47.251.13.59 -j REJECT
-A INPUT -p tcp -m tcp -s 205.210.31.89 -j REJECT
-A INPUT -p tcp -m tcp -s 51.161.82.133 -j REJECT
-A INPUT -p tcp -m tcp -s 51.161.82.191 -j REJECT
-A INPUT -p tcp -m tcp -s 198.235.24.130 -j REJECT
-A INPUT -p tcp -m tcp -s 172.168.40.190 -j REJECT
-A INPUT -p tcp -m tcp -s 147.185.133.38 -j REJECT
-A INPUT -p tcp -m tcp -s 109.202.99.46 -j REJECT
-A INPUT -p tcp -m tcp -s 213.232.87.232 -j REJECT
-A INPUT -p tcp -m tcp -s 165.227.173.41 -j REJECT
-A INPUT -p tcp -m tcp -s 46.101.111.185 -j REJECT
-A INPUT -p tcp -m tcp -s 139.59.132.8 -j REJECT
-A INPUT -p tcp -m tcp -s 167.99.210.137 -j REJECT
-A INPUT -p tcp -m tcp -s 13.229.249.197 -j REJECT
-A INPUT -p tcp -m tcp -s 23.178.112.211 -j REJECT
-A INPUT -p tcp -m tcp -s 1.12.245.182 -j REJECT
-A INPUT -p tcp -m tcp -s 5.8.11.202 -j REJECT
-A INPUT -p tcp -m tcp -s 154.213.187.182 -j REJECT
-A INPUT -p tcp -m tcp -s 78.153.140.177 -j REJECT
-A INPUT -p tcp -m tcp -s 167.172.236.245 -j REJECT
-A INPUT -p tcp -m tcp -s 193.41.206.24 -j REJECT
-A INPUT -p tcp -m tcp -s 13.59.197.17 -j REJECT
-A INPUT -p tcp -m tcp -s 203.81.86.34 -j REJECT
-A INPUT -p tcp -m tcp -s 78.153.140.224 -j REJECT
-A INPUT -p tcp -m tcp -s 31.220.1.88 -j REJECT
-A INPUT -p tcp -m tcp -s 51.161.80.229 -j REJECT
-A INPUT -p tcp -m tcp -s 184.105.247.196 -j REJECT
-A INPUT -p tcp -m tcp -s 13.203.19.73 -j REJECT
##############################################
-A INPUT -d 127.0.0.0/8 ! -i lo -j DROP
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -s <your pub IP>/32 -j ACCEPT ## allow full access to your self
# public open 80,443
-A INPUT -p tcp -m multiport --dports 80,443,25 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j DROP
-A INPUT -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
COMMIT
server {
server_name www.myhost.com myhost.org;
location / {
limit_except GET POST PUT DELETE {
deny all;
}
proxy_cache cache1;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
include /etc/nginx/bots.d/ddos.conf;
include /etc/nginx/bots.d/blockbots.conf;
# Strict Security
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()";
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;
proxy_set_header X-Forwarded-Host $server_name;
proxy_redirect off;
add_header P3P 'CP="ALL DSP COR PSAa OUR NOR ONL UNI COM NAV"';
add_header Access-Control-Allow-Origin *;
uwsgi_read_timeout 120;
proxy_pass http://localhost:8000;
}
location /static/ {
alias /home/user/django_project/django_app/static/;
}
location /media/ {
alias /home/user/django_project/django_app/media/;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/myhost.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/myhost.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.myhost.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = myhost.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.myhost.com myhost.com;
return 404; # managed by Certbot
}
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
proxy_connect_timeout 120s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
send_timeout 180s;
client_max_body_size 10M;
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache1:10m max_size=1g inactive=60m use_temp_path=off;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# define connection_upgrade value, connection header for websocket reverse proxy, closes upgrade if null
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
access_log /var/log/nginx/access.log main;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256";
ssl_prefer_server_ciphers on;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 180;
types_hash_max_size 2048;
#server_names_hash_bucket_size 128;
gzip on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_vary on;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name _;
add_header X-Frame-Options "SAMEORIGIN" always;
limit_req zone=one burst=5 nodelay;
return 301 https://www.myhost.com;
}
}
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
django = "*"
psycopg2 = "*"
loguru = "*"
django-bootstrap5 = "*"
django-allauth = "*"
pillow = "*"
django-bootstrap-modal-forms = "*"
uvicorn = "*"
gunicorn = "*"
dictor = "*"
django-recaptcha = "*"
python-magic = "*"
python-dotenv = "*"
django-debug-toolbar = "*"
[dev-packages]
[requires]
python_version = "3.10"
[scripts]
dev = "python manage.py runserver 127.0.0.1:8000"
prod = "gunicorn django_app.wsgi:application -k gthread -w 2 --threads 8"
### distribute variables according to .env file
if os.getenv("SITE_ENV") == "dev":
SECRET_KEY = os.getenv("SECRET_KEY")
ALLOWED_HOSTS = ["localhost", "*"]
#CSRF_TRUSTED_ORIGINS = ["localhost"]
DOMAIN = "http://localhost:8000"
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = False
SESSION_COOKIE_SAMESITE = 'Strict'
DEBUG = True
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "http"
## DEBUG TOOLS
INSTALLED_APPS.append("debug_toolbar")
MIDDLEWARE.append("debug_toolbar.middleware.DebugToolbarMiddleware")
INTERNAL_IPS = ["127.0.0.1"]
DEBUG_TOOLBAR_CONFIG = {
'RENDER_PANELS': True,
'RESULTS_CACHE_SIZE': 100,
'RESULTS_STORE_SIZE': 30, # Required for ddt_request_history
'SHOW_TOOLBAR_CALLBACK': lambda request: True
}
else:
SECRET_KEY = os.getenv("SECRET_KEY")
ALLOWED_HOSTS = ["www.myhost.com", "myhost.com", "https://myhost.com", "<additional IPs>"]
CSRF_TRUSTED_ORIGINS = ["https://myhost.com"]
CSRF_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_PRELOAD = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
DOMAIN = "https://www.myhost.com"
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "live.smtp.mailtrap.io"
EMAIL_PORT = 2525
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
DEFAULT_FROM_EMAIL = "[email protected]"
# prevent client side scripts from accessing cookies
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = 'Lax'
SESSION_COOKIE_DOMAIN = None
DEBUG = False
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
## place in /etc/systemd/system/myapp.service - if change this, run sudo systemctl --daemon-reload
[Service]
Type=simple
User=joe
WorkingDirectory=/home/joe/django_proj/django_app
ExecStart=/bin/pipenv run prod
Restart=on-failure
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment