Uncategorized

Required Inputs in your forms

Como marcar rapidamente todos los elementos required usando solo CSS

Durante la implementacion de un proyecto es posible que algunos campos requeridos ya no lo sean tanto al final. Tambien es posible que en lugar de un * quieran incluir el texto required, o un icono de !, etc. Ir cambiando cada uno de los labels, olvidarte de cambiar uno … es mucho estres.

Vamos a mostrar una forma de añadir dicho elemento de nuestro codigo desde un archivo CSS.

Primero, tenemos nuestro formulario HTML

<form>
     <div class="form-field">
         <label>Nombre</label>
         <input type="text" name"nombre" required />
     </div>



     <div class="form-field">
         <label>Apellido</label>
         <input type="text" name"nombre" />
     </div>


     <input type="submit" value="Enviar" />

</form>

Con nuestro codigo CSS vamos a buscar los elementos .form-field que tengan un hijo con el attributo required y a esos .form-field vamos a marcar su hijo label.

.form-field:has(:required) label:after{
   content: " required";
   color: red;
   font-size: 0.5em;
}

BASH: Como ejecutar el comando cp y excluir ciertos subdirectorios

Quiero copiar todos los archivos de un directorio excepto algunos archivos en un subdirectorio, aprendamos como !

Cuando ejecutamos el comando cp

cp <origen> <destino>

Linux crea ( o modifica ) el archivo destino con el mismo contenido que el archivo origen. Este comando no funciona si <origen> es un directorio

cp <origen> <destino> -r

En ese caso debemos usar el flag -r para indicar que copie el directorio <origen> y todo lo que se encuentre en su subdirectorios. https://man7.org/linux/man-pages/man1/cp.1.html

Sin embargo, en este caso en particular debia copiar <origen> que tenia 30 subdirectorios, menos el directorio assets

Podria haber ejecutado el comando cp 29 veces. Y aunque esa tarea no era muy dificil, no me veia ejecutando a mano 34 comandos de cp mientras espero que termine cada uno para poder ejecutar el siguiente.

Para resolver este problema, debemos indicarle al comando cp cada archivo que queremos copiar y excluir a los que no deseamos.

El comando CP puede recibir UN ORIGEN o MULTIPLES ORIGENES entonces nuestro problema se vuelve este: “como obtengo la lista de archivos de un directorio ? “

ls -A

El comando LS nos devolvera la lista completa de los archivos de ORIGEN. https://man7.org/linux/man-pages/man1/ls.1.html Debemos solo retirar la carpeta no deseada

ls -A | grep -v “assets”

En esta concatenacion de comandos, el comando GREP retirara de los resultados aquellos archivos que esten en la carpeta assets/archivos https://man7.org/linux/man-pages/man1/grep.1.html

El siguiente paso es enviarle esa lista de archivos de ORIGEN al comando CP.

cp -r $( ls -A | grep -v “assets” ) /tmp/DESTINO

Cuando encerramos un comando en $( ) estamos ejecutando primero el contenido del parentesis y luego ese resultado se integra en el comando exterior.

Como excluir servicios con Docker Compose ?

El comando docker-compose up inicia todos los servicios de nuestro proyecto. Incluso servicios que no deseamos como herramientas ( drush, por ejemplo ) o servicios de mantenimiento esporadicos ( docker-compose run –rm ). Entonces como podemos evitar que ciertos servicios se inicien con docker-compose up ?

Existe una opcion en nuestro archivo de configuracion docker-compose.yml con la cual podemos indicar que algun(nos) servicios no esten disponibles al levantar nuestro proyecto.

Profiles en Docker Compose

Cuando declaramos un servicio dentro de nuestro archivo docker-compose.yml podemos establecer la opcion profiles y establecer a que perfiles de ejecucion pertenecera ese servicio.

version: ‘2’

services:
node:
image : node:14
volumes:
– .:/var/www/html
command: “npm start”

db:
image: mysql:5.7
volumes:
– ./mysql:/etc/mysql/conf.d/
– ./db_init.sql:/docker-entrypoint-initdb.d/init.sql

