Mostrando las entradas con la etiqueta Tutoriales. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Tutoriales. Mostrar todas las entradas

domingo, 24 de agosto de 2025

📘 Guía rápida: Despliegue de Django en un VPS con Ubuntu


📘 Guía rápida: Despliegue de Django en un VPS con Ubuntu

1. 🔧 Preparación del servidor

  1. Conéctate por SSH a tu VPS (ejemplo con Contabo o DigitalOcean):

    ssh usuario@IP_DEL_SERVIDOR
  2. Actualiza paquetes:

    sudo apt update && sudo apt upgrade -y
  3. Instala dependencias:

    sudo apt install python3 python3-pip python3-venv git curl -y

2. 🐍 Crear entorno de Django

  1. Clona tu proyecto desde GitLab/GitHub:

    git clone https://gitlab.com/usuario/proyecto.git cd proyecto
  2. Crea un entorno virtual:

    python3 -m venv venv source venv/bin/activate
  3. Instala dependencias:

    pip install -r requirements.txt

3. 🗄️ Configurar base de datos PostgreSQL

  1. Instala PostgreSQL y librerías:

    sudo apt install postgresql postgresql-contrib libpq-dev -y
  2. Crea base de datos y usuario:

    sudo -u postgres psql CREATE DATABASE miapp; CREATE USER miusuario WITH PASSWORD 'mipassword'; ALTER ROLE miusuario SET client_encoding TO 'utf8'; ALTER ROLE miusuario SET default_transaction_isolation TO 'read committed'; ALTER ROLE miusuario SET timezone TO 'UTC'; GRANT ALL PRIVILEGES ON DATABASE miapp TO miusuario; \q
  3. Configura settings.py en tu proyecto:

    DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'miapp', 'USER': 'miusuario', 'PASSWORD': 'mipassword', 'HOST': 'localhost', 'PORT': '5432', } }

4. 🛠 Migraciones y archivos estáticos

python manage.py migrate python manage.py collectstatic --noinput

5. 🚀 Configuración de Gunicorn

Instala Gunicorn:

pip install gunicorn

Prueba que funcione:

gunicorn --bind 0.0.0.0:8000 proyecto.wsgi:application

6. ⚙️ Configuración de Systemd

Crea un servicio para tu app en /etc/systemd/system/miapp.service:

[Unit] Description=Gunicorn instance to serve Django app After=network.target [Service] User=usuario Group=www-data WorkingDirectory=/home/usuario/proyecto ExecStart=/home/usuario/proyecto/venv/bin/gunicorn --workers 3 --bind unix:/home/usuario/proyecto/miapp.sock proyecto.wsgi:application [Install] WantedBy=multi-user.target

Activa el servicio:

sudo systemctl start miapp sudo systemctl enable miapp

7. 🌐 Configuración de Nginx

Instala Nginx:

sudo apt install nginx -y

Configura un bloque de servidor en /etc/nginx/sites-available/miapp:

server { listen 80; server_name midominio.com www.midominio.com; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/usuario/proyecto; } location / { include proxy_params; proxy_pass http://unix:/home/usuario/proyecto/miapp.sock; } }

Habilita la configuración:

sudo ln -s /etc/nginx/sites-available/miapp /etc/nginx/sites-enabled sudo nginx -t sudo systemctl restart nginx

8. 🔒 Certificado SSL con Let’s Encrypt

sudo apt install certbot python3-certbot-nginx -y sudo certbot --nginx -d midominio.com -d www.midominio.com

✅ Conclusión

Ya tienes tu aplicación Django desplegada en un VPS con Ubuntu, lista para producción con PostgreSQL, Gunicorn, Nginx y SSL.

📌 Si quieres ver más detalles paso a paso, junto con ejemplos avanzados (Docker, automatización, multitenant, seguridad y más), revisa el curso completo aquí:

👉 Curso en Udemy: Despliegue de aplicaciones Django en varias plataformas VPS



O mira si está en descuento actualmente en este enlace:



🚀Guía: Deploy local de Django + PostgreSQL + Gunicorn + Nginx en Red Hat

Guía: Deploy local de Django + PostgreSQL + Gunicorn + Nginx en Red Hat




Escenario: vamos a correr la app en Red Hat, accesible en http://localhost, con PostgreSQL local, Gunicorn como WSGI y Nginx como reverse proxy.

Supuesto: el proyecto Django ya existe y llega desde GitLab.

0) Preparación del sistema

sudo dnf update -y
sudo dnf install -y git python3 python3-pip python3-venv nginx
sudo dnf install -y postgresql-server postgresql-contrib postgresql-devel
sudo dnf install -y gcc python3-devel
sudo dnf install -y policycoreutils-python-utils

