Docker Compose (NestJS y MongoDB)
- Ejemplo con Nest y MongoDB en una imagen
1. Imagen de nuestra app
Dockerfile
- Cada
fromes construir una nueva imagen, ya sea de Node, MongoDB, Postgres, etc.
Dockerfile
# 1. Imagen solo para las dependencias
FROM node:20.9.0-alpine3.18 AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json ./
RUN npm install --frozen-lockfile
# 2. Imagen builder para compilar la aplicación
FROM node:20.9.0-alpine3.18 AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# 3. Imagen de producción
FROM node:20.9.0-alpine3.18 AS runner
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install --prod
COPY --from=builder /app/dist ./dist
# 4. Iniciar la aplicación
CMD [ "node","dist/main" ]
Con comentarios
Dockerfile
# 1. Imagen solo para las dependencias
# (Si el nuevo build no tiene cambios en las dependencias, no se instalan de nuevo)
# (Si hay nuevas dependencias, se instalan)
FROM node:20.9.0-alpine3.18 AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json ./
RUN npm install --frozen-lockfile
# 2. Imagen builder para compilar la aplicación
# Copia de las deps a la imagen de producción
FROM node:20.9.0-alpine3.18 AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
# Copiar de la carpeta actual a la carpeta de la aplicación
COPY . .
# Compilar la aplicación
RUN npm run build
# 3. Imagen de producción
# Copiar de la imagen de builder a la imagen de producción
FROM node:20.9.0-alpine3.18 AS runner
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install --prod
# Copiar de la imagen de builder a la imagen de producción
COPY --from=builder /app/dist ./dist
# # Copiar el directorio y su contenido
# RUN mkdir -p ./pokedex
# COPY --from=builder ./app/dist/ ./app
# COPY ./.env ./app/.env
# # Dar permiso para ejecutar la applicación
# RUN adduser --disabled-password pokeuser
# RUN chown -R pokeuser:pokeuser ./pokedex
# USER pokeuser
# EXPOSE 3000
# 4. Iniciar la aplicación
CMD [ "node","dist/main" ]
.dockerignore
.dockerignore
dist/
node_modules/
.gitignore
.git/
2. docker-compose.yaml
- El archivo que une o construye varias imagenes
- Se pueden crear variables, como prod y dev.
docker-compose.prod.yaml
version: '3'
# Servicios o contenedores que se van a ejecutar
services:
# 1. Servicio de la aplicación
pokedexapp:
# Depende de otras imagenes
depends_on:
- db
# Construir nuestra imagen con la app
build:
context: .
dockerfile: Dockerfile
image: pokedex-docker
container_name: pokedexapp
restart: always
ports:
- "${PORT}:${PORT}"
# Variables de entorno
environment:
MONGO_DB: ${MONGO_DB}
PORT: ${PORT}
DEFAULT_LIMIT: ${DEFAULT_LIMIT}
# 2. Servicio de base de datos
db:
image: mongo:5.0.0
container_name: mongo-poke
restart: always
ports:
- 27017:27017
environment:
MONGODB_DATABASE: nest-pokemon
volumes:
- ./mongo:/data/db
Con comentarios
docker-compose.prod.yaml
version: '3'
# Servicios o contenedores que se van a ejecutar
services:
# 1. Servicio de la aplicación
pokedexapp:
# depende de otro servicio
depends_on:
- db
# Construir nuestra imagen
build:
# Buscar el archivo Dockerfile en el directorio
context: .
dockerfile: Dockerfile
# Nombre de la imagen
image: pokedex-docker
# Nombre del contenedor
container_name: pokedexapp
restart: always # reiniciar el contenedor si se detiene
ports:
- "${PORT}:${PORT}"
# working_dir: /var/www/pokedex
# Variables de entorno para la aplicación
environment:
MONGO_DB: ${MONGO_DB}
PORT: ${PORT}
DEFAULT_LIMIT: ${DEFAULT_LIMIT}
# Opcional, para persistir los datos de la aplicación
# volumes:
# - ./:/var/www/pokedex
# 2. Servicio de base de datos
db:
image: mongo:5.0.0
container_name: mongo-poke
restart: always # reiniciar el contenedor si se detiene
ports:
- 27017:27017
environment:
MONGODB_DATABASE: nest-pokemon
# Opcional, para persistir los datos de la base de datos
# volumes:
# - ./mongo:/data/db
3. Variables de entorno
.env
PORT=3000
DEFAULT_LIMIT=10
# Debido a utilizar docker entonces no usamos IP, sino el nombre del contenedor
# Utiliza el nombre definido en el docker-compose.yml
# db:
# container_name: mongo-poke
MONGO_DB=mongodb://mongo-poke:27017/nest-pokemon
4. Ejecutar
Ejecutar archivo
docker compose up -d
# -d para cerrar la terminal sin detener los servicios
Build
Cada vez que se hace un cambio en el proyecto, nuevo módulo, funcionalidad, etc.
docker-compose -f docker-compose.prod.yaml --env-file .env.prod up --build -d
info
Por defecto, docker-compose usa el archivo .env, por lo que si tienen el archivo .env y lo configuran con sus variables de entorno de producción, bastaría con
docker-compose -f docker-compose.prod.yaml up --build -d
Run
docker-compose -f docker-compose.prod.yaml --env-file .env.prod up -d
info
Por defecto, docker-compose
- Usa el archivo docker-compose.yaml, entoneces si no tenemos otro, como
prodno seria necesario - Usa el archivo
.env, por lo que si tienen el archivo .env y lo configuran con sus variables de entorno de producción
docker-compose up -d