AWS Fargate: Criando um servidor Node.js com Express e Docker
Tags: ptbr, docker, node, webdev
Published: 2020-05-15 08:58:36

Meu primeiro projeto com o [Node.js](https://nodejs.org/) - que é uma engine de execução JavaScript assíncrono orientado a eventos, projetado para criar aplicativos de rede escaláveis ​​- estava construindo uma plataforma de negociação on-line em 2013. Desde então, o Node.js. é uma das minhas tecnologias favoritas. Irei mostrar nesse artigo, como utilizar Docker no seu aplicativo Node.js com Express - um framework minimalista, rápido e sem opiniões fortes - para executá-lo no AWS Fargate. O AWS Fargate deixa a execução de contêineres na nuvem muito mais fácil.

> Esse artigo é um trecho do livro [Rapid Docker na AWS](https://cloudonaut.io/rapid-docker-on-aws/?utm_source=eduardorabelo&utm_medium=blog&utm_campaign=ptbr-translation).

Veja abaixo como criar uma imagem do Docker para um aplicativo Node.js.

![](https://cloudonaut.io/images/2019/12/docker-ship.jpg)

## Construindo a imagem do Docker

O `Dockerfile` é baseado na imagem oficial Node.js em Docker: `node:10.16.2-stretch`. Arquivos estáticos (pastas `img` e `css`) são exibidos pelo Express, bem como suas partes dinâmicas. Os seguintes detalhes são necessários para entender o `Dockerfile`:

- `envsubst` - é usado para gerar o arquivo de configuração a partir de variáveis ​​de ambiente
- `npm ci --only=production` - instala as dependências declaradas em `package.json` (utilizando `package-lock.json`, para ser mais preciso)
- O aplicativo Express escuta na porta 8080
- O ponto de entrada do aplicativo Express é `server.js` e pode ser iniciado com `node server.js`

Usaremos um `server.js` simples, um aplicativo mais completo, com certeza contém mais componentes.

No `server.js`:

```js

const express = require('express');

const app = express();
app.use('/css', express.static('css'));
app.use('/img', express.static('img'));

app.get('/health-check', (req, res, next) => {
  res.sendStatus(200);
});

app.listen(8080, '0.0.0.0');
```

> **Personalização:** Provavelmente, sua estrutura de pastas é diferente. Portanto, adapte as seções `COPY` no Dockerfile a seguir às suas necessidades.

No `Dockerfile`:

```dockerfile
FROM node:10.16.2-stretch

WORKDIR /usr/src/app

ENV NODE_ENV production

# Instala o envsubst
RUN apt-get update && apt-get install -y gettext
COPY docker/custom-entrypoint /usr/local/bin/
RUN chmod u+x /usr/local/bin/custom-entrypoint
ENTRYPOINT ["custom-entrypoint"]
RUN mkdir /usr/src/app/config/

# Copia os arquivos de configuração
COPY config/*.tmp /tmp/config/

# Instala as dependências do projeto
COPY package*.json /usr/src/app/
RUN npm ci --only=production

# Copia os arquivos do projeto
COPY css /usr/src/app/css
COPY img /usr/src/app/img
COPY views /usr/src/app/views
COPY server.js /usr/src/app/

# Expõe a porta 8080 e inicia o servidor
EXPOSE 8080
CMD ["node", "server.js"]
```

O ponto de entrada personalizado é usado para gerar o arquivo de configuração a partir de variáveis ​​de ambiente `envsubst`.

Dentro de `custom-entrypoint`:

```bash
#!/bin/bash
set -e

echo "generating configuration files"
FILES=/tmp/config/*
for f in $FILES
do
  c=$(basename $f .tmp)
  echo "... $c"
  envsubst < $f > /usr/src/app/config/${c}
done

echo "starting $@"
exec "$@"
```

Em seguida, você aprenderá como testar seus contêineres e aplicativos localmente.

## Testando localmente
Use o [Docker Compose](https://docs.docker.com/compose/) para executar seu aplicativo localmente. O seguinte arquivo `docker-compose.yml` configura o Docker Compose e inicia dois contêineres: um para Node.js e um banco de dados MySQL.

---

Para continuar lendo, consulte o livro [Rapid Docker na AWS](https://cloudonaut.io/rapid-docker-on-aws/?utm_source=eduardorabelo&utm_medium=blog&utm_campaign=ptbr-translation).

# Créditos

- [How to dockerize your Node.js Express application for AWS Fargate?](https://cloudonaut.io/how-to-dockerize-your-nodejs-express-application-for-aws-fargate/), originalmente escrito por [Michael Wittig](https://twitter.com/hellomichibye).