bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


Barra lateral

ASIX Administració de Sistemes Informàtics i Xarxes
Tots els mòduls del cicle
MP01 Implantació de sistemes operatius
Totes les UFs del modul
MP02 Gestió de bases de dades
Totes les UFs del modul
MP03 Programació bàsica
Totes les UFs del modul
MP04 Llenguatges de marques i sistemes de gestió d'informació
Totes les UFs del modul
MP05 Fonaments de maquinari
Totes les UFs del modul
MP06 Administració de sistemes operatius
Totes les UFs del modul
MP07 Planificació i administració de xarxes
Totes les UFs del modul
MP08 Serveis de xarxa i Internet
Totes les UFs del modul
MP09 Implantació d'aplicacions web
Totes les UFs del modul
MP10 Administració de sistemes gestors de bases de dades
Totes les UFs del modul
MP11 Seguretat i alta disponibilitat
Totes les UFs del modul
MP12 Formació i orientació laboral
Totes les UFs del modul
MP13 Empresa i iniciativa emprenedora
Totes les UFs del modul
MP14 Projecte
Totes les UFs del modul
DAM Desenvolupament d’aplicacions multiplataforma
Tots els mòduls del cicle
MP01 Sistemes informàtics
Totes les UFs del modul
MP02 Bases de dades
Totes les UFs del modul
MP03 Programació bàsica
Totes les UFs del modul
MP04 Llenguatges de marques i sistemes de gestió d'informació
Totes les UFs del modul
MP05 Entorns de desenvolupament
Totes les UFs del modul
MP06 Accés a dades
Totes les UFs del modul
MP07 Desenvolupament d’interfícies
Totes les UFs del modul
MP08 Programació multimèdia i dispositius mòbils
Totes les UFs del modul
MP09 Programació de serveis i processos
Totes les UFs del modul
MP10 Sistemes de gestió empresarial
Totes les UFs del modul
MP11 Formació i orientació laboral
Totes les UFs del modul
MP12 Empresa i iniciativa emprenedora
Totes les UFs del modul
MP13 Projecte de síntesi
Totes les UFs del modul
MPDual Mòdul Dual / Projecte
DAW Desenvolupament d’aplicacions web
Tots els mòduls del cicle
MP01 Sistemes informàtics
Totes les UFs del modul
MP02 Bases de dades
Totes les UFs del modul
MP03 Programació
Totes les UFs del modul
MP04 Llenguatge de marques i sistemes de gestió d’informació
Totes les UFs del modul
MP05 Entorns de desenvolupament
Totes les UFs del modul
MP06 Desenvolupament web en entorn client
Totes les UFs del modul
MP07 Desenvolupament web en entorn servidor
Totes les UFs del modul
MP08 Desplegament d'aplicacions web
Totes les UFs del modul
MP09 Disseny d'interfícies web
Totes les UFs del modul
MP10 Formació i Orientació Laboral
Totes les UFs del modul
MP11 Empresa i iniciativa emprenedora
Totes les UFs del modul
MP12 Projecte de síntesi
Totes les UFs del modul
SMX Sistemes Microinformàtics i Xarxes
Tots els mòduls del cicle
MP01 Muntatge i manteniment d’equips
Totes les UFs del modul
MP02 Sistemes Operatius Monolloc
Totes les UFs del modul
MP03 Aplicacions ofimàtiques
Totes les UFs del modul
MP04 Sistemes operatius en xarxa
Totes les UFs del modul
MP05 Xarxes locals
Totes les UFs del modul
MP06 Seguretat informàtica
Totes les UFs del modul
MP07 Serveis de xarxa
Totes les UFs del modul
MP08 Aplicacions Web
Totes les UFs del modul
MP09 Formació i Orientació Laboral
Totes les UFs del modul
MP10 Empresa i iniciativa emprenedora
Totes les UFs del modul
MP11 Anglès
Totes les UFs del modul
MP12 Síntesi
Totes les UFs del modul
CETI Ciberseguretat en Entorns de les Tecnologies de la Informació
Tots els mòduls del cicle
CiberOT Ciberseguretat en Entorns d'Operació
Tots els mòduls del cicle
django_docker

Dockeritzant una aplicació Django

En aquest article dockeritzarem una aplicació Django. Cal haver seguit el tutorial inicial Django o, com a mínim disposar d'un projecte Django amb el complement django-environ per a les variables d'entorn.

Referències:


Dockeritzant amb el servidor de desenvolupament

El Dockerfile permet crear la imatge del contenidor.

Dockerfile
# We Use an official Python runtime as a parent image
FROM python:3.11.7-bullseye
 
# install db libs
RUN apt-get update
RUN apt-get install -y default-mysql-client libmariadb-dev
RUN apt-get install -y libmariadb-dev-compat gcc gdal-bin libjpeg-dev
 
# install app libs
COPY requirements.txt requirements.txt
RUN pip3 install --no-cache-dir -r requirements.txt
 
# Mounts the application code to the image
COPY . code
 
# establish workdir
WORKDIR /code
 
EXPOSE 8000 
 
# runs the development server
ENTRYPOINT ["python3","manage.py"]
CMD ["runserver","0.0.0.0:8000"]

Fixeu-vos en què la darrera instrucció equival a python3 manage.py runserver 0.0.0.0:8000, és a dir, que estem fent servir el servidor de desenvolupament, i no un servidor d'aplicacions específic per producció com uWSGI o Gunicorn.

El docker-compose ens facilita la posada en producció juntament amb la base de dades:

