You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
393 lines
10 KiB
Markdown
393 lines
10 KiB
Markdown
---
|
|
title: "Despliegue de aplicaciones python sobre django"
|
|
date: 2023-01-23T08:47:22+01:00
|
|
draft: false
|
|
image: featured.png
|
|
categories:
|
|
- documentación
|
|
- Implantación de Aplicaciones Web
|
|
tags:
|
|
- python
|
|
- django
|
|
---
|
|
|
|
|
|
## Tarea 1 Entorno de desarrollo
|
|
|
|
He elegido como entorno de desarrollo la máquina bravo.
|
|
|
|
Primero creamos un entorno virtual de python3 e instalamos las dependencias necesarias para que funcione el proyecto.
|
|
|
|
```bash
|
|
python3 -m venv django
|
|
source django/bin/activate
|
|
pip install django
|
|
```
|
|
|
|
Ahora descargamos el proyecto de github:
|
|
|
|
```bash
|
|
git clone https://github.com/robertorodriguez98/django_tutorial
|
|
```
|
|
|
|
### Configuración de django
|
|
|
|
Comprobamos que vamos a trabajar con una base de datos sqlite. Para ello tenemos que consultar el fichero settings.py. En este caso la base de datos se llama db.sqlite3.
|
|
|
|
```bash
|
|
(django)$ cd django_tutorial
|
|
(django)$ cat django_tutorial/settings.py | egrep -A 5 'DATABASES';
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'django.db.backends.sqlite3',
|
|
'NAME': BASE_DIR / 'db.sqlite3',
|
|
}
|
|
}
|
|
```
|
|
|
|
Para poder acceder desde la dirección www.roberto.gonzalonazareno.org, tenemos que modificar el fichero `django_tutorial/settings.py` y añadir la dirección a la lista de hosts permitidos de la siguiente manera:.
|
|
|
|
```python
|
|
ALLOWED_HOSTS = ['www.roberto.gonzalonazareno.org']
|
|
```
|
|
|
|
Ahora creamos la base de datos:
|
|
|
|
```bash
|
|
(django)$ python manage.py migrate
|
|
```
|
|
|
|
Y el usuario administrador:
|
|
|
|
```bash
|
|
(django)$ python3 manage.py createsuperuser
|
|
```
|
|
|
|
Ahora ejecutamos el servidor web de desarrollo:
|
|
|
|
```bash
|
|
(django)$ python3 manage.py runserver 0.0.0.0:8000
|
|
```
|
|
|
|
Y accedemos a la zona de administración, en este caso en la dirección [www.roberto.gonzalonazareno.org:8000/admin](www.roberto.gonzalonazareno.org:8000/admin) y añadimos dos preguntas con sus posibles respuestas.
|
|
|
|
![Zona de administración](https://i.imgur.com/DZW2zzb.png)
|
|
|
|
* Comprueba en el navegador que la aplicación está funcionando, accede a la url /polls.
|
|
|
|
![Página principal](https://i.imgur.com/p4ZeXNj.png)
|
|
|
|
![Página de votación1](https://i.imgur.com/Bq4Tpml.png)
|
|
|
|
![Página de votación2](https://i.imgur.com/DWNxLFr.png)
|
|
|
|
|
|
### Configuración del servidor web
|
|
|
|
En bravo, el servidor web apache2 ya está instalado y configurado para servir páginas web estáticas. Para servir páginas web dinámicas, tenemos que instalar el módulo wsgi.
|
|
|
|
```bash
|
|
sudo dnf install python3-mod_wsgi
|
|
```
|
|
|
|
Ahora, para que el entorno sea similar al de producción, movemos el proyecto y el entorno virtual a la ruta `/var/www/html/django_tutorial` y `/var/www/html/django` respectivamente.
|
|
|
|
```bash
|
|
sudo mv django_tutorial /var/www/html/
|
|
sudo mv django /var/www/html/
|
|
```
|
|
|
|
Creamos el contenido estático de la aplicación:
|
|
|
|
```bash
|
|
sudo python3 manage.py collectstatic
|
|
```
|
|
|
|
Editamos el fichero `/var/www/html/django_tutorial/django_tutorial/settings.py` y modificamos las siguientes líneas:
|
|
|
|
```python
|
|
ALLOWED_HOSTS = ['*']
|
|
STATIC_ROOT = '/var/www/html/django_tutorial/static/'
|
|
```
|
|
|
|
Ahora configuraremos el servidor apache para que sirva la aplicación django. Para ello, tenemos que crear un fichero de configuración en la ruta `/etc/httpd/sites-available/django.conf` con el siguiente contenido:
|
|
|
|
```apache
|
|
<VirtualHost python.roberto.gonzalonazareno.org:80>
|
|
ServerName python.roberto.gonzalonazareno.org
|
|
DocumentRoot /var/www/html/django_tutorial
|
|
|
|
Alias /static/ /var/www/html/django_tutorial/static/
|
|
|
|
WSGIDaemonProcess django_tutorial python-path=/var/www/html/django_tutorial:/var/www/html/django/lib/python3.9/site-packages
|
|
WSGIProcessGroup django_tutorial
|
|
WSGIScriptAlias / /var/www/html/django_tutorial/django_tutorial/wsgi.py
|
|
|
|
ErrorLog /var/log/httpd/django_tutorial_error.log
|
|
CustomLog /var/log/httpd/django_tutorial_access.log combined
|
|
</VirtualHost>
|
|
```
|
|
|
|
Para que funcione la configuración tenemos que activar el sitio web y reiniciar el servidor web:
|
|
|
|
```bash
|
|
sudo ln -s /etc/httpd/sites-available/django.conf /etc/httpd/sites-enabled/django.conf
|
|
sudo systemctl restart httpd
|
|
```
|
|
|
|
Ahora podemos acceder a la aplicación desde la dirección [python.roberto.gonzalonazareno.org](http://python.roberto.gonzalonazareno.org).
|
|
|
|
## Tarea 2: Entorno de producción
|
|
|
|
Vamos a realizar el despliegue de nuestra aplicación en un entorno de producción, para ello vamos a utilizar nuestro VPS, sigue los siguientes pasos:
|
|
|
|
### Instalación de django y base de datos
|
|
|
|
Clonamos el repositorio:
|
|
|
|
```bash
|
|
git clone https://github.com/robertorodriguez98/django_tutorial
|
|
```
|
|
|
|
Creamos el entorno virtual:
|
|
|
|
```bash
|
|
python3 -m venv django
|
|
source django/bin/activate
|
|
cd django_tutorial
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
Instalamos el módulo que permite que python trabaje con mysql:
|
|
|
|
```bash
|
|
sudo apt install libmariadb-dev
|
|
pip install mysqlclient
|
|
```
|
|
|
|
Tras crear un usuario y la base de datos, configuramos la aplicación para trabajar con mysql, para ello modifica la configuración de la base de datos en el archivo `settings.py`:
|
|
|
|
```python
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'django.db.backends.mysql',
|
|
'NAME': 'django',
|
|
'USER': 'djadmin',
|
|
'PASSWORD': 'djadmin',
|
|
'HOST': 'localhost',
|
|
'PORT': '',
|
|
}
|
|
}
|
|
```
|
|
|
|
Creamos la copia de seguridad de la aplicación en bravo:
|
|
|
|
```bash
|
|
sudo python manage.py dumpdata > /home/roberto/basedatos.json
|
|
```
|
|
|
|
y la restauramos en el VPS:
|
|
|
|
```bash
|
|
(django)$ python manage.py migrate
|
|
(django)$ python manage.py loaddata basedatos.json
|
|
Installed 57 object(s) from 1 fixture(s)
|
|
```
|
|
|
|
Finalmente generamos el contenido estático:
|
|
|
|
```bash
|
|
(django)$ python manage.py collectstatic
|
|
```
|
|
|
|
### Configuración de nginx
|
|
|
|
Instalamos uwsgi:
|
|
|
|
```bash
|
|
pip install uwsgi
|
|
```
|
|
|
|
Podemos comprobar que funciona correctamente:
|
|
|
|
```bash
|
|
uwsgi --http :8080 --chdir /home/calcetines/django_tutorial --wsgi-file django_tutorial/wsgi.py --process 4 --threads 2 --master
|
|
```
|
|
|
|
Creamos el fichero de configuración de uwsgi en `/home/calcetines/django/servidor.ini`:
|
|
|
|
```bash
|
|
[uwsgi]
|
|
http = :8080
|
|
chdir = /home/calcetines/django_tutorial
|
|
wsgi-file = django_tutorial/wsgi.py
|
|
processes = 4
|
|
threads = 2
|
|
```
|
|
|
|
Ahora crearemos la unidad de systemd para que se ejecute uwsgi como servicio en el fichero `/etc/systemd/system/uwsgi-django.service`:
|
|
|
|
```bash
|
|
[Unit]
|
|
Description=uwsgi-django
|
|
After=network.target
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
[Service]
|
|
User=www-data
|
|
Group=www-data
|
|
Restart=always
|
|
|
|
ExecStart=/home/calcetines/django/bin/uwsgi /home/calcetines/django/servidor.ini
|
|
ExecReload=/bin/kill -s HUP $MAINPID
|
|
ExecStop=/bin/kill -s TERM $MAINPID
|
|
|
|
WorkingDirectory=/home/calcetines/django_tutorial
|
|
Environment=PYTHONPATH='/home/calcetines/django_tutorial:/home/calcetines/django/lib/python3.9/site-packages'
|
|
|
|
PrivateTmp=true
|
|
```
|
|
|
|
activamos el servicio:
|
|
|
|
```bash
|
|
systemctl enable uwsgi-django.service
|
|
systemctl start uwsgi-django.service
|
|
```
|
|
|
|
Ahora configuramos nginx como proxy inverso añadiendo la siguiente configuración en el fichero `/etc/nginx/sites-available/django`:
|
|
|
|
```bash
|
|
server {
|
|
listen 80;
|
|
server_name python.admichin.es;
|
|
|
|
if ($host ~ ^[^.]+\.admichin\.es$) {
|
|
return 301 https://$host$request_uri;
|
|
} # managed by Certbot
|
|
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl;
|
|
server_name python.admichin.es;
|
|
access_log /var/log/nginx/example.com_access.log combined;
|
|
error_log /var/log/nginx/example.com_error.log error;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/admichin.es-0001/fullchain.pem; # managed by Certbot
|
|
ssl_certificate_key /etc/letsencrypt/live/admichin.es-0001/privkey.pem; # managed by Certbot
|
|
|
|
location /static/ {
|
|
root /home/calcetines/django_tutorial;
|
|
}
|
|
|
|
location / {
|
|
proxy_pass http://localhost:8080/;
|
|
include proxy_params;
|
|
proxy_redirect off;
|
|
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
}
|
|
}
|
|
```
|
|
|
|
Desactivamos el modo debug en el fichero `settings.py`:
|
|
|
|
```python
|
|
DEBUG = False
|
|
```
|
|
|
|
Finalmente accedemos a la página web en [python.admichin.es](https://python.admichin.es) y comprobamos que funciona correctamente.
|
|
|
|
![base](https://i.imgur.com/ULmiDVn.png)
|
|
|
|
![admin](https://i.imgur.com/c77oBhu.png)
|
|
|
|
![polls](https://i.imgur.com/TnfrXlx.png)
|
|
|
|
## Tarea 3: Modificación de nuestra aplicación
|
|
|
|
### En el entorno de desarrollo
|
|
|
|
Vamos a hacer las siguientes modificaciones:
|
|
|
|
* Modificamos el fichero `django_tutorial/polls/templates/polls/index.html` para que aparezca nuestro nombre.
|
|
* Modificamos la imagen de fondo que se ve la aplicación. Para hacerlo debemos modificar el fichero `django_tutorial/polls/static/polls/css/style.css` y cambiar la siguiente línea, estando la imagen en la carpeta `django_tutorial/polls/static/polls/images`:
|
|
|
|
```css
|
|
background: white url("images/gundam.jpg");
|
|
```
|
|
|
|
Ahora vamos a crear una nueva tabla en la base de datos para almacenar las categorías de las preguntas. Para ello sigue los siguientes pasos:
|
|
|
|
* Se Añade un nuevo modelo al fichero `django_tutorial/polls/models.py`:
|
|
|
|
```python
|
|
class Categoria(models.Model):
|
|
Abr = models.CharField(max_length=4)
|
|
Nombre = models.CharField(max_length=50)
|
|
|
|
def __str__(self):
|
|
return self.Abr+" - "+self.Nombre
|
|
```
|
|
|
|
* Se crea una nueva migración.
|
|
|
|
```bash
|
|
(django)$ sudo python manage.py makemigrations --name tabla_categoria
|
|
|
|
Migrations for 'polls':
|
|
polls/migrations/0002_tabla_categoria.py
|
|
- Create model Categoria
|
|
```
|
|
|
|
* Se realiza la migración.
|
|
|
|
```bash
|
|
(django)$ sudo python manage.py migrate
|
|
Operations to perform:
|
|
Apply all migrations: admin, auth, contenttypes, polls, sessions
|
|
Running migrations:
|
|
Applying polls.0002_tabla_categoria... OK
|
|
```
|
|
|
|
* Se añade el nuevo modelo al sitio de administración de django modificando el fichero `django_tutorial/polls/admin.py`:
|
|
|
|
```python
|
|
from .models import Choice, Question, Categoria
|
|
|
|
[...]
|
|
|
|
admin.site.register(Categoria)
|
|
```
|
|
|
|
Para que los cambios se trasladen al entorno de producción debemos realizar los siguientes pasos:
|
|
|
|
```bash
|
|
(django)$ sudo python manage.py
|
|
(django)$ sudo python manage.py dumpdata > basedatos2.json
|
|
(django)$ sudo python manage.py collectstatic # este no hace falta para el entorno de producción
|
|
(django)$ git push
|
|
```
|
|
|
|
### En el entorno de producción
|
|
|
|
* Se realiza la migración.
|
|
|
|
```bash
|
|
(django)$ git pull
|
|
(django)$ sudo python manage.py migrate
|
|
(django)$ sudo python manage.py loaddata basedatos2.json
|
|
(django)$ sudo python manage.py collectstatic
|
|
```
|
|
|
|
Podemos comprobar que se han producido los cambios:
|
|
|
|
![base](https://i.imgur.com/nSoCgbk.png)
|
|
|
|
![admin](https://i.imgur.com/s5iUxOB.png)
|
|
|
|
![polls](https://i.imgur.com/UrEhNQj.png) |