puppeteer:
profiles: [“puppeteer”]
build: ./puppeteer/
volumes:
– ./puppeteer/:/var/www/html/
– ./config:/var/www/html/config
command: “npm start”

En este archivo de configuracion, estamos asignando al perfil puppeteer al servicio puppeteer. Por lo tanto cuando ejecutemos el comando:

docker-compose up -d

Solo se iniciaran los servicios node y db, excluyendo el servicio puppeteer.

Si quisieramos ejecutar el servicio puppeteer debemos indicar el nombre del servicio

docker-compose run –rm puppeteer npm start

Subiendo 2 millones de archivos a la nube

En el contexto de la migracion de un sistema PHP desde un entorno local a servidores en AWS, sin embargo debemos subir mas de 220 Gb de informacion en archivos 100K

Para poder subir archivos a servidores en la nube suelo usar comandos como scp o rsync, los cuales realizan la transferencia de los archivos en una conexion segura. Esta solucion funciona relativamente bien cuando se sube hasta 1000 archivos, sin embargo mas alla de eso se puede empezar algunos problemas.

Velocidad de Transferencia, cuando se realiza la transferencia de un archivo, la velocidad de transferencia empieza a la menor velocidad posible y va aumentando la velocidad conforme dura la transferencia. Eso quiere decir, que se necesita un tiempo minimo para alcanzar la velocidad maxima posible. Un archivo muy pequeño ( 100K ) no permite alcanzar la velocidad maxima de transferencia.

Costo Administrativo, de todo el tiempo que dura realizar la transferencia de un archivo. Una pequeña parte se gasta en coordinaciones entre servidor y cliente, este tiempo no es afectado por el tamaño del archivo. Es decir gasto 5 milisegundos ya sea vaya a subir un archivo de 100K o suba un archivo de 100M. En archivos muy pequeños este tiempo administrativo se transforma en una parte muy importante del tiempo total de transferencia.

Con estos dos problemas, subir 2 millones de archivos de 100K me generaba un tiempo estimado de 1 semana en condiciones de red ideales.

En este escenario recorde mi primer proyecto que desarrolle en la universidad en el año 1999. ( El siglo pasado o el milenio pasado … como prefieran ) que era cortar un archivo grande en pequeños pedazos para guardarlos en disquettes 3 1/4 y llevarlos de las cabinas de internet a la casa.

Debia pasar de 2millones de archivos a apenas 220 archivos de 1G cada uno. Con 1G de tamaño por archivo la velocidad de transferencia seria mucho mayor, y el Costo Administrativo de la Transferencia seria despreciable.

Para lograrlo debia convertir los 2 millones de archivos a uno solo

tar -cf archivos.tar archivos/

Con este comando creaba un archivo unico con el contenido de la carpeta archivos. No realize ninguna compresion ya que el proceso de comprimir podria ser muy demandante en tiempo y CPU para 220 Gb. Ademas que al no ser archivos de texto esperaba que el porcentaje de ahorro no sea mayor al 15%.

Con mi nuevo archivo de 220G, la transferencia hubiera tomando ya no 2 semanas, sino tan solo 5 dias. Sin embargo al ser un archivo unico, se corria el riesgo de corrupcion del archivo o corte de la transferencia y habria q volver a subir todo el archivo … siendo esto un riesgo inaceptable.

Para reducir este riesgo, opte por dividir el archivo en 220 partes de 1G cada una. una transferencia de 1G me tomaba unos 10min aprox. Si alguna fallaba, solo debia repetir esa parte.

split –bytes=1G archivo.tar partes/

Con este comando, indicaba a mi Ubuntu que cortara el archivo.tar en tantas partes de 1G como fuera necesario y lo colocara en la carpeta partes.

El proceso de corte es un proceso que demora bastante … ya vamos 2 horas y contando. Generar cada parte toma un aproximado de 2 minutos, asi que seran unas 8 horas casi 😀

Por mientras se van generando, se puede ir subiendo los archivos por rsync o scp.

