Running several services in a single container.

Doca, Recipiente, Exportar, Carga, Frete, Envio, Porto

Docker was idealized for running a single service at once. The principal advantage of that is the isolation: you can keep several applications isolated one from the other.
But, it is possible to run several services in a single container with the supervisor. Supervisor is a client/server system to control processes in *nix-like systems.
The following example creates a single container with two services different from each other (the code is the same) controlled by supervisor.
You can download the code at: https://github.com/t3rcio/docker-supervisor

Dockerfile

#Dockerfile
FROM python:3.9

ENV PYTHONUNBUFFERED=1

RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor

WORKDIR /code
COPY . /code
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN mkdir logs

RUN supervisord -c /etc/supervisor/conf.d/supervisord.conf &

docker-compose.yml

#docker-compose.yml
version: "3.9"

services:
   supervisor:
      build: .
      restart: always
      command: /usr/bin/supervisord
      volumes:
         - .:/code

Put the code above in a directory, and execute:

user@user-pc:~$ docker-compose -f docker-compose.yml -up

With that, you just made the container.
To verify whether the services are running, execute:

user@user-pc:~$ tail -f out1.log
(...)
user@user-pc:~$ tail -f out2.log

That’s it :-) With this technique, you can run several services in a single container; you can, for example, have a task scheduler and a task consumer.

References

https://docs.docker.com/config/containers/multi-service_container/

https://github.com/t3rcio/docker-supervisor#:~:text=Docker%20Tutorial%20%3D%3E%20Dockerfile%20%2B%20supervisord.conf

Serving static files with wsgi

Deploy Python/Django apps is not a hard task. However, sometimes some problems can show: deploy static files.

Django’s manual offers a detailed set of instructions to copy and deploy static files on production environments: using STATIC_URL and STATIC_ROOT variables on settings.py. More details here: https://docs.djangoproject.com/en/3.0/howto/static-files/

Yet, you will set the webserver to serve files from paths on settings.py. Follow the instructions here.

Deploy on shared hosting environments

However, the scenery can be more difficult when you don’t have access to web server config files. It is a reality on shared hosts. To solve this problem you can consider using the wsgi file: the config file that sets the interface between webserver and Django app.

It is true that Django’s manual affirms that Django does not serve static files. But there are several developers that use the wsgi to serve these files. We can do this in two ways:
1 – dj-static: https://pypi.org/project/dj-static/
2 – withenoise: http://whitenoise.evans.io/en/stable/

Using dj-static

To perform the installation of dj-static package use the follow commands:

pip install dj-static

Perhaps in your hosting server, you need permission to install packages. To solve this, we can use:

pip install dj-static --user

This command will install the package in your /home directory.
After the installation, it is time to config the WSGI file. Open the WSIG file and add the following lines:

from django.core.wsgi import get_wsgi_application
from dj_static import Cling
(…)
application = Cling(get_wsgi_application())

Finally, you can test your site by accessing it. If your static files doest not loaded, verify the STATIC_URL and STATIC_ROOT variables onsettings.py.

Have you ever found this problem in shared hosting? What solution you have applied to?

References

WSGI: https://wsgi.readthedocs.io/en/latest/what.html
PEP333 : https://www.python.org/dev/peps/pep-3333/
WSGI no Django: https://docs.djangoproject.com/pt-br/3.0/howto/deployment/wsgi/