Skip to content

Commit

Permalink
Group environment variables by the corresponding directories (cookiec…
Browse files Browse the repository at this point in the history
…utter#1295)

* Update generated project's .gitignore

* Post-gen gitignore .env/ and .env

* Fix linesep between gitignored entries

* Persist `.env/**/*` files into cookiecutter-django's VCS

* Rename .env/ to .envs/

* Reference the newly created .envs/**/.* files in local.yml

* Reference the newly created .envs/**/.* files in production.yml

* Delete .env.example

* Refactor post-gen-project.py

Closes cookiecutter#1299.

* Implement production-dotenv-files-to-dotenv-file merge script

* Create shared PyCharm Run Configuration for the automation script

* Randomize POSTGRES_PASSWORD in ./envs/(.local|.production)/.postgres

* Default POSTGRES_PASSWORD and POSTGRES_USER to random values

* Fix jinja linebreaks in local.yml

* Spaces in production.yml

* Fix post-merge leftovers & set DJANGO_ADMIN_URL automatically

* Prettify here and there

* Fix FileNotFoundError

* Leave a TODO in post_gen_hook.py

* Introduce keep_local_envs_in_vcs option

* Remove envs when not opted for

* Inline pre_gen_project.py if-condition

* Get rid of PROJECT_DIR_PATH in post_gen_project.py

* Clean up the docs

* Match copyright notices

* Document envs ins and outs
  • Loading branch information
webyneter authored Mar 8, 2018
1 parent 6c8538a commit 3f8aa26
Show file tree
Hide file tree
Showing 24 changed files with 411 additions and 266 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2013-2018, Daniel Greenfeld
Copyright (c) 2013-2018, Daniel Roy Greenfeld
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Pyup brings you automated security and dependency updates used by Google and oth
Usage
------

Let's pretend you want to create a Django project called "redditclone". Rather than using `startproject`
Let's pretend you want to create a Django project called "redditclone". Rather than using ``startproject``
and then editing the results to include your name, email, and various configuration issues that always get forgotten until the worst possible moment, get cookiecutter_ to do all the work.

First, get Cookiecutter. Trust me, it's awesome::
Expand Down Expand Up @@ -192,6 +192,7 @@ Answer the prompts with your own desired options_. For example::
4 - Apache Software License 2.0
5 - Not open source
Choose from 1, 2, 3, 4, 5 [1]: 1
keep_local_envs_in_vcs [y]: y

Enter the project and take a look around::

Expand Down
3 changes: 2 additions & 1 deletion cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
"use_opbeat": "n",
"use_whitenoise": "y",
"use_heroku": "n",
"use_travisci": "n"
"use_travisci": "n",
"keep_local_envs_in_vcs": "y"
}
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

# General information about the project.
project = 'Cookiecutter Django'
copyright = "2013-2016, Daniel Roy Greenfeld".format(now.year)
copyright = "2013-2018, Daniel Roy Greenfeld".format(now.year)

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down
2 changes: 1 addition & 1 deletion docs/deployment-on-pythonanywhere.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Database setup:

Go to the PythonAnywhere **Databases tab** and configure your database.

* For Postgres, setup your superuser password, then open a Postgres console and run a `CREATE DATABASE my-db-name`. You should probably also set up a specific role and permissions for your app, rather than using the superuser credentials. Make a note of the address and port of your postgres server.
* For Postgres, setup your superuser password, then open a Postgres console and run a ``CREATE DATABASE my-db-name``. You should probably also set up a specific role and permissions for your app, rather than using the superuser credentials. Make a note of the address and port of your postgres server.

* For MySQL, set the password and create a database. More info here: https://help.pythonanywhere.com/pages/UsingMySQL

Expand Down
14 changes: 7 additions & 7 deletions docs/deployment-with-docker.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Deployment with Docker
=======================
======================

.. index:: Docker, deployment

Expand All @@ -10,7 +10,7 @@ Prerequisites
* Docker Compose (at least 1.6)

Understand the Compose Setup
--------------------------------
----------------------------

Before you start, check out the `production.yml` file in the root of this project. This is where each component
of this application gets its configuration from. Notice how it provides configuration for these services:
Expand Down Expand Up @@ -73,12 +73,12 @@ You can read more about this here at `Automatic HTTPS`_ in the Caddy docs.
.. _Automatic HTTPS: https://caddyserver.com/docs/automatic-https


Optional: Postgres Data Volume Modifications
(Optional) Postgres Data Volume Modifications
---------------------------------------------

Postgres is saving its database files to the `postgres_data` volume by default. Change that if you want something else and make sure to make backups since this is not done automatically.

Run your app with docker-compose
Run your app with Docker Compose
--------------------------------

