mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-08-09 06:24:52 +03:00
Introduce unified Docker / Docker Compose infrastructure
This commit is contained in:
parent
3ac9902670
commit
36535770d1
|
@ -46,7 +46,7 @@ You will probably also need to setup the Mail backend, for example by adding a `
|
||||||
Optional: Use AWS IAM Role for EC2 instance
|
Optional: Use AWS IAM Role for EC2 instance
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
If you are deploying to AWS, you can use the IAM role to substitute AWS credentials, after which it's safe to remove the ``AWS_ACCESS_KEY_ID`` AND ``AWS_SECRET_ACCESS_KEY`` from ``.envs/.production/.django``. To do it, create an `IAM role`_ and `attach`_ it to the existing EC2 instance or create a new EC2 instance with that role. The role should assume, at minimum, the ``AmazonS3FullAccess`` permission.
|
If you are deploying to AWS, you can use the IAM role to substitute AWS credentials, after which it's safe to remove the ``AWS_ACCESS_KEY_ID`` AND ``AWS_SECRET_ACCESS_KEY`` from ``.envs/.django``. To do it, create an `IAM role`_ and `attach`_ it to the existing EC2 instance or create a new EC2 instance with that role. The role should assume, at minimum, the ``AmazonS3FullAccess`` permission.
|
||||||
|
|
||||||
.. _IAM role: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
|
.. _IAM role: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
|
||||||
.. _attach: https://aws.amazon.com/blogs/security/easily-replace-or-attach-an-iam-role-to-an-existing-ec2-instance-by-using-the-ec2-console/
|
.. _attach: https://aws.amazon.com/blogs/security/easily-replace-or-attach-an-iam-role-to-an-existing-ec2-instance-by-using-the-ec2-console/
|
||||||
|
|
|
@ -87,31 +87,24 @@ This is the excerpt from your project's ``local.yml``: ::
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
build:
|
# ...
|
||||||
context: .
|
|
||||||
dockerfile: ./compose/production/postgres/Dockerfile
|
|
||||||
volumes:
|
|
||||||
- local_postgres_data:/var/lib/postgresql/data
|
|
||||||
- local_postgres_data_backups:/backups
|
|
||||||
env_file:
|
env_file:
|
||||||
- ./.envs/.local/.postgres
|
- ./.envs/.postgres.local
|
||||||
|
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
The most important thing for us here now is ``env_file`` section enlisting ``./.envs/.local/.postgres``. Generally, the stack's behavior is governed by a number of environment variables (`env(s)`, for short) residing in ``envs/``, for instance, this is what we generate for you: ::
|
The most important thing for us here now is ``env_file`` section enlisting ``./.envs/.postgres.local``. Generally, the stack's behavior is governed by a number of environment variables (`env(s)`, for short) residing in ``envs/``, for instance, this is what we generate for you: ::
|
||||||
|
|
||||||
.envs
|
.envs
|
||||||
├── .local
|
|
||||||
│ ├── .django
|
|
||||||
│ └── .postgres
|
|
||||||
└── .production
|
|
||||||
├── .caddy
|
├── .caddy
|
||||||
├── .django
|
├── .django
|
||||||
└── .postgres
|
├── .django.local
|
||||||
|
├── .postgres
|
||||||
|
└── .postgres.local
|
||||||
|
|
||||||
By convention, for any service ``sI`` in environment ``e`` (you know ``someenv`` is an environment when there is a ``someenv.yml`` file in the project root), given ``sI`` requires configuration, a ``.envs/.e/.sI`` `service configuration` file exists.
|
By convention, for any service ``sI`` in environment ``e`` (you know ``someenv`` is an environment when there is a ``someenv.yml`` file in the project root), given ``sI`` requires configuration, a ``.envs/.sI(.e)`` `service configuration` file exists.
|
||||||
|
|
||||||
Consider the aforementioned ``.envs/.local/.postgres``: ::
|
Consider the aforementioned ``.envs/.postgres.local``: ::
|
||||||
|
|
||||||
# PostgreSQL
|
# PostgreSQL
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -122,7 +115,7 @@ Consider the aforementioned ``.envs/.local/.postgres``: ::
|
||||||
|
|
||||||
The three envs we are presented with here are ``POSTGRES_DB``, ``POSTGRES_USER``, and ``POSTGRES_PASSWORD`` (by the way, their values have also been generated for you). You might have figured out already where these definitions will end up; it's all the same with ``django`` and ``caddy`` service container envs.
|
The three envs we are presented with here are ``POSTGRES_DB``, ``POSTGRES_USER``, and ``POSTGRES_PASSWORD`` (by the way, their values have also been generated for you). You might have figured out already where these definitions will end up; it's all the same with ``django`` and ``caddy`` service container envs.
|
||||||
|
|
||||||
One final touch: should you ever need to merge ``.envs/production/*`` in a single ``.env`` run the ``merge_production_dotenvs_in_dotenv.py``: ::
|
One final touch: should you ever need to merge ``.envs/*`` (except ``.envs/*.local``) in a single ``.env`` run the ``merge_production_dotenvs_in_dotenv.py``: ::
|
||||||
|
|
||||||
$ python merge_production_dotenvs_in_dotenv.py
|
$ python merge_production_dotenvs_in_dotenv.py
|
||||||
|
|
||||||
|
@ -184,6 +177,6 @@ Prerequisites:
|
||||||
* ``use_docker`` was set to ``y`` on project initialization;
|
* ``use_docker`` was set to ``y`` on project initialization;
|
||||||
* ``use_celery`` was set to ``y`` on project initialization.
|
* ``use_celery`` was set to ``y`` on project initialization.
|
||||||
|
|
||||||
By default, it's enabled both in local and production environments (``local.yml`` and ``production.yml`` Docker Compose configs, respectively) through a ``flower`` service. For added security, ``flower`` requires its clients to provide authentication credentials specified as the corresponding environments' ``.envs/.local/.django`` and ``.envs/.production/.django`` ``CELERY_FLOWER_USER`` and ``CELERY_FLOWER_PASSWORD`` environment variables. Check out ``localhost:5555`` and see for yourself.
|
By default, it's enabled both in local and production environments (``local.yml`` and ``production.yml`` Docker Compose configs, respectively) through a ``flower`` service. For added security, ``flower`` requires its clients to provide authentication credentials specified as the corresponding environments' ``.envs/.django.local`` and ``.envs/.production/.django`` ``CELERY_FLOWER_USER`` and ``CELERY_FLOWER_PASSWORD`` environment variables. Check out ``localhost:5555`` and see for yourself.
|
||||||
|
|
||||||
.. _`Flower`: https://github.com/mher/flower
|
.. _`Flower`: https://github.com/mher/flower
|
||||||
|
|
|
@ -91,7 +91,7 @@ use_travisci:
|
||||||
Indicates whether the project should be configured to use `Travis CI`_.
|
Indicates whether the project should be configured to use `Travis CI`_.
|
||||||
|
|
||||||
keep_local_envs_in_vcs:
|
keep_local_envs_in_vcs:
|
||||||
Indicates whether the project's ``.envs/.local/`` should be kept in VCS
|
Indicates whether the project's ``.envs/*.local`` should be kept in VCS
|
||||||
(comes in handy when working in teams where local environment reproducibility
|
(comes in handy when working in teams where local environment reproducibility
|
||||||
is strongly encouraged).
|
is strongly encouraged).
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ def remove_pycharm_files():
|
||||||
|
|
||||||
|
|
||||||
def remove_docker_files():
|
def remove_docker_files():
|
||||||
shutil.rmtree("compose")
|
shutil.rmtree("docker")
|
||||||
|
|
||||||
file_names = ["local.yml", "production.yml", ".dockerignore"]
|
file_names = ["local.yml", "production.yml", ".dockerignore"]
|
||||||
for file_name in file_names:
|
for file_name in file_names:
|
||||||
|
@ -223,10 +223,10 @@ def set_flags_in_envs(
|
||||||
celery_flower_user,
|
celery_flower_user,
|
||||||
debug=False,
|
debug=False,
|
||||||
):
|
):
|
||||||
local_django_envs_path = os.path.join(".envs", ".local", ".django")
|
local_django_envs_path = os.path.join(".envs", ".django.local")
|
||||||
production_django_envs_path = os.path.join(".envs", ".production", ".django")
|
production_django_envs_path = os.path.join(".envs", ".django")
|
||||||
local_postgres_envs_path = os.path.join(".envs", ".local", ".postgres")
|
local_postgres_envs_path = os.path.join(".envs", ".postgres.local")
|
||||||
production_postgres_envs_path = os.path.join(".envs", ".production", ".postgres")
|
production_postgres_envs_path = os.path.join(".envs", ".postgres")
|
||||||
|
|
||||||
set_django_secret_key(production_django_envs_path)
|
set_django_secret_key(production_django_envs_path)
|
||||||
set_django_admin_url(production_django_envs_path)
|
set_django_admin_url(production_django_envs_path)
|
||||||
|
@ -252,9 +252,14 @@ def remove_envs_and_associated_files():
|
||||||
os.remove("merge_production_dotenvs_in_dotenv.py")
|
os.remove("merge_production_dotenvs_in_dotenv.py")
|
||||||
|
|
||||||
|
|
||||||
def remove_celery_compose_dirs():
|
def remove_django_celery_docker_scripts():
|
||||||
shutil.rmtree(os.path.join("compose", "local", "django", "celery"))
|
file_names = [
|
||||||
shutil.rmtree(os.path.join("compose", "production", "django", "celery"))
|
"celerybeat",
|
||||||
|
"celeryworker",
|
||||||
|
"flower"
|
||||||
|
]
|
||||||
|
for file_name in file_names:
|
||||||
|
os.remove(os.path.join("docker", "django", "scripts", file_name))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -296,7 +301,7 @@ def main():
|
||||||
append_to_gitignore_file(".env")
|
append_to_gitignore_file(".env")
|
||||||
append_to_gitignore_file(".envs/*")
|
append_to_gitignore_file(".envs/*")
|
||||||
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
|
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
|
||||||
append_to_gitignore_file("!.envs/.local/")
|
append_to_gitignore_file("!.envs/*.local")
|
||||||
|
|
||||||
if "{{ cookiecutter.js_task_runner}}".lower() == "none":
|
if "{{ cookiecutter.js_task_runner}}".lower() == "none":
|
||||||
remove_gulp_files()
|
remove_gulp_files()
|
||||||
|
@ -320,7 +325,7 @@ def main():
|
||||||
if "{{ cookiecutter.use_celery }}".lower() == "n":
|
if "{{ cookiecutter.use_celery }}".lower() == "n":
|
||||||
remove_celery_app()
|
remove_celery_app()
|
||||||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||||
remove_celery_compose_dirs()
|
remove_django_celery_docker_scripts()
|
||||||
|
|
||||||
if "{{ cookiecutter.use_travisci }}".lower() == "n":
|
if "{{ cookiecutter.use_travisci }}".lower() == "n":
|
||||||
remove_dottravisyml_file()
|
remove_dottravisyml_file()
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
FROM python:3.6-alpine
|
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED 1
|
|
||||||
|
|
||||||
RUN apk update \
|
|
||||||
# psycopg2 dependencies
|
|
||||||
&& apk add --virtual build-deps gcc python3-dev musl-dev \
|
|
||||||
&& apk add postgresql-dev \
|
|
||||||
# Pillow dependencies
|
|
||||||
&& apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
|
|
||||||
# CFFI dependencies
|
|
||||||
&& apk add libffi-dev py-cffi \
|
|
||||||
# Translations dependencies
|
|
||||||
&& apk add gettext \
|
|
||||||
# https://docs.djangoproject.com/en/dev/ref/django-admin/#dbshell
|
|
||||||
&& apk add postgresql-client
|
|
||||||
|
|
||||||
# Requirements are installed here to ensure they will be cached.
|
|
||||||
COPY ./requirements /requirements
|
|
||||||
RUN pip install -r /requirements/local.txt
|
|
||||||
|
|
||||||
COPY ./compose/production/django/entrypoint /entrypoint
|
|
||||||
RUN sed -i 's/\r//' /entrypoint
|
|
||||||
RUN chmod +x /entrypoint
|
|
||||||
|
|
||||||
COPY ./compose/local/django/start /start
|
|
||||||
RUN sed -i 's/\r//' /start
|
|
||||||
RUN chmod +x /start
|
|
||||||
{% if cookiecutter.use_celery == "y" %}
|
|
||||||
COPY ./compose/local/django/celery/worker/start /start-celeryworker
|
|
||||||
RUN sed -i 's/\r//' /start-celeryworker
|
|
||||||
RUN chmod +x /start-celeryworker
|
|
||||||
|
|
||||||
COPY ./compose/local/django/celery/beat/start /start-celerybeat
|
|
||||||
RUN sed -i 's/\r//' /start-celerybeat
|
|
||||||
RUN chmod +x /start-celerybeat
|
|
||||||
|
|
||||||
COPY ./compose/local/django/celery/flower/start /start-flower
|
|
||||||
RUN sed -i 's/\r//' /start-flower
|
|
||||||
RUN chmod +x /start-flower
|
|
||||||
{% endif %}
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
ENTRYPOINT ["/entrypoint"]
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
|
|
||||||
rm -f './celerybeat.pid'
|
|
||||||
celery -A {{cookiecutter.project_slug}}.taskapp beat -l INFO
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
|
|
||||||
celery flower \
|
|
||||||
--app={{cookiecutter.project_slug}}.taskapp \
|
|
||||||
--broker="${CELERY_BROKER_URL}" \
|
|
||||||
--basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}"
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
|
|
||||||
celery -A {{cookiecutter.project_slug}}.taskapp worker -l INFO
|
|
|
@ -1,3 +0,0 @@
|
||||||
FROM abiosoft/caddy:0.11.0
|
|
||||||
|
|
||||||
COPY ./compose/production/caddy/Caddyfile /etc/Caddyfile
|
|
|
@ -1,54 +0,0 @@
|
||||||
FROM python:3.6-alpine
|
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED 1
|
|
||||||
|
|
||||||
RUN apk update \
|
|
||||||
# psycopg2 dependencies
|
|
||||||
&& apk add --virtual build-deps gcc python3-dev musl-dev \
|
|
||||||
&& apk add postgresql-dev \
|
|
||||||
# Pillow dependencies
|
|
||||||
&& apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
|
|
||||||
# CFFI dependencies
|
|
||||||
&& apk add libffi-dev py-cffi
|
|
||||||
|
|
||||||
RUN addgroup -S django \
|
|
||||||
&& adduser -S -G django django
|
|
||||||
|
|
||||||
# Requirements are installed here to ensure they will be cached.
|
|
||||||
COPY ./requirements /requirements
|
|
||||||
RUN pip install --no-cache-dir -r /requirements/production.txt \
|
|
||||||
&& rm -rf /requirements
|
|
||||||
|
|
||||||
COPY ./compose/production/django/entrypoint /entrypoint
|
|
||||||
RUN sed -i 's/\r//' /entrypoint
|
|
||||||
RUN chmod +x /entrypoint
|
|
||||||
RUN chown django /entrypoint
|
|
||||||
|
|
||||||
COPY ./compose/production/django/start /start
|
|
||||||
RUN sed -i 's/\r//' /start
|
|
||||||
RUN chmod +x /start
|
|
||||||
RUN chown django /start
|
|
||||||
{% if cookiecutter.use_celery == "y" %}
|
|
||||||
COPY ./compose/production/django/celery/worker/start /start-celeryworker
|
|
||||||
RUN sed -i 's/\r//' /start-celeryworker
|
|
||||||
RUN chmod +x /start-celeryworker
|
|
||||||
RUN chown django /start-celeryworker
|
|
||||||
|
|
||||||
COPY ./compose/production/django/celery/beat/start /start-celerybeat
|
|
||||||
RUN sed -i 's/\r//' /start-celerybeat
|
|
||||||
RUN chmod +x /start-celerybeat
|
|
||||||
RUN chown django /start-celerybeat
|
|
||||||
|
|
||||||
COPY ./compose/production/django/celery/flower/start /start-flower
|
|
||||||
RUN sed -i 's/\r//' /start-flower
|
|
||||||
RUN chmod +x /start-flower
|
|
||||||
{% endif %}
|
|
||||||
COPY . /app
|
|
||||||
|
|
||||||
RUN chown -R django /app
|
|
||||||
|
|
||||||
USER django
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
ENTRYPOINT ["/entrypoint"]
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o pipefail
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
|
|
||||||
celery -A {{cookiecutter.project_slug}}.taskapp beat -l INFO
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
|
|
||||||
celery flower \
|
|
||||||
--app={{cookiecutter.project_slug}}.taskapp \
|
|
||||||
--broker="${CELERY_BROKER_URL}" \
|
|
||||||
--basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}"
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o pipefail
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
|
|
||||||
celery -A {{cookiecutter.project_slug}}.taskapp worker -l INFO
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o pipefail
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
|
|
||||||
python /app/manage.py collectstatic --noinput
|
|
||||||
/usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app
|
|
|
@ -1,6 +0,0 @@
|
||||||
FROM postgres:{{ cookiecutter.postgresql_version }}
|
|
||||||
|
|
||||||
COPY ./compose/production/postgres/maintenance /usr/local/bin/maintenance
|
|
||||||
RUN chmod +x /usr/local/bin/maintenance/*
|
|
||||||
RUN mv /usr/local/bin/maintenance/* /usr/local/bin \
|
|
||||||
&& rmdir /usr/local/bin/maintenance
|
|
3
{{cookiecutter.project_slug}}/docker/caddy/Dockerfile
Normal file
3
{{cookiecutter.project_slug}}/docker/caddy/Dockerfile
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
FROM abiosoft/caddy:0.11.0
|
||||||
|
|
||||||
|
COPY ./Caddyfile /etc/Caddyfile
|
46
{{cookiecutter.project_slug}}/docker/django/Dockerfile
Normal file
46
{{cookiecutter.project_slug}}/docker/django/Dockerfile
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
FROM python:3.6-alpine
|
||||||
|
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
ARG environment
|
||||||
|
|
||||||
|
RUN apk update \
|
||||||
|
# psycopg2 dependencies
|
||||||
|
&& apk add --virtual build-deps gcc python3-dev musl-dev \
|
||||||
|
&& apk add postgresql-dev \
|
||||||
|
# Pillow dependencies
|
||||||
|
&& apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
|
||||||
|
# CFFI dependencies
|
||||||
|
&& apk add libffi-dev py-cffi \
|
||||||
|
&& [ "${environment}" != 'production' ] && apk add \
|
||||||
|
# Translations dependencies
|
||||||
|
gettext \
|
||||||
|
# and https://docs.djangoproject.com/en/dev/ref/django-admin/#dbshell
|
||||||
|
postgresql-client
|
||||||
|
|
||||||
|
COPY ./requirements/ /app/requirements/
|
||||||
|
WORKDIR /app/
|
||||||
|
RUN [ "${environment}" = 'production' ] && pip --no-cache-dir install -r "./requirements/${environment}.txt" || pip install -r "./requirements/${environment}.txt"
|
||||||
|
|
||||||
|
RUN addgroup -S django \
|
||||||
|
&& adduser -S -g django django
|
||||||
|
|
||||||
|
COPY ./docker/django/scripts/ /scripts/
|
||||||
|
RUN [ "${environment}" = 'production' ] && find /scripts/ -type f -name '*.local' -exec rm -f {} \; || true
|
||||||
|
RUN chown --recursive django:django /scripts/
|
||||||
|
RUN find /scripts/ -type f -exec sed -i 's/\r//' {} \;
|
||||||
|
RUN chmod +x /scripts/*
|
||||||
|
RUN mv /scripts/* / \
|
||||||
|
&& rmdir /scripts/
|
||||||
|
|
||||||
|
COPY . /app/
|
||||||
|
RUN chown --recursive django:django /app/
|
||||||
|
|
||||||
|
USER django
|
||||||
|
|
||||||
|
ENTRYPOINT ["/entrypoint"]
|
||||||
|
|
||||||
|
ARG cmd
|
||||||
|
# See why we need ENV as well: https://stackoverflow.com/a/35562189
|
||||||
|
ENV cmd ${cmd}
|
||||||
|
CMD ${cmd}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
|
||||||
|
celery beat \
|
||||||
|
--app={{ cookiecutter.project_slug }}.taskapp \
|
||||||
|
--loglevel=INFO
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
|
||||||
|
celery worker \
|
||||||
|
--app={{ cookiecutter.project_slug }}.taskapp \
|
||||||
|
--loglevel=INFO
|
10
{{cookiecutter.project_slug}}/docker/django/scripts/django
Normal file
10
{{cookiecutter.project_slug}}/docker/django/scripts/django
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
|
||||||
|
python manage.py migrate
|
||||||
|
# TODO: runs so long that web dyno times out after 60 secs on Heroku
|
||||||
|
#python manage.py collectstatic --noinput
|
||||||
|
/usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app
|
|
@ -1,7 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -o errexit
|
set -o errexit
|
||||||
set -o pipefail
|
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: ? merge with -local somehow
|
||||||
|
|
||||||
|
# N.B. If only .env files supported variable expansion...
|
||||||
|
export CELERY_BROKER_URL="${REDIS_URL}"
|
||||||
|
|
||||||
|
exec "$@"
|
|
@ -1,7 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -o errexit
|
set -o errexit
|
||||||
set -o pipefail
|
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,9 +16,7 @@ export DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES
|
||||||
postgres_ready() {
|
postgres_ready() {
|
||||||
python << END
|
python << END
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import psycopg2
|
import psycopg2
|
||||||
|
|
||||||
try:
|
try:
|
||||||
psycopg2.connect(
|
psycopg2.connect(
|
||||||
dbname="${POSTGRES_DB}",
|
dbname="${POSTGRES_DB}",
|
||||||
|
@ -31,7 +28,6 @@ try:
|
||||||
except psycopg2.OperationalError:
|
except psycopg2.OperationalError:
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
END
|
END
|
||||||
}
|
}
|
||||||
until postgres_ready; do
|
until postgres_ready; do
|
10
{{cookiecutter.project_slug}}/docker/django/scripts/flower
Normal file
10
{{cookiecutter.project_slug}}/docker/django/scripts/flower
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
|
||||||
|
celery flower \
|
||||||
|
--app={{ cookiecutter.project_slug }}.taskapp \
|
||||||
|
--broker="${CELERY_BROKER_URL}" \
|
||||||
|
--loglevel=INFO
|
1
{{cookiecutter.project_slug}}/docker/mailhog/Dockerfile
Normal file
1
{{cookiecutter.project_slug}}/docker/mailhog/Dockerfile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
FROM mailhog/mailhog:v1.0.0
|
7
{{cookiecutter.project_slug}}/docker/postgres/Dockerfile
Normal file
7
{{cookiecutter.project_slug}}/docker/postgres/Dockerfile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
FROM postgres:{{ cookiecutter.postgresql_version }}
|
||||||
|
|
||||||
|
COPY ./scripts/ /usr/local/bin/scripts/
|
||||||
|
RUN find /usr/local/bin/scripts/ -type f -exec sed -i 's/\r//' {} \;
|
||||||
|
RUN chmod +x /usr/local/bin/scripts/*
|
||||||
|
RUN mv /usr/local/bin/scripts/* /usr/local/bin/ \
|
||||||
|
&& rmdir /usr/local/bin/scripts/
|
1
{{cookiecutter.project_slug}}/docker/redis/Dockerfile
Normal file
1
{{cookiecutter.project_slug}}/docker/redis/Dockerfile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
FROM redis:3.2
|
|
@ -3,12 +3,16 @@ version: '3'
|
||||||
volumes:
|
volumes:
|
||||||
local_postgres_data: {}
|
local_postgres_data: {}
|
||||||
local_postgres_data_backups: {}
|
local_postgres_data_backups: {}
|
||||||
|
local_redis_data: {}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
|
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./compose/local/django/Dockerfile
|
dockerfile: ./docker/django/Dockerfile
|
||||||
|
args:
|
||||||
|
environment: local
|
||||||
|
cmd: /django.local
|
||||||
image: {{ cookiecutter.project_slug }}_local_django
|
image: {{ cookiecutter.project_slug }}_local_django
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
|
@ -18,35 +22,14 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- .:/app
|
||||||
env_file:
|
env_file:
|
||||||
- ./.envs/.local/.django
|
- ./.envs/.django.local
|
||||||
- ./.envs/.local/.postgres
|
- ./.envs/.postgres.local
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
command: /start
|
entrypoint: /entrypoint.local
|
||||||
|
command: /django.local
|
||||||
postgres:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./compose/production/postgres/Dockerfile
|
|
||||||
image: {{ cookiecutter.project_slug }}_production_postgres
|
|
||||||
volumes:
|
|
||||||
- local_postgres_data:/var/lib/postgresql/data
|
|
||||||
- local_postgres_data_backups:/backups
|
|
||||||
env_file:
|
|
||||||
- ./.envs/.local/.postgres
|
|
||||||
{%- if cookiecutter.use_mailhog == 'y' %}
|
|
||||||
|
|
||||||
mailhog:
|
|
||||||
image: mailhog/mailhog:v1.0.0
|
|
||||||
ports:
|
|
||||||
- "8025:8025"
|
|
||||||
|
|
||||||
{%- endif %}
|
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:3.2
|
|
||||||
|
|
||||||
celeryworker:
|
celeryworker:
|
||||||
<<: *django
|
<<: *django
|
||||||
image: {{ cookiecutter.project_slug }}_local_celeryworker
|
image: {{ cookiecutter.project_slug }}_local_celeryworker
|
||||||
|
@ -57,7 +40,7 @@ services:
|
||||||
- mailhog
|
- mailhog
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
ports: []
|
ports: []
|
||||||
command: /start-celeryworker
|
command: /celeryworker
|
||||||
|
|
||||||
celerybeat:
|
celerybeat:
|
||||||
<<: *django
|
<<: *django
|
||||||
|
@ -69,13 +52,34 @@ services:
|
||||||
- mailhog
|
- mailhog
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
ports: []
|
ports: []
|
||||||
command: /start-celerybeat
|
command: /celerybeat
|
||||||
|
|
||||||
flower:
|
flower:
|
||||||
<<: *django
|
<<: *django
|
||||||
image: {{ cookiecutter.project_slug }}_local_flower
|
image: {{ cookiecutter.project_slug }}_local_flower
|
||||||
ports:
|
ports:
|
||||||
- "5555:5555"
|
- "5555:5555"
|
||||||
command: /start-flower
|
command: /flower
|
||||||
|
|
||||||
|
redis:
|
||||||
|
build: ./docker/redis/
|
||||||
|
volumes:
|
||||||
|
- local_redis_data:/data
|
||||||
|
|
||||||
|
{%- endif %}
|
||||||
|
postgres:
|
||||||
|
build: ./docker/postgres/
|
||||||
|
image: {{ cookiecutter.project_slug }}_production_postgres
|
||||||
|
volumes:
|
||||||
|
- local_postgres_data:/var/lib/postgresql/data
|
||||||
|
- local_postgres_data_backups:/backups
|
||||||
|
env_file:
|
||||||
|
- ./.envs/.postgres.local
|
||||||
|
{%- if cookiecutter.use_mailhog == 'y' %}
|
||||||
|
|
||||||
|
mailhog:
|
||||||
|
build: ./docker/mailhog/
|
||||||
|
ports:
|
||||||
|
- "8025:8025"
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
@ -3,67 +3,87 @@ version: '3'
|
||||||
volumes:
|
volumes:
|
||||||
production_postgres_data: {}
|
production_postgres_data: {}
|
||||||
production_postgres_data_backups: {}
|
production_postgres_data_backups: {}
|
||||||
|
production_redis_data: {}
|
||||||
production_caddy: {}
|
production_caddy: {}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
|
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./compose/production/django/Dockerfile
|
dockerfile: ./docker/django/Dockerfile
|
||||||
|
args:
|
||||||
|
environment: production
|
||||||
|
cmd: /django
|
||||||
image: {{ cookiecutter.project_slug }}_production_django
|
image: {{ cookiecutter.project_slug }}_production_django
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
env_file:
|
env_file:
|
||||||
- ./.envs/.production/.django
|
- ./.envs/.django
|
||||||
- ./.envs/.production/.postgres
|
- ./.envs/.postgres
|
||||||
command: /start
|
command: /django
|
||||||
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
|
|
||||||
postgres:
|
celeryworker:
|
||||||
|
<<: *django
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./compose/production/postgres/Dockerfile
|
dockerfile: ./docker/django/Dockerfile
|
||||||
|
args:
|
||||||
|
environment: production
|
||||||
|
cmd: /celeryworker
|
||||||
|
image: {{ cookiecutter.project_slug }}_production_celeryworker
|
||||||
|
ports: []
|
||||||
|
command: /celeryworker
|
||||||
|
|
||||||
|
celerybeat:
|
||||||
|
<<: *django
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./docker/django/Dockerfile
|
||||||
|
args:
|
||||||
|
environment: production
|
||||||
|
cmd: /celerybeat
|
||||||
|
image: {{ cookiecutter.project_slug }}_production_celerybeat
|
||||||
|
command: /celerybeat
|
||||||
|
|
||||||
|
flower:
|
||||||
|
<<: *django
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./docker/django/Dockerfile
|
||||||
|
args:
|
||||||
|
environment: production
|
||||||
|
cmd: /flower
|
||||||
|
image: {{ cookiecutter.project_slug }}_production_flower
|
||||||
|
ports:
|
||||||
|
- "5555:5555"
|
||||||
|
command: /flower
|
||||||
|
|
||||||
|
{%- endif %}
|
||||||
|
postgres:
|
||||||
|
build: ./docker/postgres/
|
||||||
image: {{ cookiecutter.project_slug }}_production_postgres
|
image: {{ cookiecutter.project_slug }}_production_postgres
|
||||||
volumes:
|
volumes:
|
||||||
- production_postgres_data:/var/lib/postgresql/data
|
- production_postgres_data:/var/lib/postgresql/data
|
||||||
- production_postgres_data_backups:/backups
|
- production_postgres_data_backups:/backups
|
||||||
env_file:
|
env_file:
|
||||||
- ./.envs/.production/.postgres
|
- ./.envs/.postgres
|
||||||
|
|
||||||
|
redis:
|
||||||
|
build: ./docker/redis/
|
||||||
|
volumes:
|
||||||
|
- production_redis_data:/data
|
||||||
|
|
||||||
caddy:
|
caddy:
|
||||||
build:
|
build: ./docker/caddy/
|
||||||
context: .
|
|
||||||
dockerfile: ./compose/production/caddy/Dockerfile
|
|
||||||
image: {{ cookiecutter.project_slug }}_production_caddy
|
image: {{ cookiecutter.project_slug }}_production_caddy
|
||||||
depends_on:
|
depends_on:
|
||||||
- django
|
- django
|
||||||
volumes:
|
volumes:
|
||||||
- production_caddy:/root/.caddy
|
- production_caddy:/root/.caddy
|
||||||
env_file:
|
env_file:
|
||||||
- ./.envs/.production/.caddy
|
- ./.envs/.caddy
|
||||||
ports:
|
ports:
|
||||||
- "0.0.0.0:80:80"
|
- "0.0.0.0:80:80"
|
||||||
- "0.0.0.0:443:443"
|
- "0.0.0.0:443:443"
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:3.2
|
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
|
||||||
|
|
||||||
celeryworker:
|
|
||||||
<<: *django
|
|
||||||
image: {{ cookiecutter.project_slug }}_production_celeryworker
|
|
||||||
command: /start-celeryworker
|
|
||||||
|
|
||||||
celerybeat:
|
|
||||||
<<: *django
|
|
||||||
image: {{ cookiecutter.project_slug }}_production_celerybeat
|
|
||||||
command: /start-celerybeat
|
|
||||||
|
|
||||||
flower:
|
|
||||||
<<: *django
|
|
||||||
image: {{ cookiecutter.project_slug }}_production_flower
|
|
||||||
ports:
|
|
||||||
- "5555:5555"
|
|
||||||
command: /start-flower
|
|
||||||
|
|
||||||
{%- endif %}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user