# Docker Compose: build de imagem Nginx e versão do PostgreSQL

> Suba um Nginx com imagem própria (build no Compose) e um PostgreSQL trocando a versão numa linha do YAML. O WordPress entra só como resumo.

- Autor: Henrylle Maia, consultor AWS
- Publicado em: 2026-10-15
- Assuntos: Containers
- URL: https://pages.formacaoaws.com.br/blog/docker-compose-build-nginx-e-versao-postgres/
- Aula de origem: "3 exemplos práticos com docker-compose partindo do zero" (https://www.youtube.com/watch?v=Si3KX2dvWGI)

Ninguém guarda de cabeça a série de `docker run` com nome, imagem e porta. O Docker Compose põe tudo isso num arquivo YAML que sobe e derruba os containers com um comando. Abaixo estão dois exemplos: um Nginx que o Compose constrói a partir de um Dockerfile e um PostgreSQL em que você troca a versão mudando uma linha. No fim, um resumo do terceiro exemplo da aula, o WordPress.

Gravei essa aula em 20 de outubro de 2022, numa live de aquecimento. O arquivo e os comandos são os daquela data (`version: '3.1'` e o comando `docker-compose` com hífen). Antes de copiar, confira a [documentação oficial do Docker Compose](https://docs.docker.com/compose/), porque o formato do arquivo e a forma de chamar o comando mudam com o tempo. Se ainda não sabe o que é uma imagem, comece por [o que é Docker](https://pages.formacaoaws.com.br/blog/o-que-e-docker/).

## Por que usar o Compose

O Compose é um arquivo YAML com uma estrutura específica. Ele padroniza a rotina de subir os containers, e padronizar traz organização. Quando você tem vários containers, o mesmo arquivo cuida de todos.

Ele também resolve a comunicação entre aplicações. Ao subir os serviços do arquivo, o Compose levanta uma rede para eles, e o nome de cada serviço serve para um referenciar o outro. Cada projeto fica isolado, e o nome da pasta vira o prefixo do que ele cria.

## Exemplo 1: Nginx com imagem própria

O ponto de partida é uma pasta `exemplo-nginx` com um `hello/hello.htm` e um Dockerfile de duas linhas:

```dockerfile
FROM nginx
COPY hello /usr/share/nginx/html
```

Ao lado, crie o `docker-compose.yml`:

```yaml
version: '3.1'
services:
  server:
    build: .
    ports:
      - 8080:80
```

![O docker-compose.yaml do exemplo Nginx: serviço server com build apontando para a pasta atual e a porta 8080:80](https://pages.formacaoaws.com.br/blog/assets/posts/docker-compose-build-nginx-e-versao-postgres/compose-nginx.webp)

- **`server`:** o nome do serviço.
- **`build: .`:** em vez de baixar uma imagem pronta, o Compose constrói uma. O ponto diz que o contexto é a pasta atual, e por convenção ele procura um arquivo chamado `Dockerfile` ali. Se o seu tiver outro nome, passe o argumento `dockerfile`.
- **`ports`:** o `-p` do `docker run`, declarado. A porta 80 do container fica na 8080 da máquina.

Na pasta do arquivo, gere a imagem e suba o serviço:

```bash
docker-compose build server
docker-compose up -d
```

O `up` cria a rede (`exemplo-nginx_default`) e o container (`exemplo-nginx_server_1`), ambos com o nome da pasta na frente. O `-d` solta o terminal. Abri `localhost:8080/hello.htm` e apareceu o conteúdo do meu `hello.htm`.

Para mudar a página, o container antigo precisa sair antes de um novo build. Confira com `docker ps` e derrube:

```bash
docker-compose down
```

Troquei o texto do `hello.htm`, rodei de novo `docker-compose build server` e `docker-compose up -d`, e a página mostrou a mensagem nova.

## Exemplo 2: PostgreSQL com a versão que você escolher

Para testar um banco, o caminho comum é instalar na máquina e depois desinstalar. Com o Compose, o banco é um serviço sem `build`, porque a imagem oficial já está no Docker Hub. Na página do PostgreSQL lá tem até um exemplo de Compose para copiar. O meu ficou assim, numa pasta `exemplo-postgres`:

```yaml
version: '3.1'
services:
  database:
    image: postgres:14.5
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=postgres"
    ports:
      - 5434:5432
    volumes:
      - db:/var/lib/postgresql/data
volumes:
  db:
```

![O docker-compose.yaml do exemplo Postgres: serviço database com a imagem postgres:14.5, usuário e senha em environment e a porta 5434:5432](https://pages.formacaoaws.com.br/blog/assets/posts/docker-compose-build-nginx-e-versao-postgres/compose-postgres.webp)

- **`image: postgres:14.5`:** repositório, dois pontos e a versão. Para testar a 13.5 ou a 14 em vez da 12.5, troque só esse número, porque todas as versões estão no Docker Hub.
- **`ports: 5434:5432`:** a 5432 é a porta padrão do PostgreSQL no container, e a 5434 é a da sua máquina.
- **`volumes`:** o banco precisa dos dados de volta quando o container morre e sobe de novo. O volume `db` guarda o que fica em `/var/lib/postgresql/data`.

Suba com `docker-compose up`. Quando o log disser que o banco está pronto para aceitar conexões, conecte por qualquer cliente. No DBeaver usei `localhost`, porta `5434`, usuário e senha `postgres`, e a conexão respondeu PostgreSQL 14.5, a mesma versão do arquivo. Um `Ctrl+C` mata o banco, e `docker-compose up -d` levanta de novo.

Aqui não houve `build`: se a imagem não existe na máquina, o Docker a baixa do Docker Hub. Só precisa de Dockerfile e build se você quiser customizar a imagem.

**Fluxo:** docker-compose.yml (serviços declarados) → build ou image (Dockerfile local ou Docker Hub) → docker-compose up -d (rede e containers) → docker-compose down (derruba tudo)

## WordPress: o terceiro exemplo da aula

O WordPress dá trabalho para instalar na máquina: aplicação web e banco, cada um com sua configuração. A página dele no Docker Hub também traz um arquivo Compose pronto. Copiei, e ele define dois serviços, `wordpress` e o banco MySQL, com variáveis de ambiente e volumes, porque o WordPress guarda arquivos na máquina e o banco guarda os dados.

A diferença para o exemplo anterior está na porta: aqui usei `8081:80`. Subi com `docker-compose up`, abri `localhost:8081`, escolhi português do Brasil, preenchi o título, o usuário e a senha, e entrei na administração. Esse arquivo, linha por linha, está em [Docker Compose na prática](https://pages.formacaoaws.com.br/blog/docker-compose-na-pratica/). E para levar o mesmo modelo a uma instância, veja [WordPress na AWS com Docker](https://pages.formacaoaws.com.br/blog/wordpress-na-aws-com-docker/).

## Derrubar e limpar os volumes

O volume sobrevive ao container. Se você derrubar e subir de novo, a aplicação volta como estava. Para apagar também os dados, acrescente `-v`:

```bash
docker-compose down -v
```

Isso serve para um fluxo de testes automatizado, por exemplo. Em um pipeline de CI/CD, três linhas (`docker-compose up -d`, os testes e `docker-compose down -v`) preparam um banco, rodam a validação e o deixam no estado inicial para o próximo desenvolvedor que submeter uma funcionalidade. Foi uma ideia que citei na aula, não um pipeline que montei.

Para comparar com um projeto de verdade, olhe o Docker Compose e o Dockerfile da aplicação Node com React que usamos em [App Node com React na EC2 com Docker Compose](https://pages.formacaoaws.com.br/blog/app-node-react-na-ec2-com-docker/).

## Checklist

- Crie uma pasta por projeto, com o `docker-compose.yml` dentro.
- Use `build: .` quando tiver Dockerfile e `image:` quando a imagem vier do Docker Hub.
- Declare `ports` e `volumes` no arquivo, em vez de repeti-los no `docker run`.
- Fixe a versão da imagem (`postgres:14.5`) e troque o número para testar outra.
- Suba com `docker-compose up -d` e derrube com `docker-compose down`.
- Para recomeçar do zero, derrube com `docker-compose down -v`.
- Antes de repetir, confira o formato do arquivo na documentação oficial.

Um arquivo por projeto e dois comandos bastam para subir um servidor web, um banco ou um WordPress, e para tirar tudo do ar sem sobrar nada na máquina.
