DEV Community

Gabriel Brocco de Oliveira
Gabriel Brocco de Oliveira

Posted on

6 1 1 2 1

Como configurar deploy automático da sua API (GO) + Postgres com Docker via GitHub Actions e SSH

Nesta publicação, vou te mostrar passo a passo como estruturar seu projeto em Go, configurar o deploy automático com GitHub Actions e subir sua API — utilizando Docker. Ao final, você terá tudo rodando em um servidor remoto via SSH e realizando o deploy de forma automatizada.

1. Arquitetura do projeto

O projeto utilizado como exemplo é um CRUD simples de usuários, bancos e contas bancárias. Porém estruturado utilizando o padrão de arquitetura Ports and Adapters, também conhecido como Arquitetura Hexagonal.

.github/
├── workflows/
│   └── deploy.yml
cmd/
├── config/
│   └── database/
│       └── migrations/
└── main.go
internal/
├── core/
│   ├── domain/
│   │   ├── banco.go
│   │   ├── conta.go
│   │   └── usuario.go
│   ├── dto/
│   │   ├── banco.go
│   │   ├── conta.go
│   │   └── usuario.go
│   └── usecase/
│       ├── banco.go
│       ├── conta.go
│       └── usuario.go
├── infra/
│   ├── controller/
│   │   ├── banco.go
│   │   ├── conta.go
│   │   └── usuario.go
│   ├── repository/
│   │   ├── banco.go
│   │   ├── conta.go
│   │   └── usuario.go
│   └── server/
│       └── server.go
pkg/
└── di/
├── banco.go
├── conta.go
└── usuario.go
.env
.env-example
.gitignore
docker-compose.yml
Dockerfile
go.mod
go.sum
README.md
Enter fullscreen mode Exit fullscreen mode

Dockerfile: este arquivo cria a imagem Docker da nossa API escrita em Go. Ele utiliza uma imagem base (Golang + Alpine), instala as dependências do projeto, compila o código-fonte em um executável e define os comandos para iniciar a aplicação automaticamente quando o contêiner for iniciado.

./Dockerfile

FROM golang:1.24.2-alpine

WORKDIR /app

COPY go.mod go.sum ./

RUN go mod download

COPY . .

WORKDIR /app/cmd

RUN go build -o main .

EXPOSE 8080

CMD ["./main"]

Enter fullscreen mode Exit fullscreen mode

docker-compose.yml: Define dois serviços principais que rodam em seus próprios contêineres Docker: api (nossa aplicação Go) e db (o banco de dados PostgreSQL). Ele configura a comunicação entre eles, garante que o banco de dados esteja totalmente operacional antes de iniciar a API, expõe as portas necessárias e gerencia as credenciais e dados de forma eficiente.

./docker-compose.yml

version: '3.8'

services:
  api:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy
    environment:
      - DB_HOST=db
      - DB_PORT=5432
      - DB_USER=postgres
      - DB_PASSWORD=${DB_PASSWORD}
      - DB_NAME=banco
    env_file:
      - .env 

  db:
    image: postgres:16-alpine
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=banco
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    env_file:
      - .env 

volumes:
  postgres_data:

Enter fullscreen mode Exit fullscreen mode

2. Configurando o GitHub Secrets

No repositório do GitHub, clique em Settings > Secrets and variables > Actions > New repository secret.

Adicione uma SECRET para cada variável abaixo:

ENV → Variáveis do seu .env que não serão expostas
SSH_HOST → IP ou domínio do seu servidor
SSH_USER → Usuário SSH no servidor (ex: ubuntu)
SSH_PRIVATE_KEY → Conteúdo da chave privada SSH (sem senha)

3. Workflow GitHub Actions para deploy automático