Una vez los archivos estan en el servidor debemos proceder a juntarlos

cat * > archivos.tar

Este comando reconstruye el archivo tar original de 220G uniendo todas las partes.

tar -xf archivos.tar archivos/

Este comando descomprime el archivo tar a todos los 2 millones de archivos y lo coloca en la carpeta archivos/

En total reducimos el tiempo de transferencia de 2 semanas a tan solo 4h de creacion del TAR + 8h de creacion de las partes + 40h de transferencia + 8h de union de las partes + 4h de descompresion del TAR = 64h un total de 3 dias.

IMAPCOPY, una herramienta para migrar cuentas de correo entre servidores

SPOILER, migrar cuentas de correo toma su tiempo. Depende de la cantidad de mails existentes en cada cuenta pero diria que entre 8 y 20 horas por cuenta de correo. Asi que preparense un cafe y relajense.

Cuando un cliente quiere salir de Godaddy y migrar a Bluehost, no solo hay que mover el sitio web … tambien debes mover todas sus cuentas de correo. Aca explicaremos como realizar esa migracion usando la herramienta IMAPCOPY.

Primero debemos instalar las herramientas:

sudo apt install imapcopy stunnel4

ImapCopy, no trabaja con protocolos cifrados. Es por eso que necesitaremos la herramienta stunnel4 para abrir un puerto de nuestra maquina y conectarlo con el puerto del servidor remoto. Durante este proceso stunnel4 es la que se encarga del cifrado de la comunicacion.

Editamos el archivo de configuracion /etc/stunnel/stunnel.conf

foreground = yes
debug = info 

[outlook-imap]
client = yes
accept = 127.0.0.1:9993
connect = outlook.office365.com:993
verifyChain = yes 
CApath = /etc/ssl/certs
checkHost = outlook.office365.com
OCSPaia = yes

Con esta configuracion estamos definiendo un servicio que abrira el puerto 9993 en nuestra PC local y lo conectara directamente con el puerto 993 de outlook.office365.com usando los certificados SSL definidos en nuestra PC.

Ejecutamos el servicio

sudo stunel /etc/stunnel/stunnel.conf

Dejamos el servicio corriendo en foreground y en otra terminal procedemos a realizar la configuracion de imapcopy. Creamos un archivo imapcopy.cfg

SourceServer 127.0.0.1
SourcePort 9993

DestServer box2024.bluehost.com
DestPort 143
DenyFlags "\Recent"


Copy "contabilidad@empresa.com" "passwordorigen" "contabilidad@empresa.com" "passworddestino"
Copy "info@empresa.com" "passwordorigen" "info@empresa.com" "passworddestino"

En esta configuracion indico que voy a copiar correos desde el servidor SourceServer ( que si recordamos esta apuntando a outlook.office365.com gracias a stunnel ) al servidor de bluehost.com

Y en las lineas Copy indicamos que cuentas de correo se van a copiar desde el servidor SourceServer hasta el servidor DestServer.

Y lo ejecutamos con el comando:

imapcopy -l 

ImapCopy leera cada carpeta del servidor de origen he ira copiando uno a uno los correos existentes. A una velocidad aproximada de 2 a 5 segundos por correo.

Yo tengo en mi cuenta personal, luego de varias limpiezas unos 15 mil correos. Eso es aproximadamente 21 horas.

ADVERTENCIA, el proceso no se puede cortar. No hay forma de continuar. Si se te va la luz, pierdes el internet, se te cuelga la PC debes borrar la cuenta destino y volver a empezar.

Como configurar una aplicacion aspnet como servicio en Ubuntu

Una vez desarrollada nuestra aplicacion en dotnet, e instalada en el servidor queda un ultimo paso. Como hacer que este permanentemente activa ? Esto lo lograremos creando un servicio en Ubuntu ( Linux )

Lo primero sera crear nuestro archivo de definicion de servicio

# nano /etc/systemd/system/dotnet-app.service

El nombre del servicio en este caso sera dotnet-app, pero podria ser cualquier otro.

Este archivo donet-app.service, tiene un formato .INI que debemos completar, asi:

