Skip to content

Commit

Permalink
integrate config file to testable tutorial, also test REST API
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiasertl committed Jan 6, 2025
1 parent 3a3893c commit fa83e5b
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 105 deletions.
18 changes: 12 additions & 6 deletions devscripts/validation/docker_compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def compose_status() -> None:

if errors != 0:
raise RuntimeError(f"{errors} container(s) have not started successfully.")
ok("Containers seem to have started properly.")
ok("All containers have started successfully.")


def _compose_exec(*args: str, **kwargs: Any) -> "subprocess.CompletedProcess[Any]":
Expand Down Expand Up @@ -250,7 +250,7 @@ def _sign_certificates(csr: str) -> str:
return cert_subject


def validate_endpoints(base_url: str, verify: Optional[str] = None) -> None:
def validate_endpoints(base_url: str, api_user: str, api_password: str, verify: Optional[str] = None) -> None:
"""Validate all endpoints of the setup."""
# Test that HTTPS connection and admin interface is working:
resp = requests.get(f"{base_url}/admin/", verify=verify, timeout=10)
Expand All @@ -260,6 +260,10 @@ def validate_endpoints(base_url: str, verify: Optional[str] = None) -> None:
resp = requests.get(f"{base_url}/static/admin/css/base.css", verify=verify, timeout=10)
resp.raise_for_status()

# Test the REST API
resp = requests.get(f"{base_url}/api/ca/", auth=(api_user, api_password), verify=verify, timeout=10)
resp.raise_for_status()

# Test (principal) ACME connection
resp = requests.get(f"{base_url}/acme/directory/", verify=verify, timeout=10)
resp.raise_for_status()
Expand All @@ -270,7 +274,7 @@ def test_tutorial(release: str) -> int: # pylint: disable=too-many-locals # no
info("Validating tutorial...")
errors = 0
standalone_dir = config.ROOT_DIR / "devscripts" / "standalone"
docker_compose_yml = config.ROOT_DIR / "docker-compose.yml"
docker_compose_yml = config.ROOT_DIR / "compose.yaml"
if not docker_compose_yml.exists():
return err(f"{docker_compose_yml}: File not found.")

Expand Down Expand Up @@ -305,8 +309,10 @@ def test_tutorial(release: str) -> int: # pylint: disable=too-many-locals # no

with start_tutorial("quickstart_with_docker_compose", context) as tut:
cwd = Path(os.getcwd())
print("# Running in ", cwd)
tut.write_template("docker-compose.override.yml.jinja")
info(f"# Running in {cwd}")
tut.write_template("localsettings.yaml.jinja")
shutil.copy(docker_compose_yml, cwd)
tut.write_template("compose.override.yaml.jinja")
tut.write_template(".env.jinja")
shutil.copy(docker_compose_yml, cwd)

Expand Down Expand Up @@ -372,7 +378,7 @@ def test_tutorial(release: str) -> int: # pylint: disable=too-many-locals # no
_validate_crl_ocsp("root.pem", f"{cert_subject}.pem", cert_subject)

# Test all endpoints
validate_endpoints("https://localhost", verify=str(ca_pub_pem))
validate_endpoints("https://localhost", 'user', 'nopass', verify=str(ca_pub_pem))

