Increíble la ventaja que da trabajar en Docker, me haré el curso de Docker para profundizar en el tema.
Introducción
Persistencia de datos en Node.js
Platzi Store: instalación y presentación del proyecto
Base de datos
Instalación de Docker
Configuración de Postgres en Docker
Explorando Postgres: interfaces gráficas vs. terminal
Integración de node-postgres
Manejando un Pool de conexiones
Variables de ambiente en Node.js
Sequelize
¿Qué es un ORM? Instalación y configuración de Sequelize ORM
Tu primer modelo en Sequelize
Crear, actualizar y eliminar
Cambiando la base de datos a MySQL
Migraciones
¿Qué son las migraciones? Migraciones en Sequelize ORM
Configurando y corriendo migraciones con npm scripts
Modificando una entidad
Relaciones
Relaciones uno a uno
Resolviendo las relaciones uno a uno
Relaciones uno a muchos
Resolviendo relaciones uno a muchos
Consultas
Órdenes de compra
Relaciones muchos a muchos
Resolviendo relaciones muchos a muchos
Paginación
Filtrando precios con operadores
Despliegue
Deploy en Heroku
Consideraciones al hacer migraciones
Próximos pasos
Toma con el Curso de Backend con Node.js: Autenticación con Passport.js y JWT
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Aportes 72
Preguntas 25
Increíble la ventaja que da trabajar en Docker, me haré el curso de Docker para profundizar en el tema.
Para aquellos que les tira error y el docker no es recordar que sequelize necesita las librería
npm i --save mysql2
Saludos
Si a alguno le da error solo tiene que cambiar el puerto en mysql así esto conecta el puerto 33061 de nuestro sistema operativo con el puerto 3306 del contenedor.
Este curso ha sido muy frustrante para mi. El Docker y Sequealize me han dado muchos problemas, no entiendo porqué.
SI a alguien le da algun error al intentar conectarse al contendor de mysql, les dejo la configuración con la que me sirvio, muy similar a la de la clase, con un ligero cambio (:
mysql:
image: mysql:5
environment:
- MYSQL_DATABASE=my_store
- MYSQL_USER=
- MYSQL_ROOT_PASSWORD=admin123
- MYSQL_PORT=3306
ports:
- "3306:3306"
volumes:
- ./mysql_data:/var/lib/mysql
Cuando vayan a ejecutar el servidor si les da error, en la variable de entorno deben colocar el puerto 33061 para que ejecute, ya que el contenedor de docker levanta mysql con el puerto 3306 y externamente el server se levanta con el puerto 33061 como esta en la imagen anterior.
.
✨Definición de variables de entorno.
# mysql and docker
MYSQLDATABASE=thingst
MYSQLUSER=tester
MYSQLPASSWORD=14db7d47-f442-4a90-b633-2a537c8b5c13
♻️ Adición de DB como servicio en Docker:
services:
mysql:
image: mysql
restart: always
ports:
- 3306:3306
environment:
MYSQL_DATABASE: ${MYSQLDATABASE}
MYSQL_ROOT_PASSWORD: ${MYSQLPASSWORD}
MYSQL_USER: ${MYSQLUSER}
MYSQL_PASSWORD: ${MYSQLPASSWORD}
volumes:
- ./db/mysql:/var/lib/mysql
Donde:
MYSQL_DATABASE
. Define la base de datos con la que se trabajará.MYSQL_ROOT_PASSWORD
. Se define la contraseña del usuario root
.MYSQL_USER
. Se define un usuario root
con ámbito definida por MYSQL_DATABASE
MYSQL_PASSWORD
. Se define la contraseña para el usuario MYSQL_USER
..
🔥 Finalmente, levantamos los servicios:
docker compose --env-file src/config/.env up -d
--env-file
se cargan las variables de entorno definidas.-d
se levantan las instancia en modo silencioso.
ℹ️ Para conectarse mediante clientes, el host permitido es mediante default del contenedor 0.0.0.0:3306
Buenas!
Si les aparece en el estado de la máquina de MySQL como “Exit 1”, lo que deben hacer es eliminar, del archivo docker-compose.yml, la siguiente variable:
MYSQL_USER=root
De esta forma iniciará el sistema. (En versiones anteriores permitía agregar esa variable, ahora se toma por defecto como root si no existe).
Para andar evitando re escribir que motor de Base de datos corremos, es mejor añadir que motor es en .env y añadirlo dentro de config.js
.env
DB_ENGINE=mysql
config.js
require('dotenv').config()
const config = {
env: process.env.NODE_ENV || 'dev',
dbHost: 'localhost',
dbPort: process.env.MYSQL_PORT || 3000,
dbUser: process.env.MYSQL_USER,
dbPassword: process.env.MYSQL_PASSWORD,
dbName: process.env.MYSQL_DATABASE,
dbEngine: process.env.DB_ENGINE
}
module.exports = config
Al momento de querer levantar mysql su estado se quedaba en Exit 1.
Para arreglar ese problema dentro de docker-compose.yml en el apartado de volumes lo cambié.
Antes:
./mysql_data:/var/lib/mysql
Después:
"~/mysql_data:/var/lib/mysql"
Ahora al momento de subirlo a docker si está en Up.
Si tiene una MacBook M1 y te muestra el siguiente mensaje al levantar el contener con MySQL:
ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries
Agrega esta línea en el archivo docker-compose.yml:
platform: linux/amd64
Debería quedar así:
mysql:
image: mysql:5
platform: linux/amd64
environment:
- MYSQL_DATABASE=my_store
- MYSQL_USER=menyin
- MYSQL_ROOT_PASSWORD=admin123
- MYSQL_ROOT_PORT=3306
ports:
- 3306:3306
volumes:
- ./mysql_data:/var/lib/mysql
Comando | Descripcion |
---|---|
docker-compose up -d mysql |
Cambiando de DDBB |
docker-compose ps |
Verificar si ya esta corriendo |
docker-compose up -d phpmyadmin |
Levantando phpmyadmin |
npm install --save mysql2 |
Driver para mysql |
npm run dev |
Correr la base de datos |
Me aparecia el estado del servicio de mysql en Exit 1
solo deje el usuario vacio y me funciono
Nico te explica hasta el ; GENIO!!!
que bien que se tomo la molestia de dar otro ejemplo con mysql
Compañeros no olvidar crear la base de datos ‘my_store’ en el gestor de bd phpMyAdmin
Yo tengo instalado MySQL Workbench en mi pc, por lo que me da un error al levantar el servicio de “mysql”.
Sin embargo, hice un pequeño cambio en el puerto para que funcione.
mysql:
image: mysql:5
environment:
- MYSQL_DATABASE=my_store
- MYSQL_USER=root
- MYSQL_ROOT_PASSWORD=admin123
- MYSQL_PORT=3306
ports:
- 3307:3306
volumes:
- ./mysql_data:/var/lib/mysql
al puerto que escucha el servicio lo cambie de 3306 al 3307. Espero les sirva.
Tengan cuidado con los tipos de datos decimales, en postgres funcional el NUMBER(escala,no.Decimal), pero en MYSQL no funciona. Se recomienda usar el tipo NUMERIC()
hola muchachos para los que el handler no les funcionó o no les mostraba en la respuesta la sección de “errors” averigüé un poco y posiblemente se ha actualizado la manera en que se puede tener acceso a ese detalle.
es solo remplazar:
errors: err.errors
por:
errors: err.details
Hola a todos!
Es posible que el puerto este en uso, para ello en el CMD como admin podemos terminar la tarea que lo tiene en uso:
netstat -aon | findstr :3306
taskkill /pid IdTASK /F
Para aquellos que les da el siguiente error: Host ‘X’ is not allowed to connect to this MySQL server, lo solucioné exponiendo el puerto, por otro lado, no es necesario el MYSQL_USER=root dado que mysql lo crea por default.
mysql:
image: mysql:5.7
restart: always
environment:
- MYSQL_DATABASE=my_store
- MYSQL_USER=userX
- MYSQL_PASSWORD=useXPassword
- MYSQL_ROOT_PASSWORD=admin123
ports:
- "3306:3306"
expose:
- "3306"
volumes:
- ./mysql_data:/var/lib/mysql
P.D.: las siguientes líneas se pueden omitir, únicamente las agregué para tener otro usuario MYSQL_USER=userX y MYSQL_PASSWORD=useXPassword
Veo que muchos compañeros tuvieron dificultades, esto es normal cuando empezamos una nueva tecnologia, siempre hay detalles que debemos descubrir nosotros mismos. No se rindan, con paciencia y constancia lo lograra.
Yo soy usuario de WSL2 y asi esta mi codigo docker-compose.yml:
version: "3.8"
services:
postgres:
image: postgres:latest
restart: always
container_name: my_container_db
environment:
POSTGRES_DB: my_store
POSTGRES_USER: maxdn
POSTGRES_PASSWORD: admin123
ports:
- 5432:5432
volumes:
- /postgres_data:/var/lib/postgresql/data
pgadmin:
image: dpage/pgadmin4
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: [email protected]
PGADMIN_DEFAULT_PASSWORD: root
ports:
- 5050:80
mysql:
image: mysql
environment:
MYSQL_DATABASE: my_store
MYSQL_USER: oot
MYSQL_ROOT_PASSWORD: admin123
MYSQL_PORT: 3306
ports:
- 3306:3306
volumes:
- /mysql_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
MYSQL_ROOT_PASSWORD: admin123
PMA_HOST: mysql
ports:
- 8080:80
Cualquier duda comentar, saludos
Si están trabajando con algún mac con procesador M1 es necesario agregar otra llave valor en el servicio de mysql:
platform: linux/x86_64
quedaria de la siguiente forma:
mysql:
platform: linux/x86_64
image: mysql:5
environment:
- MYSQL_DATABASE=my_store
- MYSQL_USER=nico
- MYSQL_ROOT_PASSWORD=admin123
- MYSQL_PORT=3306
ports:
- 3306:3306
volumes:
- ./mysql_data:/var/lib/mysql
Les comparto la configuración que me funciono para conectar con SQL Server.
const { Sequelize } = require('sequelize');
const { config } = require('./../config/config');
const setupModels = require('./../db/models');
const USER = encodeURIComponent(config.dbUser);
const PASSWORD = encodeURIComponent(config.dbPassword);
const URI = `mssql://${USER}:${PASSWORD}@${config.dbHost}:${config.dbPort}/${config.dbName}`;
const sequelize = new Sequelize(URI, {
dialect: 'mssql',
logging: true,
dialectOptions: {
options: {
enableArithAbort: false,
cryptoCredentialsDetails: {
minVersion: 'TLSv1'
}
}
}
});
setupModels(sequelize);
sequelize.sync();
module.exports = sequelize;
Estuvo complicada la clase, no corria ni el contenedor ni la app, para el contenedor, tome la solución de varios comentarios aqui dejando MYSQL_USER= vacío y en el port puse 3307:3306, ya para la app si se quedo ‘root’ en el .env pero cambie el DB_PORT por ‘3302’
Este tema de cambiar la fuente de las bases de datos me ha gustado muchisimo. Gracias profesor @nicobytes
No todos los tipos de de sequelize para postgres son soportados en mysql. Por si a alguien le pasa, mientras en postgres acepta el tipo array: en mysql no, así que tuve que cambiar a J
DataTypes.ARRAY(DataTypes.STRING)
por
DataTypes.JSON
SON.
¡Hola chicos!
Para los que no les funcionan al momento de hacer
docker-compose up -d sql
Si les da error , el nuevo servicio quedaria así (O bueno este me funciono)
services:
mysql:
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_db
ports:
- "3307:3306"
volumes:
- ./mysql_data:/var/lib/mysql
Donde:
MYSQL_ROOT_PASSWORD Este es tu usuario y a la vez tu contraseña
MYSQL_DATABASE El nombre de la base de datos
Despues corren el PHPMYADMIN y funciona normal
Este es la estrategia que me funciono a mí. 💻💻💻
en mi caso deje el middleware asi
static sqlErrorHamdler(err, req, res, next) {
if(err instanceof ValidationError) {
console.log(err)
res
.status(409)
.json({
statusCode: 409,
message: err.errors.message,
details: err.errors
})
}
next(err)
}
Aqui les dejo la doumentacion de sequelize donde pueden ver los diferentes errores que maneja sequelize.
Los que tengas este error:
original: Error: connect ETIMEDOUT
at Connection._handleTimeoutError (/home/alex10/express/my-store/node_modules/mysql2/lib/connection.js:205:17)
at listOnTimeout (node:internal/timers:569:17)
at process.processTimers (node:internal/timers:512:7) {
errorno: ‘ETIMEDOUT’,
code: ‘ETIMEDOUT’,
syscall: ‘connect’,
fatal: true
}
}
Se arregla cambiando la URI en sequilize.js:
const URI = mysql://root:${PASSWORD}@${config.dbHost}:3306/${config.dbName}
con el truco de la “~” al inicio de la ruta de la carpeta de mysql logré tener la persistencia de los datos en el folder del proyecto, sin embargo, me ha sido IMPOSIBLE replicarlo para la carpeta de postgres, he hecho cualquier cantidad de modificaciones, estructuraciones, mengurjes, oraciones y cánticos a todos los dioses y no he podido.
Para No cambiar manualmente el Driver de conexión desde código, cada vez que se cambie de gestor de base de datos:
DB_DRIVER=mysql
dbDriver: process.env.DB_DRIVER,
const URI = `${config.dbDriver}://${USER}:${PASSWORD}@${config.dbHost}:${config.dbPort}/${config.dbName}`;
const sequelize = new Sequelize(URI, {
dialect: config.dbDriver,
logging: true,
});
Así puede cambiar libremente su gestor de base de datos en un entorno de producción sin tener que cambiarlo también en el código.
Me encanta ! ❤️
Es importante que el host de phpmyadmin sea igual al nombre del contenedor de mysql
Tengo este error
"message": "Cannot convert undefined or null to object",
toca tener encuanta si tenemos el port de phpmyadmin si ya lo tenemos local que no este en uso ese puerto 3306.
para aquellos que quieran usar MariaDB deben usar la siguiente versión, si to se optiene un error de meta
"mariadb": "^2.3.3",
Si a alquien le sale este error es porque el archivo docker-compose.yml debe estar correctamente identado!
me salia este error y me di cuenta que no tenia bien tabulado las lineas del código.
“Configuration error - Version in “./docker-compose.yml” is unsupported.
You might be seeing this error because you’re using the wrong Compose file version.
Either specify a supported version (e.g “2.2” or “3.3”) and place your service definitions under the services
key, or omit the version
key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/”
Vaya clase mas fea, estuve haciendo malabares y no pude solucionar los problemas, nose si es porque ya tenia instalado mysql workbench o que, pero fue demasiado frustante
para que todo me funcionara correctamente con el servicio de mysql, coloque el puerto 3307 en mi maquina local y el 3306 en el contenedor
docker-compose.yml:
version: '3.3'
services:
postgres:
...
pgadmin:
...
mysql:
image: mysql:5
environment:
- MYSQL_DATABASE=my-store
- MYSQL_USER=root
- MYSQL_ROOT_PASSWORD=toor
- MYSQL_PORT=3306
ports:
- 3307:3306
volumes:
- ./mysql_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- MYSQL_ROOT_PASSWORD=toor
- PMA_HOST=mysql
ports:
- 8080:80
corremos los servicios
docker-compose up -d mysql
docker-compose up -d phpmyadmin
modificamos puerto en las variables de entorno
.env:
PORT=3000
DB_USER='root'
DB_PASSWORD='toor'
DB_HOST='localhost'
DB_NAME='my-store'
DB_PORT='3307' // puerto en mi maquina local donde corre el contenedor mysql
modificamos lenguaje y string de conexión
libs/sequelize.js:
const { Sequelize } = require('sequelize')
const { config } = require('../config/config')
const setupModels = require('../db/model/index')
const USER = encodeURIComponent(config.dbUser)
const PASSWORD = encodeURIComponent(config.dbPassword)
const URI = `mysql://${USER}:${PASSWORD}@${config.dbHost}:${config.dbPort}/${config.dbName}`
const sequelize = new Sequelize(URI, {
dialect: 'mysql',
logging: true
})
setupModels(sequelize)
sequelize.sync()
module.exports = sequelize
corremos la aplicación
npm run dev
insertamos algunos registros con una petición POST a la url “/api/v1/users/”
{
"email": "[email protected]",
"password": "12345678"
}
{
"email": "[email protected]",
"password": "12345678"
}
luego hacemos una petición GET a la misma url, veremos como respuesta
[
{
"id": 1,
"email": "[email protected]",
"password": "12345678",
"createdAt": "2023-02-28T17:57:02.000Z"
},
{
"id": 2,
"email": "[email protected]",
"password": "12345678",
"createdAt": "2023-02-28T17:57:07.000Z"
}
]
y todo estaría funcionando correctamente con mysql corriendo bien
Perdí mi tiempo nomás con MySQL, no pude hacerlo funcionar, con nada 😦
LIKE A ESTA CLASE
A pesar de los errores jajaja
Hola, también tuve problemas al hacer la conexión con mysql,
Por acá les comparto mi solución.
#docker-compose.yml
mysql:
image: mysql:5
restart: always
environment:
- MYSQL_DATABASE=my_store
- MYSQL_USER=root
- MYSQL_ROOT_PASSWORD=root
- MYSQL_PORT=3306
ports:
- 33060:3306
volumes:
- ~/mysql_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- MYSQL_ROOT_PASSWORD=root
- PMA_HOST=mysql
ports:
- 8080:80
Como tuve que cambiar el puerto en el servicio de mysql, también se tiene que cambiar en el archivo .env para que se pueda realizar una correcta conexión la bd.
#.env
PORT = 3000
DB_USER='root'
DB_PASSWORD='root'
DB_HOST='localhost'
DB_NAME='my_store'
# === DB_PORT FOR MYSQL ===
DB_PORT='33060'
# === DB_PORT FOR POSTGRES ===
# DB_PORT='5432'
Saludos.
Para los que tengan MAC con chip M1 y les sale en la consola: “no matching manifest for linux/arm64/v8 in the manifest list entries”.
👉🏻Aquí la solución:
solo tienen que agregar esto a su archivo YML:
platform: linux/x86_64
image: mysql:5
Esto no les solucionará el problema de raíz pero su los dejará seguir haciendo el curso.
Para los que estén trabajando en MAC con los Chip M1, y les sale el siguiente error al levantar el contenedor de mysql
no matching manifest for linux/arm64/v8 in the manifest list entries
Tienen que agregar la siguiente línea en la definición del servicio:
mysql:
**platform: linux/x86_64**
image: mysql:5
environment:
- MYSQL_DATABASE=my_store
- MYSQL_USER=root
- MYSQL_ROOT_PASSWORD=admin123
- MYSQL_PORT=3306
ports:
- 3306:3306
volumes:
- ./mysql_data:/var/lib/mysql
que genial y que fácil es hacer estas migraciones, me esta gustando muchísimo el curso.
tienen que instalar la herramienta de conexión de sequelize para MySQL
npm install --save mysql2
para los que tengan este error
HostNotFoundError [SequelizeHostNotFoundError]: getaddrinfo ENOTFOUND localhost
lo solucione exponiendo el puerto la instancia de sequelize
const sequelize = new Sequelize(URI, {
dialect: 'mysql',
logging: true,
port: PORT
});
Llevo años usando Linux y para hacer mis cosas lidiaba con dependencias y paquetes, de ahora en adelante; solo lidiaré con Docker
No se si alguien mas se percato de que sucede cuando ingresas un correo ya existente, y es que empieza a asignar ID en blanco (Aunque no aparezcan en la tabla) no se si esto es algo bueno o malo
docker-compose.yml
version: '3.3'
services:
postgres:
image: postgres:13
environment:
- POSTGRES_DB=my_store
- POSTGRES_USER=nico
- POSTGRES_PASSWORD=admin123
ports:
- 5432:5432
# Persitencia bd
volumes:
- ./postgres_data:/var/lib/postgresql/data
# interfaz grafica
pgadmin:
image: dpage/pgadmin4
environment:
- [email protected]
- PGADMIN_DEFAULT_PASSWORD=root
ports:
- 5050:80
mysql:
image: mysql:5
environment:
- MYQSL_DATABASE=my_store
- MYSQL_USER=
- MYSQL_ROOT_PASSWORD=admin123
- MYSQL_PORT=3306
ports:
- 3306:3306
volumes:
- ./mysql_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- MYSQL_ROOT_PASSWORD=admin123
- PMA_HOST=mysql # nombre del servicio mysql
ports:
- 8080:80
Si alguien esta teniendo problemas con la imagen de mysql en docker en una mac con m1, la solución puede ser lo siguiente.
Agregar en el archivo de docker antes de indicar la imagen de mysql.
platform: linux/x86_64
para mac con chip m1 agrgar esto, fue la unica manera de poder usar la imagen de lo contrario tenia un error (no matching manifest…):
mysql:
platform linux/x86_64
image:
mysql:5
increíble clase, ya estoy viendo la importancia de saber utilizar docker
Para aquellos que están usando una MBP M1 y tenga problemas para correr la imagen de MySQL, solo deben agregar la platform: linux/x86_64.
mysql:
platform: linux/x86_64
image: mysql:5
environment:
- MYSQL_DB=my_store
- MYSQL_USER=nico
- MYSQL_ROOT_PASSWORD=admin123
- MYSQL_PORT=3306
ports:
- 3306:3306
volumes:
- ./mysql_data:/var/lib/mysql
Saludos y espero les sea de utilidad!
Si tienen problemas iniciando el contenedor pueden intentar correr el comando docker logs
seguido del id del contenedor para tener más información para poderlo debugear.
Pueden obtener el id del contenedor con el comando docker ps -al
.
para los que salgan error al ejecutar el mysql con docker y no tengan usando el puerto 3306 dabien deben ver los espacios en archivo doker-compose.yml, ya que ami me faltaba darle un tab el mysql al crear su contendedor al inicio del mysql xd
Todo muy claro, gran clase y sobre todo integración con DOCKER.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?