Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Adding docker and supervisor deployment guides #2724

Merged
merged 5 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs/topics/deployment/docker.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Docker
===========

This uses the default python container https://hub.docker.com/_/python

Dockerfile
-----------

.. code-block:: docker

FROM python:3.12
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./src /
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"]


This copies the `src` folder on your machine to the `/code` in the docker container and runs your app via uvicorn. Adjust according to whichever asgi server you choose.

:doc:`manually-with-asgi-server`


Docker-compose
---------------

If you want to run the container as part of a docker-compose setup then you can simply use this compose file

.. code-block:: yaml

services:
api:
build:
context: ./
dockerfile: Dockerfile
container_name: "api"
depends_on:
- database
ports:
- "80:80"
2 changes: 2 additions & 0 deletions docs/topics/deployment/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ Contents

nginx-unit
manually-with-asgi-server
docker
supervisor
cofin marked this conversation as resolved.
Show resolved Hide resolved
187 changes: 187 additions & 0 deletions docs/topics/deployment/supervisor.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
Supervisor (linux)
==================

To keep a litestar app running you need to set it as a service. The 2 main ways to do that on Ubuntui is to use systemctl or supervisor. Both use unit files to define the service

Supervisor is an additional package you need to install but i find it much easier to monitor the service than with systemctl

.. code-block:: sh

sudo apt install supervisor

.. _conf_file:

Conf file
----------

Supervisord uses a config file for defining services http://supervisord.org/configuration.html

.. code-block:: text

[program:api]
directory=/opt/api/src
command=/opt/api/venv/bin/python main.py
redirect_stderr=true
stdout_logfile=/var/log/api.log
stdout_logfile_backups=10
autostart=true
autorestart=true


`[program:api]` will be your service name. so `supervisorctl start api`

`directory=/...` the directory where the service must run from

`command=...` the script the service must run. notice the python executable path, this uses the venv's python to run the app.

You will need to reload the supervisor config to load your new service file. do so with:

.. code-block:: sh

sudo supervisorctl reread
sudo supervisorctl update


to start/stop the service

.. code-block:: sh

sudo supervisorctl start api
sudo supervisorctl stop api


to get the status

.. code-block:: sh

sudo supervisorctl status api


to watch the output

.. code-block:: sh

sudo supervisorctl tail -f api


Start the service if its not started. make sure its running. check the output to make sure there aren't any errors. and if all that went according to plan your litestar application should be accessible on
http://yyy.yyy.yyy.yyy:80


Alias for easy control
=========================================

This follows onto the Supervisor setup.

To make things easier to handle the service, here's an alias to use that will make things much easier for you. this introduces some commands like:

.. code-block:: sh

api start
api stop
api restart
api status
api watch


Create an alias file `/etc/profile.d/api.sh` this is where the magic happens to let us simply use `api start` instead of `sudo supervisorctl start api` (all that extra typing.. urrgghhh). Adding it to `/etc/profile.d/` makes the alias available for all users on that system. They would still however need to pass sudo for these commands.

.. code-block:: sh

api() {
case $1 in
start)
echo "Starting"
sudo supervisorctl start api || true
;;
stop)
echo "Stopping"
sudo supervisorctl stop api || true
;;
restart)
echo "Stopping"
sudo supervisorctl stop api || true
sleep 2
echo "Starting"
sudo supervisorctl start api || true
;;
status)
echo "Status"
sudo supervisorctl status api || true
;;
watch)
sudo supervisorctl tail -f api
;;

help)
echo "Available options:"
echo " api start"
echo " api stop"
echo " api restart"
echo " api status"
echo " api watch"
;;

*)
cd /opt/api
;;
esac
}

To activate the alias without restarting your session use `source /etc/profile.d/api.sh`.

Using the `watch` command lets you monitor the realtime output of your application.


Updating your application
--------------------------

A cool tip that the whole alias brings to the table is that if you include your supervisor conf file and the alias in your code base, you can do something like this for for updating your entire application.

.. code-block:: sh

api() {
case $1 in
# ... #
update)
echo " > Stopping"
sudo supervisorctl stop api || true

echo " > Updating files"
cd /opt/api
git reset --hard origin/master
git pull origin master

sleep 2

echo " > Linking supervisord service file"
sudo ln -sf /opt/api/server/service.conf /etc/supervisor/conf.d/api.conf
echo " > Linking service alias"
sudo ln -sf /opt/api/server/alias.sh /etc/profile.d/api.sh
source /etc/profile.d/api.sh

sleep 2

echo " > Updating supervisord services"
sudo supervisorctl reread
sudo supervisorctl update

sleep 2

source venv/bin/activate
echo " > Updating dependencies"
pip install -U -r requirements.txt

echo "------------------------"
echo "Done"

read -p "Start the service? (y/n) " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo "Starting"
sudo supervisorctl start api || true
fi
;;

You can sym link both the alias file and the conf file into their respective locations and load them up after a git pull.
Loading