# Finally some manual testing
info(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
services:
backend:
volumes:
- ./localsettings.yaml:/usr/src/django-ca/ca/conf/compose/99-localsettings.yaml
frontend:
volumes:
- ./localsettings.yaml:/usr/src/django-ca/ca/conf/compose/99-localsettings.yaml
webserver:
volumes:
- {{ certbot_root }}live/${DJANGO_CA_CA_DEFAULT_HOSTNAME}:{{ tls_cert_root }}live/${DJANGO_CA_CA_DEFAULT_HOSTNAME}/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#
# See also:
# https://docs.djangoproject.com/en/4.0/topics/email/
SMTP_HOST: smtp.example.coma
#SMTP_HOST: smtp.example.coma

# Set a custom default key size for new certificate authorities
CA_DEFAULT_KEY_SIZE: 2048
#CA_DEFAULT_KEY_SIZE: 4096

# Enable the REST API
CA_ENABLE_REST_API: true
180 changes: 93 additions & 87 deletions docs/source/quickstart/docker_compose.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,97 @@ bind to port 80 (HTTP).
user@host:~$ sudo ls /etc/letsencrypt/live/ca.example.com
README cert.pem chain.pem fullchain.pem privkey.pem
.. _docker-compose.yml:

*****************
Get configuration
*****************

Docker-compose needs a configuration file, :download:`docker-compose.yml </_files/docker-compose.yml>`. You
can also download the file for other versions `from github
<https://github.com/mathiasertl/django-ca/blob/master/docker-compose.yml>`_.

.. NOTE::

Because of how **Docker Compose** works, it is better to put the file in a sub-directory and `not` directly
into your home directory. We assume you put all files into ``~/ca/`` from now on.

To run **django-ca**, you'll need a couple of files:

* `dhparam.pem <quickstart-docker-compose-dhparam.pem>`_, the DH parameters (required for TLS connections).
* `localsettings.yaml <quickstart-docker-compose-localsettings.yaml>`_, the configuration for **django-ca**.
* `docker-compose.yml <quickstart-docker-compose-docker-compose.yml>`_, the configuration for Docker Compose.
* `docker-compose.override.yml <quickstart-docker-compose-docker-compose.override.yml>`_, system-local
configuration overrides for Docker Compose.
* `.env <quickstart-docker-compose-.env>`_, the environment file for Docker Compose.

Read the sections below how to retrieve or generate all these files.

.. _quickstart-docker-compose-dhparam.pem:

Generate DH parameters
======================

The TLS configuration requires that you generate a DH parameter file, which used by some TLS ciphers. You can
generate it with:

.. console-include::
:include: /include/quickstart_with_docker_compose/dhparam.yaml
:context: quickstart-with-docker-compose
:path: ~/ca/

.. _quickstart-docker-compose-localsettings.yaml:

Add configuration file
======================

**django-ca** is configured via a YAML configuration file. It is not strictly required, as the defaults are
fine in most cases. Creating at least an empty file is recommended, as it will make any future changes easier.

.. NOTE::

Do not set ``CA_DEFAULT_HOSTNAME`` and ``CA_URL_PATH`` here! They are set in `.env
<quickstart-docker-compose-.env>`_, as the NGINX container also uses them.

Create a file called ``localsettings.yaml``. This example just enables the :doc:`/rest_api`:

.. template-include:: yaml /include/quickstart_with_docker_compose/localsettings.yaml.jinja
:caption: localsettings.yaml
:context: quickstart-with-docker-compose

Please see :doc:`custom settings </settings>` for available settings and :ref:`settings-yaml-configuration`
for more examples. Almost all settings can be changed later, if that is not the case, the settings
documentation mentions it.

Multiple configuration files
----------------------------

As with the normal Docker container, django-ca will read configuration files in
``/usr/src/django-ca/ca/conf/`` in alphabetical order, but it will also read files in the subfolder
``/usr/src/django-ca/conf/ca/compose/``, which provides configuration specific to our Docker Compose setup.
You can use any number of files as long as you map them into the ``frontend`` and ``backend`` containers as
shown in the examples below.

Environment variables
---------------------

If you want to use environment variables for configuration, we recommend you first add them to your
``docker-compose.override.yml``, for example to `configure a different SMTP server
<https://docs.djangoproject.com/en/4.0/ref/settings/#email-host>`_ for sending out emails:

.. literalinclude:: /include/quickstart_with_docker_compose/docker-compose.override-env-example.yml
:language: yaml
:caption: docker-compose.override.yml

and in your `.env <quickstart-docker-compose-.env>`_ file, set the variable:

.. code-block:: bash
DJANGO_CA_EMAIL_HOST=smtp.example.com
.. _quickstart-docker-compose-docker-compose.yml:

Add ``docker-compose.yml``
==========================

Docker-compose needs a configuration file, :download:`docker-compose.yml </_files/docker-compose.yml>`. You
can also download the file for other versions `from github
<https://github.com/mathiasertl/django-ca/blob/master/docker-compose.yml>`_.

You can also get versions for specific versions of **django-ca** from the table below, which also shows
bundled third-party Docker images.

Expand All @@ -77,8 +153,8 @@ bundled third-party Docker images.
==================================================================================== ===== ========== =======
Version Redis PostgreSQL NGINX
==================================================================================== ===== ========== =======
`2.1.1 <https://github.com/mathiasertl/django-ca/blob/2.0.0/docker-compose.yml>`_ 7 16 1.26
`2.1.0 <https://github.com/mathiasertl/django-ca/blob/2.0.0/docker-compose.yml>`_ 7 16 1.26
`2.1.1 <https://github.com/mathiasertl/django-ca/blob/2.1.1/docker-compose.yml>`_ 7 16 1.26
`2.1.0 <https://github.com/mathiasertl/django-ca/blob/2.1.0/docker-compose.yml>`_ 7 16 1.26
`2.0.0 <https://github.com/mathiasertl/django-ca/blob/2.0.0/docker-compose.yml>`_ 7 16 1.26
`1.29.0 <https://github.com/mathiasertl/django-ca/blob/1.29.0/docker-compose.yml>`_ 7 16 1.24
`1.28.0 <https://github.com/mathiasertl/django-ca/blob/1.28.0/docker-compose.yml>`_ 7 **16** 1.24
Expand All @@ -87,10 +163,10 @@ Version
`1.25.0 <https://github.com/mathiasertl/django-ca/blob/1.25.0/docker-compose.yml>`_ 7 12 **1.24**
`1.24.0 <https://github.com/mathiasertl/django-ca/blob/1.24.0/docker-compose.yml>`_ 7 12 1.23
`1.23.0 <https://github.com/mathiasertl/django-ca/blob/1.23.0/docker-compose.yml>`_ 7 12 **1.23**
`1.22.0 <https://github.com/mathiasertl/django-ca/blob/1.22.0/docker-compose.yml>`_ **7** 12 1.20
`1.21.0 <https://github.com/mathiasertl/django-ca/blob/1.21.0/docker-compose.yml>`_ 6 12 1.20
==================================================================================== ===== ========== =======

.. _quickstart-docker-compose-docker-compose.override.yml:

Add ``docker-compose.override.yml``
===================================

Expand All @@ -104,10 +180,14 @@ configuration file:
:caption: docker-compose.override.yml
:context: quickstart-with-docker-compose

In the above example, we already add

This will work if you get your certificates using ``certbot`` or a similar client. If your private key in
public key chain is named different, you can set ``NGINX_PRIVATE_KEY`` and ``NGINX_PUBLIC_KEY`` in your
:file:`.env` file below.

.. _quickstart-docker-compose-.env:

Add ``.env`` file
=================

Expand All @@ -120,89 +200,15 @@ For a quick start, there are only a few variables you need to specify:
:caption: .env
:context: quickstart-with-docker-compose

Generate DH parameters
======================

The TLS configuration also requires that you generate a DH parameter file, used by some TLS ciphers. You can
generate it with:

.. console-include::
:include: /include/quickstart_with_docker_compose/dhparam.yaml
:context: quickstart-with-docker-compose
:path: ~/ca/

Customization
=============

Although the defaults are fine for most scenarios, **django-ca** and Django itself support a wide range of
settings to customize your installation. Django has its settings documented under `Settings
<https://docs.djangoproject.com/en/4.0/ref/settings/>`_, django-ca settings are documented under :doc:`custom
settings </settings>`.

Just like when using the plain Docker container, you can configure django-ca using either environment
variables (set in e.g. ``docker-compose.override.yml``) or using an extra YAML configuration file. For more
details on how to configure the Docker container, refer to :ref:`docker-configuration`.

.. NOTE::

In our **docker compose** setup, django-ca is used in both the ``backend`` and ``frontend`` containers.
Make sure you configure both of them.


Configuration using a YAML configuration file
---------------------------------------------

Using an extra configuration file is the most flexible way to configure django-ca, as it allows you to update
even complex settings. It has the added advantage that **docker compose** will not recreate the containers if
you update the configuration.

As with the normal docker container, django-ca will read configuration files in
``/usr/src/django-ca/ca/conf/`` in alphabetical order, but it will also read files in the subfolder
``/usr/src/django-ca/conf/ca/compose/``, which provides configuration specific to our **docker compose**
setup.

To add a configuration file, first add a volume mapping in your ``docker-compose.override.yml``:

.. literalinclude:: /include/quickstart_with_docker_compose/docker-compose.override-localsettings-example.yml
:language: yaml
:caption: docker-compose.override.yml

... and then simply add a file called ``localsettings.yaml`` in your current directory, for example:

.. literalinclude:: /include/quickstart_with_docker_compose/localsettings.example.yml
:language: yaml
:caption: localsettings.yaml (example)

Please see :doc:`/settings` for a list of available settings and especially :ref:`settings-yaml-configuration`
for more YAML configuration examples.

Configuration using environment variables
-----------------------------------------

If you want to use environment variables for configuration, we recommend you first add them to your
``docker-compose.override.yml``, for example to `configure a different SMTP server
<https://docs.djangoproject.com/en/4.0/ref/settings/#email-host>`_ for sending out emails:

.. literalinclude:: /include/quickstart_with_docker_compose/docker-compose.override-env-example.yml
:language: yaml
:caption: docker-compose.override.yml

and in your ``.env`` file, set the variable:

.. code-block:: bash
DJANGO_CA_EMAIL_HOST=smtp.example.com
Recap
=====

By now, you should have at least four files in ``~/ca/``:
By now, you should have at least **five** files in ``~/ca/``:

.. code-block:: console
user@host:~/ca/$ ls -A
docker-compose.yml docker-compose.override.yml .env dhparam.pem
docker-compose.yml docker-compose.override.yml .env dhparam.pem localsettings.yaml
*************
Start your CA
Expand Down Expand Up @@ -302,7 +308,7 @@ Update
Remember to :ref:`backup your data <docker-compose-backup>` before you perform any update.

In general, updating django-ca is done by getting the :ref:`latest version of docker-compose.yml
<docker-compose.yml>` and then simply recreating the containers:
<quickstart-docker-compose-docker-compose.yml>` and then simply recreating the containers:

.. code-block:: console
Expand Down
2 changes: 1 addition & 1 deletion docs/source/update.rst
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ Note that if you have stored private keys in any custom location with the ``--pa
backup these locations as well.

**Second,** update your :file:`docker-compose.yml` file. Either get the :ref:`latest version of the file
<docker-compose.yml>`, or apply this diff:
<quickstart-docker-compose-docker-compose.yml>`, or apply this diff:

.. code-block:: diff
Expand Down

0 comments on commit fa83e5b

Please sign in to comment.