Skip to content
684 changes: 684 additions & 0 deletions docs/Material/Apuntes/apunte_backend.md

Large diffs are not rendered by default.

740 changes: 740 additions & 0 deletions docs/Material/Apuntes/apunte_integracion.md

Large diffs are not rendered by default.

813 changes: 813 additions & 0 deletions docs/Material/Apuntes/apunte_javascript.md

Large diffs are not rendered by default.

475 changes: 475 additions & 0 deletions docs/Material/Apuntes/apunte_rest_api.md

Large diffs are not rendered by default.

605 changes: 605 additions & 0 deletions docs/Material/Apuntes/linux_terminal.md

Large diffs are not rendered by default.

747 changes: 747 additions & 0 deletions docs/Material/Apuntes/regex.md

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions docs/Material/Guias/04_Git.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Guia 4 - Git

> **Nota:** Se recomienda crear un repositorio de prueba para practicar estos ejercicios. De esta manera, pueden experimentar libremente sin riesgo de afectar proyectos reales. Para una experiencia visual e interactiva del manejo de ramas, se recomienda utilizar [Learn Git Branching](https://learngitbranching.js.org/?locale=es_AR).

> **Importante:** Antes de comenzar con los ejercicios de trabajo remoto, asegurarse de tener configurada la SSH Key. En la seccion "Apuntes" hay un tutorial detallado.

### Introductorios

1. Configurar Git en tu computadora estableciendo tu nombre de usuario y tu correo electronico de manera global. Verificar la configuracion con `git config --list`.

2. Crear una carpeta llamada `mi-proyecto`, ingresar a ella e inicializar un repositorio Git. Verificar que se haya creado la carpeta `.git`.

3. Dentro del repositorio creado en el ejercicio anterior, crear un archivo llamado `notas.txt` con algun contenido. Usar `git status` para observar el estado del archivo. Luego, agregarlo al area de staging con `git add` y volver a ejecutar `git status` para ver la diferencia.

4. Realizar un commit del archivo `notas.txt` con un mensaje descriptivo. Luego, ejecutar `git log` para ver el historial de commits y verificar que el commit fue registrado correctamente.

5. Modificar el archivo `notas.txt` agregando una nueva linea de texto. Usar `git diff` para ver las diferencias antes de hacer el commit. Luego, agregar el archivo al staging y realizar un nuevo commit.

6. Crear tres archivos nuevos: `archivo1.txt`, `archivo2.txt` y `archivo3.txt`. Agregar solo `archivo1.txt` y `archivo2.txt` al area de staging. Ejecutar `git status` para confirmar que `archivo3.txt` sigue sin ser rastreado. Realizar el commit unicamente de los dos archivos preparados.

7. Crear un archivo `.gitignore` en el repositorio que ignore todos los archivos con extension `.log` y una carpeta llamada `temp/`. Luego, crear un archivo `errores.log` y una carpeta `temp/` con algun archivo dentro. Verificar con `git status` que Git los esta ignorando correctamente.

8. Ejecutar `git log` con las siguientes variantes y describir que informacion muestra cada una:
- `git log --oneline`
- `git log --oneline --graph`
- `git log --author="tu nombre"`
- `git log -3`

### Ramas y Merge

9. Crear una nueva rama llamada `nueva-funcionalidad` y cambiar a ella. Verificar en que rama te encontras con `git branch`. Luego, crear un archivo llamado `funcionalidad.txt`, hacer un commit y volver a la rama `main`.

10. Desde la rama `main`, fusionar la rama `nueva-funcionalidad` usando `git merge`. Verificar con `git log --oneline --graph` que la fusion se realizo correctamente.

11. Crear una rama llamada `experimento`. Cambiar a ella, crear un archivo `experimento.txt` y hacer un commit. Luego, volver a `main` y eliminar la rama `experimento` sin fusionarla. Investigar que flag del comando `git branch` se necesita para forzar la eliminacion.

12. Simular un merge conflict realizando los siguientes pasos:
- Desde `main`, crear un archivo `datos.txt` con el contenido "Linea original" y hacer un commit.
- Crear una rama llamada `cambio-a` y en ella modificar `datos.txt` reemplazando el contenido por "Cambio desde rama A". Hacer commit.
- Volver a `main` y modificar `datos.txt` reemplazando el contenido por "Cambio desde main". Hacer commit.
- Intentar fusionar `cambio-a` en `main`. Resolver el conflicto manualmente eligiendo que contenido conservar, y luego completar el merge con `git add` y `git commit`.

13. Crear dos ramas a partir de `main`: `feature-login` y `feature-registro`. Realizar al menos un commit en cada rama (en archivos distintos). Luego, fusionar ambas ramas en `main` de forma secuencial. Verificar el historial con `git log --oneline --graph`.

### Trabajo remoto

14. Crear un repositorio nuevo y vacio en GitHub. Luego, en tu repositorio local de prueba, agregar el repositorio remoto con `git remote add origin <url-ssh>` y subir la rama `main` con `git push -u origin main`. Verificar en GitHub que los archivos se subieron correctamente.

15. Clonar un repositorio publico de GitHub (por ejemplo, uno de un companero o cualquier repositorio de practica). Explorar su historial de commits con `git log --oneline` y listar las ramas remotas con `git branch -r`.

16. En el repositorio remoto creado en el ejercicio 14, crear un archivo directamente desde la interfaz web de GitHub. Luego, en tu repositorio local, ejecutar `git fetch` para traer los cambios sin fusionarlos. Observar con `git status` y `git log origin/main` que los cambios estan disponibles. Finalmente, ejecutar `git pull` para integrarlos a tu rama local.

17. Crear una nueva rama local llamada `feature-remota`, realizar al menos un commit en ella, y subirla al repositorio remoto con `git push -u origin feature-remota`. Verificar en GitHub que la rama fue creada correctamente.

### Colaboracion

18. Hacer un **fork** de un repositorio publico en GitHub (puede ser el de un companero). Clonar tu fork a tu computadora, crear una rama, realizar un cambio y hacer un commit. Subir la rama a tu fork y abrir un **Pull Request** hacia el repositorio original desde la interfaz de GitHub. Describir los cambios realizados en el cuerpo del PR.

19. En el repositorio de GitHub del ejercicio 14, crear un **Issue** describiendo una mejora o error ficticio. Asignarle una etiqueta (label) y una descripcion clara. Luego, crear una rama que resuelva ese issue, hacer el cambio correspondiente, subir la rama y abrir un Pull Request que mencione el issue (por ejemplo, "Resuelve #1" en la descripcion).

20. Intercambiar repositorios con un companero. Clonar el repositorio del companero, crear una rama, realizar un cambio y abrir un Pull Request. El companero debe revisar el PR (dejando al menos un comentario con sugerencias o aprobacion) y luego fusionarlo desde GitHub.

### Desafios

21. Realizar el siguiente flujo completo de trabajo colaborativo:
- Crear un repositorio en GitHub con un archivo `README.md` inicial.
- Clonar el repositorio a tu computadora.
- Crear una rama `develop` y dentro de ella crear un archivo `app.txt`.
- Hacer commit y push de `develop`.
- Desde `develop`, crear una rama `feature-header` y modificar `app.txt` agregando una seccion "Header". Hacer commit y push.
- Abrir un Pull Request de `feature-header` hacia `develop` en GitHub y fusionarlo.
- En tu computadora, cambiar a `develop` y ejecutar `git pull` para traer los cambios fusionados.

22. Investigar el comando `git stash`. En tu repositorio de prueba, modificar un archivo sin hacer commit. Luego, guardar los cambios temporalmente con `git stash`, cambiar de rama, volver a la rama original y recuperar los cambios con `git stash pop`. Describir en que situaciones resulta util este comando.

23. Usar el comando `git log` con el flag `--diff-filter` para encontrar en que commit se agrego un archivo determinado. Ademas, usar `git log -p` para ver los cambios exactos introducidos en un commit especifico. Investigar para que sirve `git log --stat`.

24. Crear un repositorio con la siguiente estructura de ramas y commits:
- `main` con un commit inicial.
- `feature-a` (creada desde `main`) con 2 commits.
- `feature-b` (creada desde `main`) con 1 commit que modifique el mismo archivo que `feature-a`.
- Fusionar `feature-a` en `main`.
- Intentar fusionar `feature-b` en `main`, resolver el conflicto resultante y completar el merge.
- Verificar el historial final con `git log --oneline --graph --all`.

25. Investigar y practicar el uso de `git restore` y `git reset`. En un repositorio de prueba, realizar los siguientes pasos:
- Modificar un archivo y usar `git restore <archivo>` para deshacer los cambios antes de hacer staging.
- Modificar un archivo, agregarlo al staging con `git add`, y usar `git restore --staged <archivo>` para sacarlo del staging sin perder los cambios.
- Hacer un commit y luego usar `git reset --soft HEAD~1` para deshacer el commit manteniendo los cambios en staging.
- Explicar la diferencia entre `git reset --soft`, `git reset --mixed` y `git reset --hard`.
98 changes: 98 additions & 0 deletions docs/Material/Guias/05_Docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Guia 5 - Docker

> Para realizar estos ejercicios se necesita tener Docker instalado. Si no se cuenta con una instalacion local, se puede utilizar [Play with Docker](https://labs.play-with-docker.com/) desde el navegador.

### Ejercicios introductorios

1. Descargar la imagen oficial de `nginx` desde Docker Hub utilizando el comando `docker pull`. Verificar que la imagen se haya descargado correctamente listando las imagenes disponibles con `docker images`.

2. Ejecutar un contenedor a partir de la imagen de `nginx` en modo interactivo. Luego, detener el contenedor con `docker stop` y verificar que ya no aparece en la lista de contenedores activos (`docker ps`).

3. Listar todos los contenedores existentes (activos e inactivos) utilizando `docker ps -a`. Luego, eliminar todos los contenedores detenidos con `docker rm`.

4. Ejecutar un contenedor de `ubuntu` en modo interactivo (`-it`) y dentro del contenedor ejecutar el comando `cat /etc/os-release` para verificar la version del sistema operativo. Salir del contenedor con `exit`.

5. Descargar la imagen de `alpine` (una distribucion Linux muy liviana). Comparar el tamaño de la imagen de `alpine` con la de `ubuntu` utilizando `docker images`. Anotar la diferencia de tamaño.

6. Ejecutar un contenedor de `nginx` en segundo plano (modo detached con `-d`) y asignarle el nombre `mi-servidor` utilizando la opcion `--name`. Verificar que esta corriendo con `docker ps`. Luego, ver los logs del contenedor con `docker logs mi-servidor`.

### Imagenes y Contenedores

7. Ejecutar un contenedor de `nginx` mapeando el puerto 8080 del host al puerto 80 del contenedor (`-p 8080:80`). Acceder desde el navegador a `http://localhost:8080` y verificar que se muestra la pagina por defecto de nginx.

8. Ejecutar un contenedor de `postgres` (version 15) configurando las siguientes variables de entorno con la opcion `-e`:
- `POSTGRES_USER=alumno`
- `POSTGRES_PASSWORD=clave123`
- `POSTGRES_DB=universidad`

Verificar que el contenedor se esta ejecutando correctamente.

9. Crear una carpeta en el host llamada `mi-web` con un archivo `index.html` que contenga un mensaje de bienvenida. Ejecutar un contenedor de `nginx` montando esa carpeta como volumen (`-v`) en la ruta `/usr/share/nginx/html` del contenedor. Acceder desde el navegador y verificar que se muestra el contenido personalizado.

10. Ejecutar un contenedor de `mysql` (version 8) con las siguientes configuraciones:
- Nombre del contenedor: `mi-mysql`
- Variable de entorno: `MYSQL_ROOT_PASSWORD=root123`
- Puerto mapeado: `3307:3306`
- Ejecucion en segundo plano

Luego, conectarse al contenedor con `docker exec -it mi-mysql mysql -uroot -p` y crear una base de datos llamada `prueba`.

11. Ejecutar un contenedor de `node` (version 20) en modo interactivo y dentro del contenedor ejecutar `node -e "console.log('Hola desde Docker')"`. Observar la salida por pantalla.

12. Ejecutar un contenedor de `postgres` con un volumen con nombre (named volume) llamado `datos-postgres` montado en `/var/lib/postgresql/data`. Crear una tabla dentro de la base de datos. Luego, detener y eliminar el contenedor. Crear un nuevo contenedor de `postgres` montando el mismo volumen y verificar que la tabla sigue existiendo.

### Dockerfile

13. Crear un archivo `Dockerfile` que parta de la imagen de `node:20-alpine`, copie un archivo `app.js` (que imprima "Hola mundo desde mi contenedor") al directorio de trabajo `/app`, y defina como comando de inicio `node app.js`. Construir la imagen con `docker build` y ejecutar un contenedor a partir de ella.

14. Crear un `Dockerfile` para una aplicacion web estatica que:
- Use `nginx:alpine` como imagen base
- Copie el contenido de una carpeta `sitio/` (con al menos un `index.html`) a `/usr/share/nginx/html`
- Exponga el puerto 80

Construir la imagen con el nombre `mi-sitio` y ejecutar un contenedor mapeando el puerto 8080 al 80.

15. Crear un `Dockerfile` que parta de `python:3.11-slim`, establezca `/app` como directorio de trabajo (`WORKDIR`), copie un archivo `requirements.txt` y ejecute `pip install -r requirements.txt` para instalar las dependencias. Luego, copie el resto del codigo y defina como comando de inicio `python main.py`. El archivo `main.py` debe imprimir "Servidor iniciado" por pantalla.

16. Construir una imagen a partir del Dockerfile del ejercicio anterior y etiquetarla con el nombre `mi-app-python` y la version `1.0` (`docker build -t mi-app-python:1.0 .`). Luego, listar las imagenes y verificar que aparece con el tag correcto.

### Docker Compose

17. Crear un archivo `docker-compose.yml` que defina un unico servicio llamado `web` que utilice la imagen de `nginx` y mapee el puerto `8080:80`. Levantar el servicio con `docker compose up -d` y verificar que funciona accediendo desde el navegador.

18. Crear un archivo `docker-compose.yml` que defina dos servicios:
- `db`: un contenedor de `postgres:15` con las variables de entorno `POSTGRES_USER`, `POSTGRES_PASSWORD` y `POSTGRES_DB`.
- `adminer`: un contenedor de `adminer` con el puerto `8080:8080`.

Levantar ambos servicios y acceder a Adminer desde el navegador para conectarse a la base de datos PostgreSQL. El nombre del servidor debe ser `db` (el nombre del servicio).

19. Crear un archivo `docker-compose.yml` que defina los siguientes servicios:
- `app`: un servicio que se construya a partir de un `Dockerfile` local (utilizar `build: .`), mapee el puerto `3000:3000` y dependa del servicio `db` (`depends_on`).
- `db`: un servicio de `postgres:15` con un volumen persistente.

Incluir una seccion `volumes:` a nivel raiz para definir el volumen con nombre.

20. Crear un archivo `docker-compose.yml` que utilice un archivo `.env` para configurar las variables de entorno. El archivo `.env` debe contener:
- `DB_USER=admin`
- `DB_PASS=secreto`
- `DB_NAME=miapp`

El archivo `docker-compose.yml` debe definir un servicio de `postgres` que use esas variables con la sintaxis `${VARIABLE}`. Levantar el servicio y verificar que la base de datos se creo con los valores definidos en el `.env`.

### Desafios

21. Crear un entorno completo de desarrollo para una aplicacion web con `docker-compose.yml` que incluya:
- Un servicio `frontend` con `nginx` sirviendo archivos estaticos desde una carpeta local.
- Un servicio `backend` construido desde un `Dockerfile` que ejecute una aplicacion en Node.js o Python.
- Un servicio `db` con `postgres` y un volumen persistente para los datos.
- Una red personalizada para que todos los servicios se comuniquen entre si.

22. Escribir un `Dockerfile` multi-stage para una aplicacion Node.js que:
- En la primera etapa (`builder`), parta de `node:20`, copie el codigo, instale las dependencias y ejecute el build.
- En la segunda etapa, parta de `nginx:alpine` y copie los archivos generados en la etapa anterior a la carpeta de nginx.

Construir la imagen y comparar su tamaño con una imagen que no utilice multi-stage.

23. Simular un escenario de base de datos con datos iniciales. Crear un `docker-compose.yml` con un servicio de `postgres` que monte un archivo `init.sql` en la carpeta `/docker-entrypoint-initdb.d/` del contenedor. El archivo `init.sql` debe crear una tabla `alumnos` con columnas `id`, `nombre`, `apellido` y `legajo`, e insertar al menos 3 registros. Verificar que al levantar el contenedor la tabla ya contiene los datos.

24. Dado el siguiente escenario: se tiene una aplicacion web compuesta por un frontend (React o HTML estatico), un backend (Node.js o Python) y una base de datos (PostgreSQL). Escribir todos los archivos necesarios (`Dockerfile`, `docker-compose.yml`, `.env`, codigo fuente minimo) para que con un unico comando (`docker compose up`) se levante toda la infraestructura y la aplicacion sea accesible desde el navegador.
Loading