Desplegar Vue app + AWS ECS 
Tags: aws, vue, docker
Published: 2020-03-26 05:08:34

---
title: Desplegar Vue app + AWS ECS 
published: true
description: En este post, se va a describir como desplegar en [AWS](https://www.aws.com) una aplicación realizada con [Vue](https://vuejs.org).
tags: aws, vue, docker
---

Este post surgió debido a las ganas de aprender nuevas tecnologías y herramientas pues durante 5 años he utilizado mayormente [Angular](https://angular.io) y mi opción estándar para despliegue de aplicaciones en la nube siempre ha sido [Google Cloud](https://cloud.google.com/). En esta ocasión me propuse adentrarme un poco en AWS, especificamente [Elastic Container Service o _(ECS)_](https://aws.amazon.com/es/ecs/) y pues de ello salió este tutorial, espero les guste.:sparkles:

A continuación encontrarán vínculos a las páginas de instalación y/o configuración de las distintas herramientas

  - [**Vue**](https://vuejs.org/v2/guide/installation.html)
  - [**Vue CLI**](https://cli.vuejs.org/guide/installation.html)
  - [**AWS**](https://aws.com)
  - [**Docker Engine - Community**]
(https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-engine---community)
- [DockerHub](https://hub.docker.com/)

> Se espera que ya esté instalado y configurado lo anterior. En caso de AWS dar de alta su tarjeta para que les permita utilizar ECS. 

Una vez ya instalado lo anterior _(docker, vue, vue cli)_ comenzaremos :rocket:


# Vue 
Para la parte de Vue, generamos un proyecto de Vue mediante la cli denominado 
_hello-world-vue_ escribiendo en la consola dentro de la carpeta deseada:

`vue create hello-world-vue`

que nos desplegará la siguiente ventana:

![Vue Project Init](https://dev-to-uploads.s3.amazonaws.com/i/h913jmt3rwnmmybu0dwy.png)

donde seleccionaremos la opción **Default _(babel, eslint)_** dependiendo de preferencias. En mi caso, la opción **Manually select features**
pues requiero:

- [Typescript](https://www.typescriptlang.org/)
- Linter / Formatter
- [Babel](https://babeljs.io/)

> Para más información de opciones sobre la creación de un proyecto  [click aquí](https://cli.vuejs.org/guide/creating-a-project.html)

después del habilitado de features _y/o haber seleccionado Default_ en la siguiente ventana nos preguntan **Use class-style component syntax?(Y/n)** la cual para fines prácticos tecleamos *n*  


![class-style components](https://dev-to-uploads.s3.amazonaws.com/i/p8ixnoaddgnq93vay9i1.png)

arrojándonos una ventana como la siguiente en la cual tecleamos *y*

![Babel alongside Typescript](https://dev-to-uploads.s3.amazonaws.com/i/yu0ifqi799vxfiixhob6.png)

posterior, nos pregunta la configuración del _linter/formatter_ lo cual seleccionamos **ESLint with error prevention only** como a continuación

![Linter / Formatter config](https://dev-to-uploads.s3.amazonaws.com/i/6tu88eqta2uwjcmdynsy.png)

seguido nos pregunta sobre la configuración del linter
![Lint on save](https://dev-to-uploads.s3.amazonaws.com/i/cmkcr7h29nyixhk7mr6e.png)

seleccionando **Lint on save** y continuamos a seleccionar dónde nos gustaría guardar la configuración por lo que seleccionamos **In dedicated config files** como a continuación:

![Config files selection](https://dev-to-uploads.s3.amazonaws.com/i/k7a0l3w93z7butelp1vq.png)

y por último nos pregunta si queremos guardar la configuración para futuros proyectos. En mi caso teclee *n*

![Preset for projects](https://dev-to-uploads.s3.amazonaws.com/i/tlxenwvcpl7gwmp4fbep.png)

> Nota: toda la selección anterior de configuración la hice de acuerdo a mis necesidades, en caso de necesitar alguna distinta sí puede utilizarse.

Una vez finalizada la configuración, procedemos a agregar un archivo `Dockerfile` en la raíz del proyecto. Este archivo sirve como punto de inicio para que Docker genere una imagen de nuestro proyecto a desplegar. [_conocer más sobre Dockerfile_](https://docs.docker.com/engine/reference/builder/)

El contenido del archivo es el siguiente:

```Docker
# Getting alpine version of node   
FROM node:lts-alpine
# Installing https://www.npmjs.com/package/http-server
RUN npm install -g http-server
# Creating app/
WORKDIR /app
# Copying compiled files
COPY dist/ .
# Exposing port 8080
EXPOSE 8080
CMD ["http-server" ]

```
> Nota: este dockerfile funciona una vez hecho el [building](https://cli.vuejs.org/guide/build-targets.html#app) de la aplicación pues busca la carpeta `dist/`

Ya teniendo el archivo Dockerfile guardado, procedemos a generar el build del proyecto escribiendo en nuestra terminal:

```javascript
npm run build
``` 

dicho comando lo que realmente va a ejecutar será 

```javascript
vue-cli-service build
```

generando pues, la carpeta `/dist` en la raíz del proyecto.


# Docker

procedemos ahora a la creación de la imagen de Docker, para ello, previamente necesitaremos una cuenta en [DockerHub](https://hub.docker.com/) pues haremos login a ella mediante la consola introduciendo el comando `docker login` para ingresar después nuestras credenciales.

Posterior haremos el build de la imagen con el comando

`docker build . -t <username>/hello-world-vue`

> **username** corresponde al generado en DockerHub. Para conocer más sobre el comando build [click aquí](https://docs.docker.com/engine/reference/commandline/build/).

y si exitosamente hacemos el build obtendremos algo similar:

```bash
Sending build context to Docker daemon  180.5MB
Step 1/6 : FROM node:lts-alpine
 ---> 927d03058714
Step 2/6 : RUN npm install -g http-server
 ---> Using cache
 ---> 074475e54368
Step 3/6 : WORKDIR /app
 ---> Using cache
 ---> 8c6551a57c4e
Step 4/6 : COPY dist/ .
f ---> 8898c0140bc9
Step 5/6 : EXPOSE 8080
 ---> Running in 5376aa103b41
Removing intermediate container 5376aa103b41
 ---> 41282d6c5a48
Step 6/6 : CMD ["http-server" ]
 ---> Running in 4981b6a63db7
Removing intermediate container 4981b6a63db7
 ---> e4fb5aefd78c
Successfully built e4fb5aefd78c
Successfully tagged luisejrobles/hello-world-vue
```

para subirlo a DockerHub procedemos a ejecutar el comando

`docker push <username>/hello-world-vue`

> Para conocer más del comando Push [click aquí](https://docs.docker.com/engine/reference/commandline/push/).

Si todo sale bien en nuestra cuenta de [Docker Hub](https://hub.docker.com/) tendremos dicha imagen. :checkered_flag:


# AWS ECS

Para la parte final, nos encargaremos de desplegar la imagen subida en Docker Hub a [Elastic Container Service](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html) :100:

Con ello, procedemos a ingresar a nuestra consola de amazon con nuestra cuenta mediante [console.aws.amazon.com](https://console.aws.amazon.com). Una vez dentro, en la sección de *Containers* seleccionamos **Elastic Container Service** en la cual obtendremos una ventana como la siguiente

![ECS Welcome page](https://dev-to-uploads.s3.amazonaws.com/i/5t8suejfj0hghtwsoxu6.png)

dando así **Get started** desplegándonos una imagen como a continuación

![ECS Config](https://dev-to-uploads.s3.amazonaws.com/i/te228kmvfub64rcyhgdn.png)

en la cual en la sección *Container definition* damos click en **Configure** en el recuadro de **Custom** lo que nos desplega

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hshf0v2kvgg583s5w8no.png)

lo cual llenamos de la siguiente manera:

**Container image:** hello-world-app
**Image:** docker.io/<username>/hello-world-vue
- **Memory limit:** 
  - *Soft:* 300
  - *Hard:* 400

**Port mappings:** 8080

> Nota: username se refiere al de Docker Hub 

Recordando pues, nuestra imagen de docker está configurada para exponer el puerto 8080 _(mediante EXPOSE 8080)_de nuestra aplicación y es por ello que en **Port mapping** seleccionamos dicho puerto quedando la configuración similar a

![Container config](https://dev-to-uploads.s3.amazonaws.com/i/3ah7fi5xrgnu6epofkif.png)


Procedemos a seleccionar *Update* lo cual nos regresa a la pantalla principal para poder seleccionar *Next* desplegando

![Task definition](https://dev-to-uploads.s3.amazonaws.com/i/0q7l7785l9jgltue0xch.png)

Damos click en *Next* la cual nos arroja

![Cluster config](https://dev-to-uploads.s3.amazonaws.com/i/jecs5bei9jf1jc670y10.png)

En la cual en **Cluster definition** procedemos a poner `hello-world-vue` y damos *Next*. Lo anterior, nos despliega la información de nuestra aplicación a ser desplegada como a continuación

 ![Config review](https://dev-to-uploads.s3.amazonaws.com/i/vhdovfq1wajnazfn2cqa.png)

y procedemos a darle *Create* para esperar unos minutos a que AWS despliegue nuestra aplicación. Una vez aprovisionado todo el servicio nos mostrará

![ECS ready](https://dev-to-uploads.s3.amazonaws.com/i/rpror6ygwipjsdhslb6i.png)

Dando pues click en *View service*

Después en **Tasks**, seleccionamos el task generado _(es alfanumérico)_ y dentro de ahí en la sección de **Network** agarramos el **Public IP** y lo pegamos en nuestro navegador añadiéndole al final *:8080*
desplegando así en el navegador nuestra app :sparkles:

![Vue app](https://dev-to-uploads.s3.amazonaws.com/i/728uv3rrrvegwsrl8etg.png)


Con ello, hemos finalizado el despliegue de nuestra app que resultó ser bastante sencillo. Cabe mencionar que **ECS** utiliza [*Fargate*](https://aws.amazon.com/es/fargate/) por detrás por si quieren leer más sobre ello.

Les dejo a continuación los recursos consultados:

- [Documentación AWS ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html)
- [Documentación Vue CLI](https://cli.vuejs.org/guide/)