docker-compose.yml
version: '3.1'

services:

  django_app:
    build: .
    restart: always
    ports:
      - 8000:8000
    environment:
      - DATABASE_URL=sqlite:///db.sqlite3
      - DEBUG=False
      - SECRET_KEY=asecretkeyblabla
    volumes:
      - ./db.sqlite3:/code/db.sqlite3

Per posar-ho en marxa primer cal crear un arxiu on persistir la BD local:

$ touch db.sqlite3
$ docker-compose up -d --build

Troubleshooting

He tingut alguns problemes amb la llibreria mysqlclient. He aconseguit que funcionés canviant requirements.txt a una versió anterior (Juny 2023):

mysqlclient==2.1.1


Exercicis

Connecta't al contenidor de l'app Django i:

  1. Fes un migrate per tal de crear les taules de la BD.
  2. Crea un superusuari i loga't al panell d'administració /admin.

Modifica el docker-compose.yml per tal que s'utilitzi una MySQL enlloc de la SQLite de test.

Assegura't que la BD MySQL sigui persistent.

Fes el migrate i crea el superusuari tal i com hem fet abans.

Alguns tips:

  • A l'afegir la MySQL la django_app depèn de la BD per poder funcionar. Per assegurar que primer arrencarà la DB i després la app, cal posar:
    depends_on:
      - db
  • Afegiu un arxiu .dockerignore on li direm quins arxius no cal posar dins el Docker. Si no ho fem, la BD es copiarà dins del Docker de la django_app la 2a vegada que l'executem:
    .dockerignore
    db/


Utilitzant uWSGI + Ngnix

El «invento» que hem fet fins ara funciona, però no és una bona pràctica utilitzar el servidor de desenvolupament de Django (el ./manage.py runserver). Ara configurarem el Dockerfile per aconseguir que s'utilitzi uWSGI + Nginx , tal i com cal per a un servidor de producció.

Recordem que un dels principis bàsics de Docker és el de «un servei per contenidor». Com que necessitem 2 serveis, seguint aquesta filosofia necessitarem un docker-compose.yml amb 2 serveis + la BD. Aquest tutorial segueix la filosofia "un servei per contenidor".

En canvi, aquest altre tutorial per a Flask integra els 2 processos (uWSGI + Nginx) en un sol contenidor. Per tal de tenir diversos serveis utilitza Supervisord, una utilíssima eina que a mode de watchdog vigila que no s'aturi cap dels dos processos.

Dockeritzant uWSGI + Nginx en un sol contenidor

Farem una mescla dels dos tutorials per aconseguir el nostre Django en un sol contenidor.

deploy/supervisord.conf
[supervisord]
# per a dockeritzar necessitem supervisord en foreground
nodaemon=true
 
[program:uwsgi]
command=/usr/local/bin/uwsgi --ini /etc/uwsgi/uwsgi.ini --die-on-term
 
[program:nginx]
command=/usr/sbin/nginx -g 'daemon off;'
deploy/uwsgi.ini
[uwsgi]
# TODO: ull, revisa si el teu projecte es diu 'mysite' o una altra cosa
module = mysite.wsgi
callable = application
uid = nginx
gid = nginx
socket = /tmp/uwsgi.sock
chown-socket = www-data:www-data
chmod-socket = 664
cheaper = 1
processes = %(%k + 1)
# clear environment on exit
vacuum=true
deploy/uwsgi_params
uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;
 
uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;
 
uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
deploy/django-site.conf
server {
    location / {
        try_files $uri @yourapplication;
    }
    location @yourapplication {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
    }
 
    # TODO: aquí cal afegir alguna cosa perquè funcionin el arxius estàtics
}
Dockerfile
# We Use an official Python runtime as a parent image
FROM python:3.11.7-bullseye
 
# install db libs
RUN apt-get update
RUN apt-get install -y default-mysql-client libmariadb-dev
RUN apt-get install -y libmariadb-dev-compat gcc gdal-bin libjpeg-dev
 
# install nginx and supervisor
RUN apt-get install -y --no-install-recommends \
        nginx supervisor
RUN useradd --no-create-home nginx
# install uwsgi
RUN pip3 install uwsgi
 
# adjustments
RUN rm /etc/nginx/sites-enabled/default
RUN rm -r /root/.cache
 
# production conf files
COPY deploy/django-site.conf /etc/nginx/conf.d/
COPY deploy/uwsgi.ini /etc/uwsgi/
COPY deploy/supervisord.conf /etc/
 
# install app libs
COPY requirements.txt requirements.txt
RUN pip3 install --no-cache-dir -r requirements.txt
 
# Mounts the application code to the image
COPY . code
 
# establish workdir
WORKDIR /code
 
EXPOSE 80
 
# runs the development server
CMD ["/usr/bin/supervisord"]

Perquè funcioni bé i veiem la web al port 8000 cal que modifiqueu el docker-compose.yml perquè connecti el port 8000 de la màquina host amb el port 80 del contenidor del Nginx.


Canvia la configuració per a utilitzar el servidor d'aplicacions uWSGI + Nginx enlloc del servidor de desenvolupament.

Ull que alguns arxius van a una nova carpeta /deploy.

Comprova que tornem a tenir el problema dels arxius estàtics accedint al /admin i refrescant fins que vegis que no es veuen els CSS.

Com creus que seria la millor manera de solventar el problema dels arxius estàtics? Implementa-la.

django_docker.txt · Darrera modificació: 2024/02/20 14:59 per enric_mieza_sanchez