To get started, pull your code from source control (don't forget the `.env` file) and change to your projects root
Expand All @@ -94,15 +94,15 @@ Once this is ready, you can run it with::

To run a migration, open up a second terminal and run::

docker-compose -f production.yml run django python manage.py migrate
docker-compose -f production.yml run --rm django python manage.py migrate

To create a superuser, run::

docker-compose -f production.yml run django python manage.py createsuperuser
docker-compose -f production.yml run --rm django python manage.py createsuperuser

If you need a shell, run::

docker-compose -f production.yml run django python manage.py shell
docker-compose -f production.yml run --rm django python manage.py shell

To get an output of all running containers.

Expand Down
152 changes: 78 additions & 74 deletions docs/developing-locally-docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,19 @@ Getting Up and Running Locally With Docker
The steps below will get you up and running with a local development environment.
All of these commands assume you are in the root of your generated project.


Prerequisites
-------------

You'll need at least Docker 1.10.

If you don't already have it installed, follow the instructions for your OS:
* Docker; if you don't have it yet, follow the `installation instructions`_;
* Docker Compose; refer to the official documentation for the `installation guide`_.

- On Mac OS X, you'll need `Docker for Mac`_
- On Windows, you'll need `Docker for Windows`_
- On Linux, you'll need `docker-engine`_
.. _`installation instructions`: https://docs.docker.com/install/#supported-platforms
.. _`installation guide`: https://docs.docker.com/compose/install/

.. _`Docker for Mac`: https://docs.docker.com/engine/installation/mac/
.. _`Docker for Windows`: https://docs.docker.com/engine/installation/windows/
.. _`docker-engine`: https://docs.docker.com/engine/installation/

Attention Windows users
-----------------------
Attention, Windows Users
------------------------

Currently PostgreSQL (``psycopg2`` python package) is not installed inside Docker containers for Windows users, while it is required by the generated Django project. To fix this, add ``psycopg2`` to the list of requirements inside ``requirements/base.txt``::

Expand All @@ -31,23 +27,21 @@ Currently PostgreSQL (``psycopg2`` python package) is not installed inside Docke

Doing this will prevent the project from being installed in an Windows-only environment (thus without usage of Docker). If you want to use this project without Docker, make sure to remove ``psycopg2`` from the requirements again.


Build the Stack
---------------

This can take a while, especially the first time you run this particular command
on your development system::
This can take a while, especially the first time you run this particular command on your development system::

$ docker-compose -f local.yml build

If you want to build the production environment you use ``production.yml`` as -f argument (``docker-compose.yml`` or ``docker-compose.yaml`` are the defaults).
Generally, if you want to emulate production environment use ``production.yml`` instead. And this is true for any other actions you might need to perform: whenever a switch is required, just do it!

Boot the System
---------------

This brings up both Django and PostgreSQL.
Run the Stack
-------------

The first time it is run it might take a while to get started, but subsequent
runs will occur quickly.
This brings up both Django and PostgreSQL. The first time it is run it might take a while to get started, but subsequent runs will occur quickly.

Open a terminal at the project root and run the following for local development::

Expand All @@ -61,98 +55,108 @@ And then run::

$ docker-compose up

Running management commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~
To run in a detached (background) mode, just::

As with any shell command that we wish to run in our container, this is done
using the ``docker-compose -f local.yml run`` command.
$ docker-compose up -d

To migrate your app and to create a superuser, run::

$ docker-compose -f local.yml run django python manage.py migrate
$ docker-compose -f local.yml run django python manage.py createsuperuser
Execute Management Commands
---------------------------

Here we specify the ``django`` container as the location to run our management commands.
As with any shell command that we wish to run in our container, this is done using the ``docker-compose -f local.yml run --rm`` command: ::

Add your Docker development server IP
-------------------------------------
$ docker-compose -f local.yml run --rm django python manage.py migrate
$ docker-compose -f local.yml run --rm django python manage.py createsuperuser

When ``DEBUG`` is set to `True`, the host is validated against ``['localhost', '127.0.0.1', '[::1]']``. This is adequate when running a ``virtualenv``. For Docker, in the ``config.settings.local``, add your host development server IP to ``INTERNAL_IPS`` or ``ALLOWED_HOSTS`` if the variable exists.
Here, ``django`` is the target service we are executing the commands against.

Production Mode
~~~~~~~~~~~~~~~

Instead of using `local.yml`, you would use `production.yml`.
(Optionally) Designate your Docker Development Server IP
--------------------------------------------------------

Other Useful Tips
-----------------
When ``DEBUG`` is set to ``True``, the host is validated against ``['localhost', '127.0.0.1', '[::1]']``. This is adequate when running a ``virtualenv``. For Docker, in the ``config.settings.local``, add your host development server IP to ``INTERNAL_IPS`` or ``ALLOWED_HOSTS`` if the variable exists.

Make a machine the active unit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This tells our computer that all future commands are specifically for the dev1 machine.
Using the ``eval`` command we can switch machines as needed.
Configuring the Environment
---------------------------

::
This is the excerpt from your project's ``local.yml``: ::

$ eval "$(docker-machine env dev1)"
# ...

Detached Mode
~~~~~~~~~~~~~
postgres:
build:
context: .
dockerfile: ./compose/production/postgres/Dockerfile
volumes:
- postgres_data_local:/var/lib/postgresql/data
- postgres_backup_local:/backups
env_file:
- ./.envs/.local/.postgres

If you want to run the stack in detached mode (in the background), use the ``-d`` argument:
# ...

::
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: ::

$ docker-compose -f local.yml up -d
.envs
├── .local
│   ├── .django
│   └── .postgres
└── .production
├── .caddy
├── .django
└── .postgres

Debugging
~~~~~~~~~~~~~
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.

ipdb
"""""
Consider the aforementioned ``.envs/.local/.postgres``: ::

If you are using the following within your code to debug:
# PostgreSQL
# ------------------------------------------------------------------------------
POSTGRES_USER=XgOWtQtJecsAbaIyslwGvFvPawftNaqO
POSTGRES_PASSWORD=jSljDz4whHuwO3aJIgVBrqEml5Ycbghorep4uVJ4xjDYQu0LfuTZdctj7y0YcCLu

::
The two envs we are presented with here are ``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.

import ipdb; ipdb.set_trace()

Then you may need to run the following for it to work as desired:
Tips & Tricks
-------------

Activate a Docker Machine
~~~~~~~~~~~~~~~~~~~~~~~~~

::
This tells our computer that all future commands are specifically for the dev1 machine. Using the ``eval`` command we can switch machines as needed.::

$ docker-compose -f local.yml run --service-ports django
$ eval "$(docker-machine env dev1)"

Debugging
~~~~~~~~~

django-debug-toolbar
""""""""""""""""""""
ipdb
"""""

If you are using the following within your code to debug: ::

In order for django-debug-toolbar to work with docker you need to add your docker-machine ip address to ``INTERNAL_IPS`` in ``local.py``
import ipdb; ipdb.set_trace()

Then you may need to run the following for it to work as desired: ::

.. May be a better place to put this, as it is not Docker specific.
$ docker-compose -f local.yml run --rm --service-ports django

You may need to add the following to your css in order for the django-debug-toolbar to be visible (this applies whether Docker is being used or not):

.. code-block:: css
django-debug-toolbar
""""""""""""""""""""

/* Override Bootstrap 4 styling on Django Debug Toolbar */
#djDebug[hidden], #djDebug [hidden] {
display: block !important;
}
In order for ``django-debug-toolbar`` to work designate your Docker Machine IP with ``INTERNAL_IPS`` in ``local.py``.

