Projeto guiado: containerizar a app Rails + Next.js
Junta as trilhas: a API de Pedidos (Rails) e a tela de Tarefas (Next.js) rodando juntas via compose.
Aqui as 3 trilhas se encontram: a API de Pedidos construída na trilha Rails e a tela construída na trilha Frontend sobem juntas, com banco de dados próprio, através de um único docker-compose.yml.
1. Dockerfile de cada app
FROM ruby:3.3-slim
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]FROM node:20-alpine
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
EXPOSE 3000
CMD ["pnpm", "start"]2. Um compose pra orquestrar os três serviços
services:
web:
build: ./web
ports:
- "3000:3000"
environment:
NEXT_PUBLIC_API_URL: http://localhost:3001 # o NAVEGADOR acessa via localhost
depends_on:
- api
api:
build: ./api
ports:
- "3001:3000"
environment:
DATABASE_URL: postgres://postgres:postgres@db:5432/app_production # containers se falam por nome
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Repare a diferença entre as duas variáveis de URL — é o resumo de toda a trilha: DATABASE_URL usa db (nome do serviço, resolvido pela rede interna do compose, lição 6); NEXT_PUBLIC_API_URL usa localhost:3001 porque quem faz essa chamada é o navegador do usuário, que está fora da rede Docker — ele não sabe o que é "api", só enxerga a porta publicada da sua máquina.
docker compose up -d --buildExercício
A tela de Tarefas (Frontend, lição 10) precisa buscar dado da API dentro de um Server Component (roda no servidor Next.js, não no navegador). Nesse caso específico, o fetch deveria usar localhost:3001 ou o nome do serviço api?