1) Clonar el proyecto desde GitLab

mkdir -p ~/apps && cd ~/apps
git clone git@gitlab.com:tu-usuario/tu-proyecto.git
cd tu-proyecto

2) Crear entorno virtual e instalar dependencias

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip wheel
pip install -r requirements.txt
pip install "psycopg[binary]"

3) Configurar PostgreSQL

sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql

Crear DB y usuario:

sudo -u postgres psql
CREATE DATABASE myprojectdb;
CREATE USER myprojectuser WITH PASSWORD 'cambia-esta-clave';
GRANT ALL PRIVILEGES ON DATABASE myprojectdb TO myprojectuser;
\q

4) Configurar Django

En settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'myprojectdb',
        'USER': 'myprojectuser',
        'PASSWORD': 'cambia-esta-clave',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'static'

5) Migraciones y estáticos

python manage.py migrate
python manage.py collectstatic
python manage.py createsuperuser

6) Configurar Gunicorn (systemd)

sudo nano /etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn for Django
After=network.target

[Service]
User=tuusuario
Group=nginx
WorkingDirectory=/home/tuusuario/apps/tu-proyecto
ExecStart=/home/tuusuario/apps/tu-proyecto/.venv/bin/gunicorn \
  --workers 3 \
  --bind unix:/run/gunicorn/myproject.sock \
  myproject.wsgi:application

[Install]
WantedBy=multi-user.target
sudo systemctl start gunicorn
sudo systemctl enable gunicorn

7) Configurar Nginx

sudo nano /etc/nginx/conf.d/myproject.conf
server {
    listen 80;
    server_name localhost;

    location /static/ {
        alias /home/tuusuario/apps/tu-proyecto/static/;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn/myproject.sock;
    }
}
sudo nginx -t
sudo systemctl restart nginx

8) Flujo de actualización desde GitLab

cd ~/apps/tu-proyecto
git pull origin main
source .venv/bin/activate
pip install -r requirements.txt --upgrade
python manage.py migrate
python manage.py collectstatic --noinput
sudo systemctl restart gunicorn
sudo systemctl reload nginx

✅ Diferencias con Ubuntu

  • Gestor de paquetes: apt (Ubuntu) vs dnf/yum (Red Hat).
  • Nginx: en Red Hat usa conf.d/, en Ubuntu sites-available/enabled.
  • Firewall: ufw (Ubuntu) vs firewalld (Red Hat).
  • SELinux: en Red Hat suele estar activo (etiquetas extra).

Autor: Daniel Bojorge - Debs Consultores


Aprende más en los cursos de udemy:

domingo, 21 de mayo de 2023

🚀 Subir Archivos CSV con Django de Python 🐍 de forma sencilla.

 


REEL


Video


💥Recuerda que en este enlace puedes encontrar mis cursos con descuentos hasta USD 9.99 x Curso👇
 🎯 https://rebrand.ly/cursos-debs-mejor-precio



martes, 24 de enero de 2023

🚀 Mostrar Static Files de Admin de Django 🐍 en Server VPS Ubuntu Producción con Apache2




🎯 Actualización #Clase #GRATIS #Curso #Deploy 🚀 Aplicaciones #Django en Varias #Plataformas 💰 Aprovecha #Descuento US $ 9.99
📚 Aprende a #Desplegar tu #App en un VPS usando Git +:
#Apache2
◾ Apache2 + #GitLab #Runner (CI/CD)
◾ NGINX + GUnicorn
◾ NGINX + #GUnicorn + GitLab Runner (#CICD)
◾ Sin #collectstatic mostrar archivos estáticos del admin (Actualización)
#ubuntu #server #VPS


domingo, 16 de mayo de 2021

Tutorial VUEJS: Refresh del token token access vencido



En el siguiente video, dejo una clase gratis de la sección de Login, que ya estará la próxima semana en el curso de Aprende Vue + Django con Ejemplos Prácticos.  Dicha clase trata del hacer refresh del token access.  Espero te sea de interés, recuerda registrarte si estás interesado en más tutoriales y/o clases gratis.



jueves, 11 de marzo de 2021

🐍 Filtrar registros para usuario logueado con Django de Python - Video Tutorial

 


En esta ocasión, les traigo una clase en Video donde muestro cómo poder filtrar los registros en base al usuario logueado, muy útil cuando se requiere, por ejemplo, filtrar los registros que pertenecen al usuario, aunque también puede ser usado para cualquier otro tipo de filtro.

 

Bueno, te dejo el video..