[Unit]
Description=.NET Web App running on Ubuntu

[Service]
WorkingDirectory=/var/www/dotnet-app
ExecStart=/usr/bin/dotnet /var/www/dotnet-app/app.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-app
User=www-data

[Install]
WantedBy=multi-user.target

En este ejemplo, le estamos indicando a Linux en que carpeta se encuentra el aplicativo ( WorkingDirectory ), cual es el comando para ejecutar el aplicativo ( ExecStart ), que hacer si el servicio se cae ( Restart ) y que usuario deberia correr el servicio ( User )

El siguiente paso es habilitar el servicio, para esto ejecutamos el comando

# systemctl enable dotnet-app.service

Esto iniciara el servicio y se asegurara de iniciarlo cada vez que el servidor se reinicie.

Si queremos ver los logs generados por el aplicativo podemos usar el comando

# journalctl -fu dotnet-app.service

Como instalar una aplicacion aspnet en Ubuntu Linux

Psicologia del Color

La psicología del color es un campo de estudio que está dirigido a analizar cómo percibimos y nos comportamos ante distintos colores, así como las emociones que suscitan en nosotros dichos tonos.

ColorSignificado
RojoPasión
NaranjaDiversion
AmarilloFelicidad
VerdeProsperidad
AzulConfianza
MoradoMisterio
RosaAmor
MarronEstabilidad
BlancoPureza
NegroElegancia

NGINX – Politicas de Cache – CSS JS y Media Elements

¿ Como mejorar el posicionamiento web en Google mejorando la velocidad de carga a traves de las Politicas de Cache de NGINX segun las recomendaciones de Google PageSpeed Insights ?

Un sitio web ( blog, ecommerce o pagina institucional ) estan compuesto por un archivo HTML, varios archivos CSS, varios archivos JS y varios archivos multimedia como imagenes.

Una pagina web estandar puede tener 100 de estos archivos, y cada vez que es visitada deben descargarse estos 100 elementos. Sin embargo, hay elementos que rara vez cambian, como las imagenes, los archivos CSS y JS.

Para evitar descargar en cada visita todos los archivos que componen una pagina existen las politicas de Cache.

Una de las variables que considera google para establecer el ranking de las paginas web, es su velocidad de carga. Las politicas de Cache permiten mejorar esa velocidad de carga y por tanto mejorar el posicionamiento del sitio en google. Puedes evaluar la velocidad de carga de tu sitio web en Google PageSpeed Insights

Politicas de Cache

Las politicas de cache establecen que archivos se van a guardar en el navegador del cliente y durante cuanto tiempo. Asi pues, si vuelves a visitar la pagina esos archivos que se han guardado ya no se vuelven a descargar.

Esto agiliza la carga del sitio web y permite que el servidor atienda de forma mas rapida a otros usuarios.

Implementacion de Politicas de Cache en NGINX

NGINX es un servidor web, existen muchos otros, pero para efectos de este tutorial vamos a centrarnos en NGINX.

Cada sitio web en NGINX se configura como un server.

server {
  server_name www.midominio.com;
  root /var/www/html/midominio;

}

En el ejemplo, hemos definido un “server” para que atienda todas las peticiones a www.midominio.com y que se encuentra alojado en la carpeta /var/www/html/midominio

Ahora dentro de esa definicion basica de “server” vamos a añadir como deben tratar NGINX a los archivos de tipo CSS, por ejemplo.

location ~* \.(?:css)$ {
	  expires 1M;
	  add_header Cache-Control "public";
	}

En este ejemplo indicamos con una expresion regular que cualquier archivo cuyo nombre termine en “.css” se le aplicaran las reglas delimitadas por las { }.

La sentencia expires 1M, nos indica que el contenido de ese archivo se guardara en el navegador durante 1 mes.

La sentencia add_header, nos indica que el cache guardado es de acceso publico para cualquiera que acceda a la pagina desde ese navegador.

Instalar Postgres en Docker

