El proyecto en si está contenido en un directorio "app". A nivel de raíz agregamos dos archivos:
1- Dockerfile
2- docker-compose.yml
Quedando de la siguiente forma
app/
src/
node_modules/
package.json
package-lock.json
Dockerfile
docker-compose.yml
El Dockerfile son las instrucciones para crear la imágen de Docker.
Es una "plantilla" que especifica como tiene que crearse un contenedor. Nos facilita crear multiples contenedores con su propio entorno.
La instruccion FROM nos dice a partir de que otra imágen se empieza a construir. En este caso node:20 que tendrá sus propias instrucciones para tener preparado un entorno con node.
FROM node:20
WORKDIR /usr/src/app
COPY app/package*.json
RUN npm install
COPY app/ .
EXPOSE 3000
CMD ['npm','start']
Con esto ya podría hacer docker run y jugar con parametros. Por ejemplo;
-p 3000:5000
mapea el puerto 3000 del contenedor al puerto 5000 de tu máquina anfitriona.-v $(pwd)/app:/usr/src/app
crea un volumen que vincula el directorio app
de tu proyecto local (asumiendo que estás en el directorio padre de app
) al directorio /usr/src/app
en el contenedor. Esto significa que los cambios en tu directorio local app
se reflejarán en el contenedor.Pero esto es engorroso de manejar desde la terminal, teniendo que escribir los comandos a mano cada vez que se para el contendor y querramos reiniciarlo.
Para evitar esto podemos dejarlo todo apuntado en un archivo el docker-compose.yml
Los servicios son los contenedores que se quieren poner en marcha. En este caso app es un servicio, pero podría haberse llamado de cualquier forma que querramos applicacion, web, api, etc.
build: Señala donde está el Dockerfile a partir del que hay que crear la imagen para el servicio concreto. ports: Expone los puertos, el 3000 del contenedor al 5000 del anfitrión. En este caso sobreescribe el Dockerfile, pero sigue siendo buena práctica dejarlo en el Dockerfile a modo de autodocumentación. command: Los comandos que hay que ejecutar una vez finalizada la construcción de la imágen. En este caso arrancar el servidor web. Esto también sobrescribe el Dockerfile como el caso anterior y se mantiene en ambos archivos por lo expuesto anteriormente. volumes: Monta el volúmen de Docker. Enlaza el directorio local "app" con el directorio en el contenedor. environment: Define variables de entorno dentro del contenedor.
version:'3'
services:
app:
build: .
ports:
- 3000:5000
volumes:
- ./app:/usr/src/app
environment:
- NODE_ENV=development
command: npm start
Con esto funcionaría. Tan solo nos quedaría ejecutar docker-compose up para iniciar el contenedor y docker-compose down para pararlo.