Enlace a youtube (https://youtu.be/rtr9ofxsP_4)
 

Si te interesa este u otro curso, puedees acceder a este enlace para que veas todos los cursos con el precio oficial en Udemy.

 

http://bit.ly/8-cursos-debsconsultores 

 

 

 Puedes probar si hoy tengo activado descuento en este enlace.

https://bit.ly/cursos-mejor-precio-udemy 

 

 También, puedes suscribirte y estar enterado cuando estén promociones en los cursos o nuevo material acá en el blog.

 

 

lunes, 12 de octubre de 2020

Mantener Activo Menú en el Template con Django

 


Hace algunos días publiqué en el canal de youtube, cómo mantener el menú activo, utilizando el Template Engine de Django, lo puedes ver en acá



En base al video anterior, pudieron ver que  el proceso es bastante extenso si el menú crece mucho.  Partiendo de ahí y que estamos en el Front End, podemos hacerlo más rápido si con jQuery capturamos todos los enlaces y los comparamos con el valor que contenga la variable de django {‌{request.path}}, ya con esto, podemos hacer una comparación aprovechando la nueva implementación de ECMAScript 6, para esto, una vez cargado el DOM (osea dentro de la instrucción $(document).ready(function () {) colocar el siguiente script:


Acá básicamente tomamos todos los enlaces y para tener la certeza que nos referimos a un enlace del menú, hacemos un filtro (en el selector) de todos los elementos que en la clase tengan collapse-item y que su padre sea collapse y el padre de este sea nav-item, dicho de otra forma, todo elemento con clase nav-item que contenga collapsey que a su vez contenga collapse-item , esto traerá todos los enlaces, en este punto, los recorremos todos y preguntamos si la ruta actual (request.path de Django) contiene la ruta del enlace que se está iterando, si lo contiene, entonces marcamos ese enlace agregándole la clase active y al div padre que contiene collpase y a la vez al padre de este que tenga la clase nav-item.


Si tienes dudas, favor hazme la llegar, no creí necesario una clase en video, pero si es necesario indícamelo en un mensaje y procederé a hacerlo.


Recuerda que puedes adquirir el curso en el siguiente enlace:

También puedes revisar si está activa alguna promoción de Udemy para todos mis cursos en este enlace

http://bit.ly/8-cursos-debsconsultores


E Incluso revisar si yo he activado descuento, por lo general, son cupones del mejor precio posible, esto es USD 9.99 viendo este enlace

viernes, 27 de septiembre de 2019

Modificar Estado de Varios Registros al Mismo tiempo con Django y jquery



 http://bit.ly/DJFULL-BLOG12019

En este tutorial, veremos cómo poder cambiar el estado de un listado de Categorías de una sola vez, para eso haremos uso de jQuery en el FrontEnd para recoger todos los id's de las categorías y con Django en el BackEnd procesaremos la lista.

Nuestra plantilla luce algo así


La idea principal es poder seleccionar más de un registro y al dar click en el botón Inactivar/Activar poder cambiar el estado de todos los registros seleccionados.

La tabla se está renderizando como una tabla normal de html y bootstrap, de la siguiente forma:



Nota que en la última columna de la tabla está el checkbox, que tiene por nombre record, esto es importante porque así los filtraremos.

Para mostrar la información, tenemos el siguiente modelo:

 class Categoria(ClaseModelo):  
   descripcion = models.CharField(  
     max_length=150,  
     help_text='Descripción de la Categoría',  
     unique=True  
   )  
   def __str__(self):  
     return '{}'.format(self.descripcion)  
   def save(self):  
     self.descripcion = self.descripcion.upper()  
     super(Categoria, self).save()  
   class Meta:  
     verbose_name_plural= "Categorias"

Asumiré que ya hay registros y ya tienes toda la estructura de un proyecto, por tanto nos iremos a trabajar en el FrontEnd, en la plantilla que muestra la tabla y trabajaremos en el evento click del botón, el cual tiene como id btnInactivar,

 $("#btnInactivar").click(function(e){  
    e.preventDefault();  
    var ids = [];  
    $("table tbody").find('input[name="record"]').each(function(){  
      if($(this).is(":checked")){  
       var id = $(this).parents("tr").find("td").eq(0).html();  
       ids.push(id);  
      }  
    });  
 }); 

Como podemos ver, primeramente creamos un arreglo llamado ids, recorremos la tabla y buscamos los input que el name sea record, luego preguntamos si ese input tiene check, de tenerlo, tomamos el valor de la columna cero, la del id (var id = $(this).parents("tr").find("td").eq(0).html();) y agregamos el valor del id al arreglo  ids.push(id);.

Ya que tenemos capturados todos los ids, ahora pondré el evento click completo, donde puedes ver el uso de ajax que invoca una ruta, a la cual se le pasa la lista el arreglo de ids recopilados

 $("#btnInactivar").click(function(e){  
    e.preventDefault();  
    var ids = [];  
    $("table tbody").find('input[name="record"]').each(function(){  
      if($(this).is(":checked")){  
       var id = $(this).parents("tr").find("td").eq(0).html();  
       ids.push(id);  
      }  
    });  
    console.log(ids);  
    if(ids.length==0){  
     alert("Debe Seleccionar al menos un registro");  
     return false;  
    }  
    var token = '{{csrf_token}}';  
    var data = JSON.stringify({"ids":ids});  
    data = {"ids[]":ids};  
    //console.log(data);  
    $.ajax({  
     headers: { "X-CSRFToken": token },  
     url: "{% url 'inv:categoria_change_state' %}",  
     type: "POST",  
     data: data,  
     success: function(e){  
      if(e="OK"){  
       location.reload(true);  
      }  
     },  
     error: function(a,b,c){  
      alert(c);  
     }  
    });  
   });  


Lo importante de todo lo anterior es ver cómo se inicializa la variable data con el arreglo de ids.
var data = JSON.stringify({"ids":ids});
data = {"ids[]":ids};

Esta forma, es que recibirá Django en el BackEnd en forma de lista.

Otros datos importantes, el token csrf que debe ir incluido en toda petición POST hacia un backend en Django y la ruta que invoca (url: "{% url 'inv:categoria_change_state' %}") que aún no lo tenemos, pero ya iremos al backend.
Al finalizar, si todo bien, se hará una recarga de la página y listo, del lado del Front hemos terminado, sólo falta aclarar que en mi caso, esta plantilla se llama categoria_list_activate_many.html.

En el BackEnd, lo primero será crear una vista y para trabajar todo en la misma, haremos una vista de funciones, a la cual le declararemos dos variables conteniendo el nombre de la plantilla y un contexto vacío, bueno, no escribo más y te dejo la vista.

 from django.shortcuts import HttpResponse  
 def categoria_change_state(request):  
   template_name = "inv/categoria_list_activate_many.html"  
   contexto={}  
   if request.method=="GET":  
     cat = Categoria.objects.all().order_by("id")  
     contexto={"obj":cat}  
   if request.method=="POST":  
     ids=request.POST.getlist("ids[]")  

     cat_change = Categoria.objects.filter(pk__in=ids)  

     for item in cat_change:  

       item.estado = not item.estado  
       item.save()  

     return HttpResponse("OK")  
   return render(request,template_name,contexto)


La vista está divida en dos partes, si el método es GET, únicamente hará el filtro de todas las categorías ordenadas por id, luego pasa ese filtro a la variable contexto que luego (línea final) retorna el control a la plantilla, a la cual le pasa el contexto.

    return render(request,template_name,contexto)

La segunda parte, es cuando se invoca el método POST, en nuestro caso, mediante ajax del frontend.  en este punto, lo importante es ver cómo pide el valor de la lista

ids=request.POST.getlist("ids[]")

Si te fijas, es igual a como se envió desde el front end, pero se le indica que es una lista (getlist), importante, debe tener los dos corchetes de apertura y cierre ([])

Luego de tener la lista, lo próximo es filtrar del modelo categoría todos los objetos que en su pk tengan el id de la lista anterior, para eso utilizamos el elmento de ORM in.

Pude agregar una validación, si devolvía objetos y si no había, se lo hiciera saber al fronend por medio del return HTTResponse, pero al final no lo hice.

Ok, con todos los objetos, lo que hará es recorrer esa variable y por cada uno, irá cambiando el estado a lo contrario de lo que tenía y lo irá guardando uno por uno:

 for item in cat_change:  
       print(item.id,item.descripcion,item.estado)  
       item.estado = not item.estado  
       item.save() 

Al finalizar envía la palabra OK, por medio de HttpResponse (importante importarlo) y listo, ya tenemos toda la funcionalidad.


Sólo hará falta definir las rutas, una para mostrar la lista y la otra para trabajar el POST:
 from .views import  categoria_change_state  
 urlpatterns = [  
   path('categorias-list/',categoria_change_state, name='categoria_list_activar'),  
   path('categorias-change-state/',categoria_change_state, name='categoria_change_state'),  
 ]  

Y bueno, espero que este pequeño aporte te sea de utilidad, cualquier duda, puedes consultar acá o también puedes adquirir el curso más completo que he podido hacer sobre Desarrollo Web con Python usando Django.


 Por tiempo limitado descuento del 95%

Por tiempo limitado, 95% con este enlace http://bit.ly/lastpromo9 o puedes escribirme para saber qué promoción puedo tener, pero te garantizo que vale la pena.

Bueno, será hasta la próxima y recuerda el enlace donde encontrarás muchos cursos con descuento http://bit.ly/lastpromo9

miércoles, 15 de mayo de 2019

Manejo Básico (básico) de GIT


En esta ocasión, decidí escribir un artículo básico (aclaro, bastante básico) sobre git, que obviamente pueda que existan otras partes para hablar de los branches (ramas) y esas cosas.  De momento, con estas instrucciones he podido trabajar con los proyectos de los cursos que tengo publicado (y los que vienen en camino).

Según la wikipedia (al día que escribí este artículo), define git como:
Git (pronunciado "guit"​) es un software de control de versiones diseñado por Linus Torvalds, pensando en la eficiencia y la confiabilidad del mantenimiento de versiones de aplicaciones cuando éstas tienen un gran número de archivos de código fuente. Su propósito es llevar registro de los cambios en archivos de computadora y coordinar el trabajo que varias personas realizan sobre archivos compartidos.

Trabajaremos con un repositorio remoto usando gitlab

Gitlab es un servicio web de control de versiones y desarrollo de software colaborativo basado en Git. Además de gestor de repositorios, el servicio ofrece también alojamiento de wikis y un sistema de seguimiento de errores, todo ello publicado bajo una Licencia de código abierto.

Por tanto, tomaremos la base que ya tienes un proyecto (o ya has iniciado uno) en local y te decidiste a usar git, para lo cual usarás gitlab como repositorio remoto.

Crear Proyecto en GITHUB, seleccionar si el proyecto será público o privado (en la imagen seleccioné privado

Acá indicaremos el nombre, en mi caso le puse por nombre ordenes. Muy importante, seleccionar el tipo de proyecto, si será privado o público.






Una vez creado, gitlab nos da algunas instrucciones a seguir en dependencia de qué tenemos creado, si estamos iniciando, se debería de ejecutar las primeras instrucciones, como crear el archivo readme y realizar el primer commit.

Pero en algo coinciden ambas opciones, se debe agregar los archivos (git add), realizar un commit, para luego enviar los cambios al repositorio de github (llamado origin).

Tareas en el proyecto local


En la imagen anterior, puedes observar las siguientes tareas.

Inicializar repositorio git para nuestro proyecto
git init

Agregar repositorio remoto
git remote add origin https://github.com/debsdaniel/ordenes.git

Verficiar estado del repositorio, se marcarán en rojo todos los archivos (o directorios) que no han sido incluidos
git status



Incluir archivos para seguimiento con GIT
git add .

Cuando tengamos algunos cambios, debemos agregarlos al repositorio, para esto se utiliza el comando git add, el punto al final, le indicamos agregue (incluya) todos los archivos con modificaciones o nuevos.  Para saber cuáles son estos archivos, es bueno ejecutar el comando git status, para saber cuáles archivos serán incluidos.




Guardar los cambios y agregar mensaje
git commit -m "mensaje"

Con el commit, lo que harás es guardar los cambios en el repositorio, para esto, se te pedirá que agregues un mensaje para poder tener una especio de "etiqueta" o mejor dicho, mensaje indicando qué cambios o qué etapa llevas del proyecto al momento del guardado.




Actualizar repositorio remoto
git push -u origin master

En este punto, lo que hace el git push, es tomar nuestro proyecto local (master) y actualizar el repositorio remoto (origin), con el último commit realizado.




Podemos ahora ver en github que ya está nuestro proyecto completo.

Si realizas cambios, básicamente sería ejecutar

git status
git add .
git commit -m "mensaje"
git push -u origin master

Con lo cual, estaremos:

  • Viendo qué archivos cambiaron (git status), es saludable revisar para saber que se vean las modificaciones únicamente de los archivos que hemos trabajado.
  • Incluyendo los archivos modificados (git add .)
  • Actualizando repositorio local (git commit)
  • Actualizando repositorio remoto (git push)

Y listo, con esto hemos visto, muy, pero muy básicamente el manejo de git, que aunque está bastante básico, ya te servirá para manejar tus proyectos. 

En otra ocasión ampliaremos el manejo de git con otras funcionalidades como ramas, reversión de commit, etiquetas (tag), etc.

Para el ejemplo se utilizo un proyecto ficticio elaborado en Django y utilizando la cuenta debsdaniel de github.  El código fuente de los proyectos que he subido a repositorios remoto, lo pueden encontrar en https://github.com/debsconsultores

Nos vemos hasta en la próxima entrega.

 
>