#djDebug [hidden][style='display: none;'] {
display: none !important;
}

Mailhog
~~~~~~~

Using the Mailhog Docker Container
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When developing locally you can go with MailHog_ for email testing provided ``use_mailhog`` was set to ``y`` on setup. To proceed,

In development you can (optionally) use MailHog_ for email testing. If you selected `use_docker`, MailHog is added as a Docker container. To use MailHog:
#. make sure ``mailhog`` container is up and running;

1. Make sure, that ``mailhog`` docker container is up and running
2. Open your browser and go to ``http://127.0.0.1:8025``
#. open up ``http://127.0.0.1:8025``.

.. _Mailhog: https://github.com/mailhog/MailHog/
8 changes: 4 additions & 4 deletions docs/docker-postgres-backups.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Database Backups with Docker
============================

The database has to be running to create/restore a backup. These examples show local examples. If you want to use it on a remote server, remove ``-f local.yml`` from each example.
The database has to be running to create/restore a backup. These examples show local examples. If you want to use it on a remote server, use ``-f production.yml`` instead.

Running Backups
================
Expand All @@ -11,17 +11,17 @@ Run the app with `docker-compose -f local.yml up`.

To create a backup, run::

docker-compose -f local.yml run postgres backup
docker-compose -f local.yml run --rm postgres backup


To list backups, run::

docker-compose -f local.yml run postgres list-backups
docker-compose -f local.yml run --rm postgres list-backups


To restore a backup, run::

docker-compose -f local.yml run postgres restore filename.sql
docker-compose -f local.yml run --rm postgres restore filename.sql

Where <containerId> is the ID of the Postgres container. To get it, run::

Expand Down
12 changes: 6 additions & 6 deletions docs/faq.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FAQ
====
===

.. index:: FAQ, 12-Factor App

Expand All @@ -17,11 +17,11 @@ Why aren't you using just one configuration file (12-Factor App)
----------------------------------------------------------------------

TODO
.. TODO
Why doesn't this follow the layout from Two Scoops of Django 1.8?
----------------------------------------------------------------------

You may notice that some elements of this project do not exactly match what we describe in chapter 3 of `Two Scoops of Django`_. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored.
Why doesn't this follow the layout from Two Scoops of Django?
-------------------------------------------------------------

You may notice that some elements of this project do not exactly match what we describe in chapter 3 of `Two Scoops of Django 1.11`_. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored.

.. _`Two Scoops of Django`: http://twoscoopspress.com/products/two-scoops-of-django-1-8
.. _Two Scoops of Django 1.11: https://www.twoscoopspress.com/collections/django/products/two-scoops-of-django-1-11
Loading

0 comments on commit 3f8aa26

Please sign in to comment.