O workflow a seguir realiza os seguintes passos:

  1. Clona o repositório com o código mais recente da branch master.
  2. Cria o arquivo .env dinamicamente, utilizando as variáveis sensíveis armazenadas nos Secrets do GitHub (como senhas e configurações de banco).
  3. Constrói a imagem Docker da aplicação, passando as variáveis do .env como argumentos de build (--build-arg).
  4. Salva a imagem como um arquivo .tar, o que permite transportá-la para o servidor.
  5. Envia a imagem Docker para o servidor remoto via SCP.
  6. Acessa o servidor via SSH, carrega a imagem Docker, remove o container antigo (caso exista), e sobe um novo container com a versão atualizada da API.

deploy.yml: Automatiza a entrega contínua da nossa API Go. Ele serve para garantir que cada nova versão da aplicação seja automaticamente compilada, empacotada em um contêiner Docker e implantada em nosso servidor, minimizando erros manuais e agilizando o ciclo de desenvolvimento.

.github/workflows/deploy.yml

name: Build and Deploy Go API via SSH

on:
  push:
    branches:
      - master

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout do repositório
        uses: actions/checkout@v3

      - name: Criar o arquivo .env com os valores do secret
        run: |
          echo "${{ secrets.ENV }}" > .env

      - name: Construir a imagem Docker
        run: |
          export $(grep -v '^#' .env | xargs) 

          docker build \
            --build-arg DB_PASSWORD=$DB_PASSWORD \
            --build-arg DB_PORT=$DB_PORT \
            --build-arg DB_SSL_MODE=$DB_SSL_MODE \
            -t go-api-banco:latest .

      - name: Salvar imagem como .tar
        run: docker save -o go-api-banco.tar go-api-banco:latest

      - name: Enviar imagem para o servidor via SCP
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: "go-api-banco.tar"
          target: "~/"

      - name: Fazer deploy da imagem via SSH
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            docker load -i ~/go-api-banco.tar
            docker stop go-api-banco || true
            docker rm go-api-banco || true
            docker run -d --name go-api-banco -p 8080:8080 go-api-banco:latest

Enter fullscreen mode Exit fullscreen mode

4. Configurando o servidor remoto

No seu servidor (exemplo Ubuntu):

  • Instale o Docker
  • Garanta que seu usuário SSH tenha permissão para rodar Docker (geralmente adicionado ao grupo docker)
  • Configure sua chave pública SSH no ~/.ssh/authorized_keys do usuário

5. Testando o Deploy

Após fazer o push para o branch master, o GitHub Actions irá iniciar o processo de deploy.

Para verificar se tudo ocorreu como esperado:

  1. Acesse o GitHub → seu repositório → Actions
  2. Veja se o workflow “Build and Deploy Go API via SSH” foi executado com sucesso
  3. Acesse seu servidor no navegador: http://<IP_DO_SERVIDOR>:8080
  4. Sua API Go estará rodando 🎉

6. O que você ganha com essa automação?

Ao automatizar o processo de deploy, você transforma algo que poderia levar vários minutos (ou até horas) em um fluxo confiável de poucos cliques ou um simples git push.

Essa integração entre GitHub Actions, Docker e seu servidor remoto garante:

  • Segurança: nenhuma senha ou dado sensível é exposto — tudo é gerenciado via GitHub Secrets.
  • Consistência: o mesmo ambiente é reproduzido em cada deploy, reduzindo erros por diferenças de ambiente.
  • Velocidade: o deploy leva apenas alguns minutos e requer zero intervenção manual.
  • Rastreabilidade: cada execução fica registrada nos Actions do GitHub, permitindo rastrear mudanças e reverter se necessário.

Conclusão

Com isso, você tem uma pipeline de deploy automatizada, segura e baseada em tecnologias sólidas como Go, Docker, PostgreSQL e GitHub Actions.

Esse processo elimina deploys manuais, acelera o desenvolvimento e garante que sua API esteja sempre atualizada no servidor.

Top comments (2)

Collapse
 
pbo profile image
Pablo Oliveira

Great article!
When will we have an English version?

Collapse
 
jacksonsantin profile image
Jackson Dhanyel Santin

Great article!
When will we have an English version?