Skip to content

Commit

Permalink
docs(WIP): add some usage docs
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobCoffee authored and cofin committed Jun 24, 2024
1 parent 5b6ec30 commit 98f4d67
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 0 deletions.
13 changes: 13 additions & 0 deletions docs/examples/app.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Litestar Fullstack App
After=network.target

[Service]
User=some-user
Group=some-group
WorkingDirectory=/opt/litestar-app/
Environment="PATH=/opt/litestar-app/.venv/bin"
ExecStart=/opt/litestar-app/.venv/bin/app run-all --host 127.0.0.1 --port 8000 --http-workers 2

[Install]
WantedBy=multi-user.target
87 changes: 87 additions & 0 deletions docs/usage/deployment.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
==========
Deployment
==========

.. note:: This section is a work in progress.
Would you like to contribute? See the :doc:`/contribution-guide`.

No matter how you decide to deploy your application, this is a Litestar app and the
:doc:`Litestar Deployment Guide <litestar:topics/deployment/index>` is a great place to start.

Docker
------

This repository contains example ``Dockerfile``'s and ``docker-compose.yml``'s for deploying
your application for development and production.

Development
^^^^^^^^^^^

Everyone's development environment is different, but we've included a ``docker-compose.infra.yml`` file that
contains the required infrastructure services for running the application.
This includes a PostgreSQL database, a Redis cache, local mail with `MailHog <https://github.com/mailhog/MailHog>`_,
and object storage with `Minio <https://min.io/>`_.

This allows you to just `docker compose up` to start your services, and then run the application
locally with (for example) the Litestar CLI: ``litestar run --debug --reload``.

We also have a ``Dockerfile`` for development:

.. dropdown:: Example ``Dockerfile`` for development

.. literalinclude:: ../../deploy/docker/dev/Dockerfile
:language: dockerfile
:linenos:

Production
^^^^^^^^^^

.. dropdown:: Example ``Dockerfile`` for production

.. literalinclude:: ../../deploy/docker/run/Dockerfile
:language: dockerfile
:linenos:

For Docker Compose, run the ``docker-compose.yml`` file, replacing the environment
variables as needed with your own values.

Railway
-------

This repository also has a template on `Railway <https://railway.app/template/KmHMvQ?referralCode=BMcs0x>`_.

.. note:: This link is a referral link that will give us a credit if you decide to utilize the service
and host your application(s) on their platform. This helps us to continue to provide great open source
software for the community by offsetting our hosting costs, and doesn't cost you anything extra.

Cloud Platforms
---------------

.. todo:: Add examples for deploying to cloud platforms.
Would you like to contribute? See the :doc:`/contribution-guide`.


Service
-------

You can also wrap this application into a ``systemd`` service, or use a process manager like
`Supervisor <http://supervisord.org/>`_.

.. dropdown:: Example ``systemd`` service

.. literalinclude:: ../examples/app.service
:language: ini
:linenos:

.. dropdown:: Manage the ``systemd`` service

.. code-block:: bash
# Enable the service.
sudo systemctl enable app
# Stop the service.
sudo systemctl stop app
# (Re)start the service.
sudo systemctl restart app
3 changes: 3 additions & 0 deletions docs/usage/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ Usage
installation
development
startup
deployment
user-management
task-queue
73 changes: 73 additions & 0 deletions docs/usage/task-queue.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
===========
Task Queues
===========

This application features a Redis-backed job/task queue thanks to the :doc:`SAQ <saq:index>` library.
You can use it to run one-off tasks, or recurring tasks on a cron-like schedule.

We are utilizing the `litestar-saq <https://github.com/cofin/litestar-saq>`_ plugin for native
integration with Litestar.

Background
----------

Your application's task queue serves a variety of purposes, this section aims to explain when and why you would
want to use a task queue.

Cron jobs are essential for updating the database, performing regular cleanup, sending scheduled emails for various
purposes, and conducting auditing or alerting activities.

Startup jobs focus on initializing essential services, loading initial data, conducting health checks, starting
monitoring services, and allocating necessary resources like database connections.

Conversely, shutdown jobs ensure the graceful release of resources, synchronization of
data with storage, completion of background jobs, and logging of shutdown activities.

Additionally, one-off jobs handle on-demand processing of user-generated content, execution of ad-hoc database tasks,
administrative operations like account resets or data migrations, and event-driven tasks triggered by
specific user actions or system events.

.. tip:: There are several alternatives to ``SAQ``, but we have chosen it for its speed, ease of use, and feature set.
Some other options include:

* Cron jobs via the OS
* `Systemd timers <https://wiki.archlinux.org/title/systemd/Timers>`_
* `RQ <https://github.com/rq/rq>`_
* `ARQ <https://github.com/samuelcolvin/arq>`_
* `SAQ <https://github.com/tobymao/saq>`_
* `Celery <https://docs.celeryq.dev/en/stable/>`_

How
---

Jobs are set up on a per-domain basis. The ``Worker`` class is instantiated when the application starts up.
This calls :func:`litetar_saq.cli.run_worker_process` that has looks at certain directories to find jobs.

Each domain has a directory in it for jobs, in the pattern of ``src/app/domain/$DOMAIN/jobs``. There are separate
modules for each type of job (``scheduled``, ``startup``, ``shutdown``, and ``tasks``).

It is self-explanatory, jobs in the ``startup`` directory are run on startup, etc.
Scheduled jobs are the only slightly unique ones, in that they are a list of :class:`CronJob <saq.job.CronJob>`'s.
That looks something like:

.. code-block:: python
scheduled_tasks: list[CronJob] = [
CronJob(
function=generate_analytics_report,
cron="*/30 * * * *",
heartbeat=30,
unique=True,
timeout=120,
),
CronJob(
function=send_daily_digest,
cron="*/35 * * * *",
heartbeat=30,
unique=True,
timeout=120,
),
]
So you see we have to scheduled jobs every 30 and 35 minutes. When the app starts up, these will run just as a
system cron job would.
13 changes: 13 additions & 0 deletions docs/usage/user-management.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
===============
User Management
===============

This application features a user management system, including teams. We have built
API endpoints and a CLI for managing them as you see fit.

.. todo:: Document the API endpoints and CLI commands for managing users and teams.
Would you like to contribute? See the :doc:`/contribution-guide`.

.. click:: app.cli:user_management_app
:prog: app
:nested: full

0 comments on commit 98f4d67

Please sign in to comment.