mirror of
https://github.com/Balshgit/public.git
synced 2025-09-11 18:00:42 +03:00
187 lines
5.6 KiB
ReStructuredText
187 lines
5.6 KiB
ReStructuredText
.. _`going-to-production`:
|
|
|
|
Going to production
|
|
===================
|
|
|
|
This section covers everything you need to know before going to production.
|
|
|
|
|
|
Django
|
|
------
|
|
|
|
Checks
|
|
~~~~~~
|
|
|
|
Before going to production make sure you have checked everything:
|
|
|
|
1. Migrations are up-to-date
|
|
2. Static files are all present
|
|
3. There are no security or other ``django`` warnings
|
|
|
|
Checking migrations, static files,
|
|
and security is done inside ``ci.sh`` script.
|
|
|
|
We check that there are no unapplied migrations:
|
|
|
|
.. code :: bash
|
|
|
|
python manage.py makemigrations --dry-run --check
|
|
|
|
If you have forgotten to create a migration and changed the model,
|
|
you will see an error on this line.
|
|
|
|
We also check that static files can be collected:
|
|
|
|
.. code :: bash
|
|
|
|
DJANGO_ENV=production python manage.py collectstatic --no-input --dry-run
|
|
|
|
However, this check does not cover all the cases.
|
|
Sometimes ``ManifestStaticFilesStorage`` will fail on real cases,
|
|
but will pass with ``--dry-run`` option.
|
|
You can disable ``--dry-run`` option if you know what you are doing.
|
|
Be careful with this option, when working with auto-uploading
|
|
your static files to any kind of CDNs.
|
|
|
|
That's how we check ``django`` warnings:
|
|
|
|
.. code:: bash
|
|
|
|
DJANGO_ENV=production python manage.py check --deploy --fail-level WARNING
|
|
|
|
These warnings are raised by ``django``
|
|
when it detects any configuration issues.
|
|
|
|
This command should give not warnings or errors.
|
|
It is bundled into `docker`, so the container will not work with any warnings.
|
|
|
|
Static and media files
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
We use ``/var/www/django`` folder to store our media
|
|
and static files in production as ``/var/www/django/static``
|
|
and ``/var/www/django/media``.
|
|
Docker uses these two folders as named volumes.
|
|
And later these volumes are also mounted to ``caddy``
|
|
with ``ro`` mode so it possible to read their contents.
|
|
|
|
To find the exact location of these files on your host
|
|
you will need to do the following:
|
|
|
|
.. code:: bash
|
|
|
|
docker volume ls # to find volumes' names
|
|
docker volume inspect VOLUME_NAME
|
|
|
|
Sometimes storing your media files inside a container is not a good idea.
|
|
Use ``CDN`` when you have a lot of user content
|
|
or it is very important not to lose it.
|
|
There are `helper libraries <http://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html>`_
|
|
to bind ``django`` and these services.
|
|
|
|
If you don't need ``media`` files support, just remove the volumes.
|
|
|
|
Migrations
|
|
~~~~~~~~~~
|
|
|
|
We do run migration in the ``gunicorn.sh`` by default.
|
|
Why do we do this? Because that's probably the easiest way to do it.
|
|
But it clearly has some disadvantages:
|
|
|
|
- When scaling your container for multiple nodes you will have multiple
|
|
threads running the same migrations. And it might be a problem since
|
|
migrations do not guarantee that it will work this way.
|
|
- You can perform some operations multiple times
|
|
- Possible other evil things may happen
|
|
|
|
So, what to do in this case?
|
|
Well, you can do whatever it takes to run migrations in a single thread.
|
|
For example, you can create a separate container to do just that.
|
|
Other options are fine as well.
|
|
|
|
|
|
Postgres
|
|
--------
|
|
|
|
Sometimes using ``postgres`` inside a container
|
|
`is not a good idea <https://myopsblog.wordpress.com/2017/02/06/why-databases-is-not-for-containers/>`_.
|
|
So, what should be done in this case?
|
|
|
|
First of all, move your database ``docker`` service definition
|
|
inside ``docker-compose.override.yml``.
|
|
Doing so will not affect development,
|
|
but will remove database service from production.
|
|
Next, you will need to specify `extra_hosts <https://docs.docker.com/compose/compose-file/#extra_hosts>`_
|
|
to contain your ``postgresql`` address.
|
|
Lastly, you would need to add new hosts to ``pg_hba.conf``.
|
|
|
|
`Here <http://winstonkotzan.com/blog/2017/06/01/connecting-to-external-postgres-database-with-docker.html>`_
|
|
is a nice tutorial about this topic.
|
|
|
|
|
|
Caddy
|
|
-----
|
|
|
|
Let's Encrypt
|
|
~~~~~~~~~~~~~
|
|
|
|
We are using ``Caddy`` and ``Let's Encrypt`` for HTTPS.
|
|
The Caddy webserver used in the default configuration will get
|
|
you a valid certificate from ``Let's Encrypt`` and update it automatically.
|
|
All you need to do to enable this is to make sure
|
|
that your DNS records are pointing to the server Caddy runs on.
|
|
|
|
Read more: `Automatic HTTPS <https://caddyserver.com/docs/automatic-https>`_
|
|
in Caddy docs.
|
|
|
|
Caddyfile validation
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
You can also run ``-validate`` command to validate ``Caddyfile`` contents.
|
|
|
|
Here's it would look like:
|
|
|
|
.. code:: bash
|
|
|
|
docker-compose -f docker-compose.yml -f docker/docker-compose.prod.yml
|
|
run --rm caddy -validate
|
|
|
|
This check is not included in the pipeline by default,
|
|
because it is quite long to start all the machinery for this single check.
|
|
|
|
Disabling HTTPS
|
|
~~~~~~~~~~~~~~~
|
|
|
|
You would need to `disable <https://caddyserver.com/docs/tls>`_
|
|
``https`` inside ``Caddy`` and in production settings for Django.
|
|
Because Django itself also redirects to `https`.
|
|
See `docs <https://docs.djangoproject.com/en/2.2/ref/settings/#secure-ssl-redirect>`_.
|
|
|
|
You would also need to disable ``manage.py check``
|
|
in ``docker/ci.sh``.
|
|
Otherwise, your application won't start,
|
|
it would not pass ``django``'s security checks.
|
|
|
|
Disabling WWW subdomain
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
If you for some reason do not require ``www.`` subdomain,
|
|
then delete ``www.{$DOMAIN_NAME}`` section from ``Caddyfile``.
|
|
|
|
Third-Level domains
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
You have to disable ``www`` subdomain if
|
|
your app works on third-level domains like:
|
|
|
|
- ``kira.wemake.services``
|
|
- ``support.myapp.com``
|
|
|
|
Otherwise, ``Caddy`` will server redirects to ``www.example.yourdomain.com``.
|
|
|
|
|
|
Further reading
|
|
---------------
|
|
|
|
- Django's deployment `checklist <https://docs.djangoproject.com/en/dev/howto/deployment/checklist/#deployment-checklist>`_
|