# Docker Intro

**Que es un contenedor** ?

* Es la pieza fundamental de docker.
* Es una agrupación de varios procesos. También puede ser un solo proceso.
* Los procesos que se definen para un contenedor, solo pueden vivir en el contexto de ese contenedor.
* Los procesos usarán los recursos que el contenedor defina.
* Los procesos corren de forma nativa en máquinas linux, lo único que se comparte es el kernel. por eso en ambientes productivos se usa linux con docker.
* No son máquinas virtuales.

```bash
docker ps = lista los contenedores
docker ps -a = lista contenedores a detalles
docker ps -aq = lista solo los ID de los contenedores (la q significa quiet, tranquilo o silencioso)
docker inspect id_contenedor = detalles internos del contenedor
docker inspect nombre_contenedor = lo mismo que el anterior
docker inspect -f {{}} nombre_contenedor = filtra una variable especifico del contenedor
docker rm nombre_contenedor = elimina un contenedor
docker rm $(ps -aq) = borra TODOS los contenedores
```

```bash
docker run -it ubuntu —> Com esto le decimos que corra el comando pero que lo haga de forma interactiva con mi terminal. Así el estado del contenedor no será apagado sino prendido.
```

### Ciclo de vida de un contenedor

El contenedor siempre estara corriendo o esperar correr un proceso de lo contrario se apagara&#x20;

Para ejecutar un proceso o un comando en un contenedor existente

```bash
docker exec it nombre_contenedor bash
docker kill nombre_contenedor = mata el proceso completo
docker rm -f nombre_contenedor = forzar la eliminación del contenedor
```

### Exponiendo contenedores al mundo exterior - BIND MOUNTS

Existen tres maneras de hacer permanencia de datos:

* Bind mount
* Volume
* tmpfs mount
* docker run --detach --name server nginx
* -d o --detach —> Si el contenedor que voy a ejecutar tiene un proceso que tiene output y/o pretende correr en modo interactivo, lo va omitir, me va dar el control de la terminal.

Los contenedores están aislados del sistema y a nivel de red, cada contenedor tiene su propia stack de net y sus propios puertos.

**Debemos redirigir los puertos del contenedor a los de la computadora** y lo podemos hacer al utilizar este comando:

```bash
docker run -d --name server -p 8080:80 nginx
```

Enlazando directorio desde afuera

```bash
docker run --name db -d -v /Users/gvilarina/Dev/platzi/mongodata:/data/db mongo
```

### Datos con Docker: Volumes

```bash
docker volume ls [
docker volume prune [ Para poder borrar los volúmenes que no están asociados a ningún contenedor en ejecución
docker volumecreate dbdata [ crea un volumen
docker run -d --name db --mount src=dbdata,dst=/data/db mongo [ asigna el volumen al contenedors\ 
```

### imágenes

Las **imágenes** son un componente fundamental de Docker y sin ellas los contenedores no tendrían sentido. Estas imágenes son fundamentalmente plantillas o templates.\
Algo que debemos tener en cuenta es que las imágenes no van a cambiar, es decir, una vez este realizada no la podremos cambiar.

**Ver imágenes descargadas en el host**\
`docker image ls`

**Descargar imágenes en el host imágenes descargadas en el host**\
docker pull \<nombre de la imagen>\
Ej: `docker pull redis`\
Ej: `docker pull ubuntu:18.04` descargando una version en particular

**Eliminar imágenes descargadas en el host**

`docker image ls` // para obtener el id de la imagen\
REPOSITORY TAG IMAGE ID CREATED SIZE\
ubuntu 18.04 93fd78260bd1 8 days ago 86.2MB

`docker rmi -f 93fd78260bd1`

-f => forzar

Ej: `docker rmi -f 93fd78260bd1`\\

