Laboratorio — Entorno de trabajo

Todo el trabajo práctico del curso (ejemplos de clase, laboratorios y el proyecto Chasqui) se hace dentro de un contenedor Docker idéntico para todos, con PostgreSQL 18, el cliente psql y Node.js 26 ya instalados. Así evitamos el “en mi computadora sí funciona”: si las pruebas pasan en el contenedor, pasan en la revisión.

1. Requisitos

Sistema Qué instalar
Linux Docker Engine
Windows 10/11 WSL2 + Docker Desktop con integración WSL. Trabajen dentro del sistema de archivos de WSL (~/), no en C:\.
macOS (Intel o Apple Silicon) Docker Desktop

La imagen es nativa: en una laptop con procesador ARM (Apple Silicon, por ejemplo) corre como ARM, y en una con procesador Intel o AMD corre como x86-64. No hay emulación, así que PostgreSQL corre a velocidad normal.

Si no pueden instalar Docker, vean la sección 7.

2. Levantar el contenedor

Desde la carpeta del repositorio del curso (o la de su proyecto):

./env/run.sh                 # la primera vez construye la imagen (unos minutos)

Al entrar, el servidor PostgreSQL ya está corriendo dentro del contenedor. run.sh monta el directorio actual en /work: los archivos se editan con el editor de siempre en su computadora y se ejecutan en el contenedor. También acepta un comando:

./env/run.sh psql chasqui            # abre psql sobre la base de datos chasqui
./env/run.sh make test               # corre las pruebas del proyecto
./env/run.sh --rebuild               # reconstruye la imagen (si cambió el Dockerfile)

Si su proyecto está en otra carpeta, llamen a run.sh con su ruta desde esa carpeta: /ruta/al/curso/env/run.sh.

Dos terminales, un mismo servidor. Si el contenedor ya está abierto y corren run.sh en otra terminal, se abre una segunda shell en el mismo contenedor, conectada al mismo servidor. Es lo que necesitamos en las semanas 13 y 14 para intercalar dos transacciones. Cuando se cierra la primera terminal, el contenedor se detiene y la segunda también se cierra.

Los datos se quedan. Las bases de datos se guardan en un volumen de Docker llamado bd-pgdata, no dentro del contenedor: al salir y volver a entrar siguen ahí. Para empezar de cero, ./env/run.sh --reset-db borra el volumen (pide confirmación).

La imagen (env/Dockerfile, basada en la imagen oficial de PostgreSQL 18) incluye:

  • PostgreSQL 18: el servidor, psql, pg_dump, createdb, dropdb y las extensiones de contrib que usamos (pageinspect, pg_buffercache, pg_walinspect)
  • Node.js 26 (LTS) con npm, y el driver pg ya instalado: import pg from 'pg' funciona en cualquier carpeta, sin npm install
  • los datos de ejemplo de Chasqui y el comando chasqui-load
  • make, git, curl y los editores de terminal vim y nano

3. Los datos de ejemplo: Chasqui

datasets/chasqui/ tiene la base de datos de una empresa de encomiendas: 29 agencias, 1800 clientes, 120 rutas, unos 6000 viajes y 12 000 envíos entre enero y junio de 2026. Los datos son inventados y se generan con gen.mjs, siempre iguales.

make -C datasets/chasqui         # crea (o vuelve a crear) la base de datos chasqui
make -C datasets/chasqui big     # crea chasqui_big, con 2 millones de envíos (semanas 9-12)
chasqui-load chasqui_lab04       # otra copia, con otro nombre, desde cualquier carpeta

make vuelve a crear la base de datos desde cero: si en un laboratorio borraron o cambiaron datos, así vuelven al estado inicial. chasqui_big tarda alrededor de un minuto y ocupa unos 300 MB.

4. psql: el cliente de PostgreSQL

psql se conecta sin argumentos: dentro del contenedor, las variables PGHOST, PGUSER y PGDATABASE ya apuntan al servidor local, con el usuario postgres.

$ psql chasqui
chasqui=# SELECT name, city FROM agency WHERE region = 'Puno';
chasqui=# \d shipment
Comando Qué hace
\l Lista las bases de datos
\c chasqui Se conecta a otra base de datos
\dt, \dv Lista las tablas o las vistas
\d tabla Columnas, índices y restricciones de una tabla
\i archivo.sql Ejecuta un archivo (la ruta es relativa a donde abrieron psql)
\x Alterna la salida vertical, útil para filas anchas
\timing Muestra el tiempo de cada consulta
\e Abre la última consulta en el editor (vim o nano, según EDITOR)
\?, \h SELECT Ayuda de los comandos de psql y de la sintaxis de SQL
\q Sale

