mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2024-11-26 03:24:01 +03:00
merge @mjsisley #576
This commit is contained in:
commit
94cb04b389
|
@ -97,6 +97,7 @@ Listed in alphabetical order.
|
|||
Matt Linares
|
||||
Matt Menzenski `@menzenski`_
|
||||
Matt Warren `@mfwarren`_
|
||||
Matthew Sisley `@mjsisley`_
|
||||
Meghan Heintz `@dot2dotseurat`_
|
||||
mjsisley `@mjsisley`_
|
||||
mozillazg `@mozillazg`_
|
||||
|
@ -183,6 +184,7 @@ Listed in alphabetical order.
|
|||
.. _@yunti: https://github.com/yunti
|
||||
.. _@zcho: https://github.com/zcho
|
||||
.. _@noisy: https://github.com/noisy
|
||||
.. _@mjsisley: https://github.com/mjsisley
|
||||
Special Thanks
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -21,5 +21,6 @@
|
|||
"use_docker": "y",
|
||||
"use_heroku": "n",
|
||||
"js_task_runner": ["Gulp", "Grunt", "None"],
|
||||
"use_certbot": "n",
|
||||
"open_source_license": ["MIT", "BSD", "Apache Software License 2.0", "Not open source"]
|
||||
}
|
||||
|
|
|
@ -110,3 +110,47 @@ To get the status, run::
|
|||
If you have errors, you can always check your stack with `docker-compose`. Switch to your projects root directory and run::
|
||||
|
||||
docker-compose ps
|
||||
|
||||
If you are using certbot for https, you must do the following before running anything with docker-compose:
|
||||
|
||||
Replace dhparam.pem.example with a generated dhparams.pem file before running anything with docker-compose. You can generate this on ubuntu or OS X by running the following in the project root:
|
||||
|
||||
::
|
||||
|
||||
$ openssl dhparam -out /path/to/project/compose/nginx/dhparams.pem 2048
|
||||
|
||||
If you would like to add additional subdomains to your certificate, you must add additional parameters to the certbot command in the `docker-compose.yml` file:
|
||||
|
||||
Replace:
|
||||
|
||||
::
|
||||
|
||||
command: bash -c "sleep 6 && certbot certonly -n --standalone -d {{ cookiecutter.domain_name }} --text --agree-tos --email mjsisley@relawgo.com --server https://acme-v01.api.letsencrypt.org/directory --rsa-key-size 4096 --verbose --keep-until-expiring --standalone-supported-challenges http-01"
|
||||
|
||||
With:
|
||||
|
||||
::
|
||||
|
||||
command: bash -c "sleep 6 && certbot certonly -n --standalone -d {{ cookiecutter.domain_name }} -d www.{{ cookiecutter.domain_name }} -d etc.{{ cookiecutter.domain_name }} --text --agree-tos --email {{ cookiecutter.email }} --server https://acme-v01.api.letsencrypt.org/directory --rsa-key-size 4096 --verbose --keep-until-expiring --standalone-supported-challenges http-01"
|
||||
|
||||
Please be cognizant of Certbot/Letsencrypt certificate requests limits when getting this set up. The provide a test server that does not count against the limit while you are getting set up.
|
||||
|
||||
The certbot certificates expire after 3 months.
|
||||
If you would like to set up autorenewal of your certificates, the following commands can be put into a bash script:
|
||||
|
||||
::
|
||||
|
||||
#!/bin/bash
|
||||
cd <project directory>
|
||||
docker-compose run certbot bash -c "sleep 6 && certbot certonly --standalone -d {{ cookiecutter.domain_name }} --text --agree-tos --email {{ cookiecutter.email }} --server https://acme-v01.api.letsencrypt.org/directory --rsa-key-size 4096 --verbose --keep-until-expiring --standalone-supported-challenges http-01"
|
||||
docker exec pearl_nginx_1 nginx -s reload
|
||||
|
||||
And then set a cronjob by running `crontab -e` and placing in it (period can be adjusted as desired):
|
||||
|
||||
0 4 * * 1 /path/to/bashscript/renew_certbot.sh
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@ Then you may need to run the following for it to work as desired:
|
|||
|
||||
$ docker-compose run -f dev.yml --service-ports django
|
||||
|
||||
|
||||
django-debug-toolbar
|
||||
""""""""""""""""""""
|
||||
|
||||
|
|
|
@ -157,6 +157,16 @@ def remove_packageJSON_file():
|
|||
PROJECT_DIRECTORY, filename
|
||||
))
|
||||
|
||||
def remove_certbot_files():
|
||||
"""
|
||||
Removes files needed for certbot if it isn't going to be used
|
||||
"""
|
||||
nginx_dir_location = os.path.join(PROJECT_DIRECTORY, 'compose/nginx')
|
||||
for filename in ["nginx-secure.conf", "start.sh", "dhparams.example.pem"]:
|
||||
os.remove(os.path.join(
|
||||
nginx_dir_location, filename
|
||||
))
|
||||
|
||||
# IN PROGRESS
|
||||
# def copy_doc_files(project_directory):
|
||||
# cookiecutters_dir = DEFAULT_CONFIG['cookiecutters_dir']
|
||||
|
@ -204,9 +214,12 @@ else:
|
|||
remove_grunt_files()
|
||||
remove_packageJSON_file()
|
||||
|
||||
# 7. Removes all certbot/letsencrypt files if it isn't going to be used
|
||||
if '{{ cookiecutter.use_certbot }}'.lower() != 'y':
|
||||
remove_certbot_files()
|
||||
|
||||
# 7. Display a warning if use_docker and js task runner are selected. Grunt isn't supported by our
|
||||
# docker config atm.
|
||||
# 8. Display a warning if use_docker and use_grunt are selected. Grunt isn't
|
||||
# supported by our docker config atm.
|
||||
if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt', 'gulp'] and '{{ cookiecutter.use_docker }}'.lower() == 'y':
|
||||
print(
|
||||
"You selected to use docker and a JS task runner. This is NOT supported out of the box for now. You "
|
||||
|
@ -214,13 +227,19 @@ if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt', 'gulp'] and '{{ cook
|
|||
"js task runner service to your docker configuration manually."
|
||||
)
|
||||
|
||||
# 7. Display a warning if use_docker and use_mailhog are selected. Mailhog isn't supported by our
|
||||
# docker config atm.
|
||||
if '{{ cookiecutter.use_mailhog }}'.lower() == 'y' and '{{ cookiecutter.use_docker }}'.lower() == 'y':
|
||||
# 9. Removes the certbot/letsencrypt files and display a warning if use_certbot is selected and use_docker isn't.
|
||||
if '{{ cookiecutter.use_certbot }}'.lower() == 'y' and '{{ cookiecutter.use_docker }}'.lower() != 'y':
|
||||
remove_certbot_files()
|
||||
print(
|
||||
"You selected to use docker and mailhog. This is NOT supported out of the box for now. You"
|
||||
" can continue to use the project like you normally would, but you will need to add a "
|
||||
" mailhog service to your docker configuration manually."
|
||||
"You selected to use certbot(letsencrypt) and didn't select to use docker. This is NOT supported out of the box for now. You "
|
||||
"can continue to use the project like you normally would, but you will no certbot files have been included"
|
||||
)
|
||||
|
||||
# 10. Directs the user to the documentation if certbot and docker are selected.
|
||||
if '{{ cookiecutter.use_certbot }}'.lower() == 'y' and '{{ cookiecutter.use_docker }}'.lower() == 'y':
|
||||
print(
|
||||
"You selected to use certbot(letsencrypt), please see the documentation for instructions on how to use this in production. "
|
||||
"You must generate a dhparams.pem file before running docker-compose in a production environment."
|
||||
)
|
||||
|
||||
# 4. Copy files from /docs/ to {{ cookiecutter.project_slug }}/docs/
|
||||
|
|
|
@ -1,2 +1,8 @@
|
|||
FROM nginx:latest
|
||||
ADD nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
{% if cookiecutter.use_certbot == 'y' and cookiecutter.use_docker == 'y' %}
|
||||
ADD start.sh /start.sh
|
||||
ADD nginx-secure.conf /etc/nginx/nginx-secure.conf
|
||||
ADD dhparams.pem /etc/ssl/private/dhparams.pem
|
||||
{% endif %}
|
||||
|
|
3
{{cookiecutter.project_slug}}/compose/nginx/dhparams.example.pem
Executable file
3
{{cookiecutter.project_slug}}/compose/nginx/dhparams.example.pem
Executable file
|
@ -0,0 +1,3 @@
|
|||
-----BEGIN DH PARAMETERS-----
|
||||
EXAMPLE_FILE
|
||||
-----END DH PARAMETERS-----
|
92
{{cookiecutter.project_slug}}/compose/nginx/nginx-secure.conf
Executable file
92
{{cookiecutter.project_slug}}/compose/nginx/nginx-secure.conf
Executable file
|
@ -0,0 +1,92 @@
|
|||
user nginx;
|
||||
worker_processes 1;
|
||||
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
proxy_headers_hash_bucket_size 52;
|
||||
|
||||
gzip on;
|
||||
|
||||
upstream app {
|
||||
server django:5000;
|
||||
}
|
||||
server {
|
||||
listen 80;
|
||||
server_name ___my.example.com___ www.___my.example.com___;
|
||||
|
||||
location /.well-known/acme-challenge {
|
||||
proxy_pass http://___LETSENCRYPT_IP___:___LETSENCRYPT_PORT___;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
server_name ___my.example.com___ www.___my.example.com___;
|
||||
|
||||
ssl on;
|
||||
ssl_certificate /etc/letsencrypt/live/___my.example.com___/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/___my.example.com___/privkey.pem;
|
||||
ssl_session_timeout 5m;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_dhparam /etc/ssl/private/dhparams.pem;
|
||||
|
||||
location /.well-known/acme-challenge {
|
||||
proxy_pass http://___LETSENCRYPT_HTTPS_IP___:___LETSENCRYPT_HTTPS_PORT___;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
}
|
||||
|
||||
location / {
|
||||
# checks for static file, if not found proxy to app
|
||||
try_files $uri @proxy_to_app;
|
||||
}
|
||||
|
||||
# cookiecutter-django app
|
||||
location @proxy_to_app {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_redirect off;
|
||||
|
||||
proxy_pass http://app;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -9,9 +9,9 @@ events {
|
|||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
|
@ -31,23 +31,40 @@ http {
|
|||
server django:5000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
charset utf-8;
|
||||
server {
|
||||
listen 80;
|
||||
charset utf-8;
|
||||
|
||||
{% if cookiecutter.use_certbot == 'y' and cookiecutter.use_docker == 'y' %}
|
||||
server_name ___my.example.com___ ;
|
||||
|
||||
location / {
|
||||
location /.well-known/acme-challenge {
|
||||
proxy_pass http://___LETSENCRYPT_IP___:___LETSENCRYPT_PORT___;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
|
||||
location / {
|
||||
# checks for static file, if not found proxy to app
|
||||
try_files $uri @proxy_to_app;
|
||||
}
|
||||
|
||||
location @proxy_to_app {
|
||||
|
||||
# cookiecutter-django app
|
||||
location @proxy_to_app {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_redirect off;
|
||||
|
||||
proxy_pass http://app;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
81
{{cookiecutter.project_slug}}/compose/nginx/start.sh
Executable file
81
{{cookiecutter.project_slug}}/compose/nginx/start.sh
Executable file
|
@ -0,0 +1,81 @@
|
|||
echo sleep 5
|
||||
sleep 5
|
||||
|
||||
echo build starting nginx config
|
||||
|
||||
|
||||
echo replacing ___my.example.com___/$MY_DOMAIN_NAME
|
||||
echo replacing ___LETSENCRYPT_IP___/$LETSENCRYPT_PORT_80_TCP_ADDR
|
||||
echo replacing ___LETSENCRYPT_PORT___/$LETSENCRYPT_PORT_80_TCP_PORT
|
||||
echo replacing ___APPLICATION_IP___/$APP_PORT_80_TCP_ADDR
|
||||
echo replacing ___APPLICATION_PORT___/$APP_PORT_80_TCP_PORT
|
||||
|
||||
# Put your domain name into the nginx reverse proxy config.
|
||||
sed -i "s/___my.example.com___/$MY_DOMAIN_NAME/g" /etc/nginx/nginx.conf
|
||||
# Add your app's container IP and port into config
|
||||
sed -i "s/___APPLICATION_IP___/$APP_PORT_80_TCP_ADDR/g" /etc/nginx/nginx.conf
|
||||
sed -i "s/___APPLICATION_PORT___/$APP_PORT_80_TCP_PORT/g" /etc/nginx/nginx.conf
|
||||
sed -i "s/___LETSENCRYPT_IP___/$LETSENCRYPT_PORT_80_TCP_ADDR/g" /etc/nginx/nginx.conf
|
||||
sed -i "s/___LETSENCRYPT_PORT___/$LETSENCRYPT_PORT_80_TCP_PORT/g" /etc/nginx/nginx.conf
|
||||
|
||||
cat /etc/nginx/nginx.conf
|
||||
echo .
|
||||
echo Firing up nginx in the background.
|
||||
nginx
|
||||
|
||||
# # Check user has specified domain name
|
||||
if [ -z "$MY_DOMAIN_NAME" ]; then
|
||||
echo "Need to set MY_DOMAIN_NAME (to a letsencrypt-registered name)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# This bit waits until the letsencrypt container has done its thing.
|
||||
# We see the changes here bceause there's a docker volume mapped.
|
||||
echo Waiting for folder /etc/letsencrypt/live/$MY_DOMAIN_NAME to exist
|
||||
while [ ! -d /etc/letsencrypt/live/$MY_DOMAIN_NAME ] ;
|
||||
do
|
||||
sleep 2
|
||||
done
|
||||
|
||||
while [ ! -f /etc/letsencrypt/live/$MY_DOMAIN_NAME/fullchain.pem ] ;
|
||||
do
|
||||
echo Waiting for file fullchain.pem to exist
|
||||
sleep 2
|
||||
done
|
||||
|
||||
while [ ! -f /etc/letsencrypt/live/$MY_DOMAIN_NAME/privkey.pem ] ;
|
||||
do
|
||||
echo Waiting for file privkey.pem to exist
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# This is added so that when the certificate is being renewed or is already in place, nginx waits for everything to be good.
|
||||
sleep 15
|
||||
|
||||
echo replacing ___my.example.com___/$MY_DOMAIN_NAME
|
||||
echo replacing ___LETSENCRYPT_IP___/$LETSENCRYPT_PORT_80_TCP_ADDR
|
||||
echo replacing ___LETSENCRYPT_PORT___/$LETSENCRYPT_PORT_80_TCP_PORT
|
||||
echo replacing ___LETSENCRYPT_HTTPS_IP___/$LETSENCRYPT_PORT_443_TCP_ADDR
|
||||
echo replacing ___LETSENCRYPT_HTTPS_PORT___/$LETSENCRYPT_PORT_443_TCP_PORT
|
||||
echo replacing ___APPLICATION_IP___/$APP_PORT_80_TCP_ADDR
|
||||
echo replacing ___APPLICATION_PORT___/$APP_PORT_80_TCP_PORT
|
||||
|
||||
|
||||
# Put your domain name into the nginx reverse proxy config.
|
||||
sed -i "s/___my.example.com___/$MY_DOMAIN_NAME/g" /etc/nginx/nginx-secure.conf
|
||||
|
||||
# Add LE container IP and port into config
|
||||
sed -i "s/___LETSENCRYPT_IP___/$LETSENCRYPT_PORT_80_TCP_ADDR/g" /etc/nginx/nginx-secure.conf
|
||||
sed -i "s/___LETSENCRYPT_PORT___/$LETSENCRYPT_PORT_80_TCP_PORT/g" /etc/nginx/nginx-secure.conf
|
||||
sed -i "s/___LETSENCRYPT_HTTPS_IP___/$LETSENCRYPT_PORT_443_TCP_ADDR/g" /etc/nginx/nginx-secure.conf
|
||||
sed -i "s/___LETSENCRYPT_HTTPS_PORT___/$LETSENCRYPT_PORT_443_TCP_PORT/g" /etc/nginx/nginx-secure.conf
|
||||
|
||||
# Add your app's container IP and port into config
|
||||
sed -i "s/___APPLICATION_IP___/$APP_PORT_80_TCP_ADDR/g" /etc/nginx/nginx-secure.conf
|
||||
sed -i "s/___APPLICATION_PORT___/$APP_PORT_80_TCP_PORT/g" /etc/nginx/nginx-secure.conf
|
||||
|
||||
#go!
|
||||
kill $(ps aux | grep 'nginx' | awk '{print $2}')
|
||||
cp /etc/nginx/nginx-secure.conf /etc/nginx/nginx.conf
|
||||
|
||||
nginx -g 'daemon off;'
|
|
@ -27,12 +27,38 @@ services:
|
|||
build: ./compose/nginx
|
||||
depends_on:
|
||||
- django
|
||||
{% if cookiecutter.use_certbot == 'y' %}
|
||||
- certbot
|
||||
{% endif %}
|
||||
ports:
|
||||
- "0.0.0.0:80:80"
|
||||
{% if cookiecutter.use_certbot == 'y' %}
|
||||
environment:
|
||||
- MY_DOMAIN_NAME={{ cookiecutter.domain_name }}
|
||||
ports:
|
||||
- "0.0.0.0:80:80"
|
||||
- "0.0.0.0:443:443"
|
||||
volumes:
|
||||
- /etc/letsencrypt:/etc/letsencrypt
|
||||
- /var/lib/letsencrypt:/var/lib/letsencrypt
|
||||
|
||||
certbot:
|
||||
image: quay.io/letsencrypt/letsencrypt
|
||||
command: bash -c "sleep 6 && certbot certonly -n --standalone -d {{ cookiecutter.domain_name }} --text --agree-tos --email {{ cookiecutter.email }} --server https://acme-v01.api.letsencrypt.org/directory --rsa-key-size 4096 --verbose --keep-until-expiring --standalone-supported-challenges http-01"
|
||||
entrypoint: ""
|
||||
volumes:
|
||||
- /etc/letsencrypt:/etc/letsencrypt
|
||||
- /var/lib/letsencrypt:/var/lib/letsencrypt
|
||||
ports:
|
||||
- "80"
|
||||
- "443"
|
||||
environment:
|
||||
- TERM=xterm
|
||||
{% endif %}
|
||||
|
||||
redis:
|
||||
image: redis:3.0
|
||||
{% if cookiecutter.use_celery == 'y' %}
|
||||
{% if cookiecutter.use_celery == 'y' %}
|
||||
celeryworker:
|
||||
build:
|
||||
context: .
|
||||
|
@ -54,4 +80,4 @@ services:
|
|||
- postgres
|
||||
- redis
|
||||
command: celery -A {{cookiecutter.project_slug}}.taskapp beat -l INFO
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
Loading…
Reference in New Issue
Block a user