![Contruir una imagen](https://3272067609-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LuF8OYM_uNdUA5G-qRU%2F-MF2vUgvR1hUlIdugSH2%2F-MF2va1XVB4t5LPE__F1%2Fimage.png?alt=media\&token=eb1d7c43-5427-4450-afe8-d08eac6a233a)

**DockerFile** que es la ““receta”” que utiliza Docker para crear imágenes.

\*\*Es importante que el DockerFile siempre empiece con un ““FROM”” sino, no va a funcionar. \*\*

El flujo para construir en Docker siempre es así:\
Dockerfile – \*\*build \*\*–> Imágen – **run** --> Contenedor

ejemplo

```bash
FROM ubuntu

RUN touch /usr/src/hola-platzi
```

Nota:

```bash
--docker push /ubuntu:platzi

docker push jcmrmelgar/ubuntu:platzi

--renombrar un tag de una imagen 
docker tag ubuntu:platzi jcmrmelgar/ubuntu:platzi
```

docker history \<tag contenedor>\
Ej: `docker history ubuntu:platzi`

Herramienta para ver mejor el contenido de las imagenes\
[dive](https://github.com/wagoodman/dive)

### Docker en aplicaciones

```yaml
FROM node:8

COPY [“.", "/usr/src/"]
# [<ubicacion de los archivos a copiar>, <destino donde van a quedar los archivos copiados>]
WORKDIR /usr/src
# es similar al comando cd, WORKDIR <entrar en la siguiente ruta> 
RUN npm install
# RUN ejecuta el comando npm install 
EXPOSE 3000
# le indica al contenedor el puerto por el cual va a salir o exponer el contenedor, es el mismo puerto por donde esta escuchando node
CMD ["node", "index.js"]
# ejecuta el comando node index.js el cual levanta el servidor de express
```

docker build -t platziapp .

docker run --rm -p 3000:3000 anturyapp&#x20;

* **–rm** : esta bandera indica que después de correr el contenedor se borre éste contenedor.

### Docker networking: colaboración entre contenedores

Podemos conectar 2 contenedores de una manera fácil sencilla y rapida. Vamos a ver que con tan solo unos comandos tendremos la colaboración entre contenedore

**Borrar una redes en docker**\
docker network rm \<nombre de la red>\
Ej: `docker network rm platzinet`

**Crear una redes en docker**\
docker network create --attachable \<nombre de la red>\
—attachable es para que otros contenedores se puedan unir a esta red\
Ej: `docker network create --attachable platzinet`

**Ver redes disponibles docker**\
`docker network ls`\
`bridge` red por defecto y se conectan con un keyword `link` esta en desuso, compatibilidad (deprecated)\
`host` simula la red del computador que corre docker (no usar)\
`none` hacer que tenga el network desabilitado

**Ver contenedores en un red**\
docker network inspect \<nombre de la red>\
Ej: `docker network inspect platzinet`\
Detallar la busqueda\
`docker network inspect -f '{{.Containers}}' platzinet`

**Unir un contenedor a la red creada**\
docker network connect \<nombre de la red> \<nombre del contenedor>\
Ej: `docker network connect platzinet db`\
`docker run -d --name app -p 3000:3000 --env MONGO_URL=mongodb://db:27017/test platziapp`

`-env` variable de entorno\
db es el nombre del contenedor sin necesidad de pasar la ip del contenedor para la conexión

### docker-compose: la herramienta todo-en-uno

**Docker compose** es una herramienta que nos permite describir de forma declarativa la arquitectura de nuestra aplicación, utiliza composefile (docker-compose.yml).

crear el archivo `docker-compose.yml`\
`Dockerfile` = describer de manera imperativa (paso a paso) la arquitectura de nuestra aplicación\
`docker-compose.yml` = describir de forma declarativa la arquitectura de nuestra aplicación

```yaml
version: "3"

services:
  app:
    image: platziapp
    environment:
      MONGO_URL: "mongodb://db:27017/test"
    depends_on:
      - db
    ports:
      - "3000:3000"

  db:
    image: mongo
```

docker-compose up para crear el build de la imagen

Detener contenedores en docker-compose\
`docker-compose down`\
Para los contenedores y los borra incluyendo el network

**Entrar a un contenedor montado con docker-compose**\
docker-compose exec \<nombre del servicio> bash\
Ej: `docker-compose exec app bash`

**Ver logs de los contenedores montados con docker-compose**\
`docker-compose logs`\
Para filtrar:\
docker-compose logs \<keyword>\
Ej: `docker-compose logs app`

**Ver el status de docker-compose**\
`docker-compose ps`

**Ejecutar contenedores en segundo plano docker-compose**\
`docker-compose up -d`\
No muestra el output\
-d = —detach Corre en segundo plano

se monta el volumen para apuntar el codgio afuera del contenerdor

```yaml
version: "3"

services:
  app:
    build: .
    environment:
      MONGO_URL: "mongodb://db:27017/test"
    depends_on:
      - db
    ports:
      - "3000-3010:3000"
    volumes:
      - .:/usr/src
      - /usr/src/node_modules

  db:
    image: mongo
```

para escalar los contenedores para que hayan mas para atender las solicitudes se puede usar el comando: se debe de agregar un rango de puertos

```yaml
docker-compose scale [nombre_contenedor]=[cantidad_contenedores]
docker-compose scale app=4
```

Montar un docker sobre docker, usar un conenedor con docker para hablarle a nuestro deamon

```yaml
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock docker
```