Unos pasos sencillos para instalar en tu computadora local el servidor de base datos postgres, usando Docker. ¿ Porque con Docker ? Porque al usar docker, no importa lo que haga nunca voy a malograr mi sistema principal.

Instalando docker ( Pasos Previos )

En caso no tuvieras instalado docker, en Ubuntu lo puedes hacer ejecutando este comando:

apt install docker-compose

Instalando Postgres

Nuestro primer paso sera crear una carpeta donde residira el proyecto. Esto es asi, porque Docker Compose buscara en la carpeta un archivo YML con las instrucciones para ejecutar y configurar el servicio de postgres.

mkdir postgres

Luego creamos el archivo docker-compose.yml con el siguiente contenido:

version: '2'

services:

  db:
    image: postgres
    user: postgres
    environment:
      POSTGRES_PASSWORD: 
      POSTGRES_USER: postgres

En este archivo ( docker-compose.yml) le estamos indicando que se creara un servicio llamado db, el cual ejecutar la ultima version de postgres.

Para iniciar el servicio lo hacemos con la sentencia: docker-compose up -d

Para detener el servicio: docker-compose stop

Conectarnos a la base de datos

Cuando el servicio db esta activo, es decir despues de haber ejecutado docker-compose up -d podemos conectarnos a la linea de comando de la base de datos usando el comando:

docker-compose exec db psql

Si tienes alguna duda, dejamelo en los comentarios y juntos lo resolveremos. 😀

Como instalar wordpress usando Docker

Si quieres hacer una instalación local de wordpress, te mostrare los pasos a seguir usando docker.

NOTA: La instalación de Docker esta pensada para Ubuntu pero pueden replicarse en windows Mac u otra distribucion Linux.

Instalar Docker

Descubrir docker es algo que te cambia la vida. Finalmente puedes hacer instalaciones de sistemas de forma rapida. Ya no tienes miedo de desconfigurar tu maquina principal. Y puedes hacer cuantas pruebas requieras en la configuracion de los servidores. Sin embargo, aun debes crear las imagenes y lanzar los containers de forma manual. Montar volumenes, configurar las redes internas, etc. Para evitar ese trabajo manual yo recomiendo usar docker-compose.

Docker-compose es una herramienta que intrepreta un archivo de texto docker-compose.yml y ejecuta por ti todos los comandos docker correspondientes.

En este caso, para instalar Docker, Docker-compose y todas sus dependencias necesarias ejecutamos el comando:

sudo apt install docker-compose

Una vez terminado, estamos listos para instalar nuestro wordpress.

Instalar WordPress

Creamos una carpeta donde residira el proyecto:

mkdir proyecto-wordpress

En dicha carpeta creamos un archivo docker-compose.yml:

version: ‘2’
services:
web:
image: wordpress
volumes:
– ./wp-content/:/var/www/html/wp-content/
ports:
– 80: 80
depends_on:
– db
links:
– db : db

db:
image: mysql: 5.7
environment:
– MYSQL_ALLOW_EMPTY_PASSWORD=true
– MYSQL_DATABASE=wordpress
– MYSQL_USER=root

El archivo en cuestion le indica al sistema que se descargue la ultima version de wordpress, que ejecute el servidor en el puerto 80 de nuestro localhost, y que la proyecto-wordpress/wp-content contenga toda la informacion que se sube a wordpress.

Ahora procedemos a ejecutar el servicio de wordpress ejecutando el comando

docker-compose up -d

Al realizar la configuración inicial de wordpress a traves de localhost, debemos tomar en cuenta, que al usar docker el Database Host ya no sera localhost sino db. ( En el archivo docker-compose.yml, en la seccion services => web => links => le pusimos el nombre db al servidor de la base de datos ).

Instalación Finalizada Exitosamente 😉

 

Comandos de Docker-Compose

El servicio de docker no es algo que debe estar permanentemente en memoria. Podemos prenderlo y apagarlo cuando lo necesitemos.

Ejecutar WordPress

docker-compose up -d

Detener WordPress

docker-compose stop

Borrar la instalación

docker-compose down

Revisar los logs

docker-compose logs web