Una consulta termina con ;. Si psql muestra chasqui-# en lugar de chasqui=#, está esperando el resto de la sentencia: falta el ;. Si muestra chasqui=!#, una sentencia falló dentro de una transacción y hay que hacer ROLLBACK;.

5. Pruebas con node --test

Los ejemplos de clase, los laboratorios y el proyecto usan el runner de pruebas que trae Node.js: node --test busca los archivos *.test.mjs y los ejecuta. Un archivo de pruebas es un módulo normal:

import { test, after } from 'node:test';
import assert from 'node:assert/strict';
import pg from 'pg';

const pool = new pg.Pool();
after(() => pool.end());

test('hay 29 agencias', async () => {
  const { rows } = await pool.query('SELECT count(*)::int AS n FROM agency');
  assert.equal(rows[0].n, 29);
});

Cada carpeta de código (code/week-NN/) y cada entrega del proyecto trae un Makefile:

make           # prepara la base de datos que usan los ejemplos o las pruebas
make test      # la vuelve a crear y corre todos los *.test.mjs
make clean     # borra esa base de datos

En el proyecto, make test usa una base de datos aparte, chasqui_test, que se crea de nuevo en cada corrida; así las pruebas no dependen de lo que hayan cambiado a mano en chasqui.

6. Editar el código

Cualquier editor sirve, porque los archivos viven en su computadora. Con VS Code, abran la carpeta del curso o del proyecto y usen la terminal integrada para ./env/run.sh. Para escribir SQL con resaltado y autocompletado, las extensiones de PostgreSQL de VS Code se pueden conectar al servidor del contenedor, pero no hace falta: psql y un archivo .sql alcanzan para todo el curso.

7. Alternativa: PostgreSQL y Node.js locales

Si no pueden usar Docker, instalen PostgreSQL 18 (descargas oficiales) y Node.js 26 (nodejs.org). Comprueben las versiones:

psql --version       # debe decir 18
node --version       # debe decir v26

Luego, en la carpeta del curso:

npm install pg                                   # crea node_modules/ en la carpeta
export PGHOST=localhost PGUSER=postgres          # y PGPASSWORD si su instalación la pide
psql -c "ALTER DATABASE postgres SET timezone TO 'America/Lima'"
make -C datasets/chasqui

chasqui-load solo existe en el contenedor; en su lugar usen make -C /ruta/al/curso/datasets/chasqui DB=chasqui_test. Antes de entregar, corran las pruebas al menos una vez en el contenedor.

8. Solución de problemas

Síntoma Causa probable
Cannot connect to the Docker daemon Docker Desktop no está abierto.
psql: error: connection to server on socket ... failed El servidor no está corriendo (por ejemplo, después de db-crash o db-stop). Arránquenlo con db-start; si no arranca, miren /var/log/postgresql.log.
database "chasqui" does not exist Falta cargar los datos: make -C datasets/chasqui (o chasqui-load).
relation "shipment" does not exist Están conectados a otra base de datos (miren el prompt de psql) o el \i se hizo en la base de datos equivocada.
current transaction is aborted, commands ignored until end of transaction block Una sentencia anterior falló dentro de BEGIN; hagan ROLLBACK;.
Cannot find package 'pg' Están corriendo node fuera del contenedor. Fuera, hace falta npm install pg.
El script de Node.js tarda en terminar o no termina Falta await pool.end() (o await client.end()): las conexiones abiertas mantienen vivo el proceso.
Aviso: el contenedor abierto monta ... Ya hay un contenedor abierto desde otra carpeta; la segunda terminal ve esa carpeta en /work. Cierren el otro o abran ambas desde la misma carpeta.
database "chasqui_test" is being accessed by other users Hay un psql abierto sobre la base de datos de pruebas en otra terminal; ciérrenlo antes de make test.
Archivos cuyo owner es root en su computadora (Linux) Agregar --user "$(id -u):$(id -g)" al docker run de run.sh no basta aquí (el servidor corre como postgres); usen sudo chown -R "$USER" . en su carpeta.
Todo muy lento en Windows El código está en C:\; muévanlo a ~/ dentro de WSL.