Como usar o comando docker init para conteinerizar uma aplicação Go

DockerBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá como conteinerizar uma aplicação Go usando o comando docker init. O laboratório começa verificando a instalação correta do Docker Desktop na VM do LabEx, incluindo a verificação da versão do Docker e a execução do container hello-world para garantir que o Docker esteja funcionando como esperado.

Os passos subsequentes envolvem a inicialização de um projeto Go com docker init, a personalização do Dockerfile e do arquivo Compose gerados especificamente para uma aplicação Go e, finalmente, a construção e execução da aplicação Go usando o Docker Compose. Esta experiência prática fornecerá as habilidades para conteinerizar efetivamente aplicações Go usando ferramentas Docker modernas.

Instalar o Docker Desktop e Verificar o Docker Init

Nesta etapa, verificaremos se o Docker está instalado corretamente na VM do LabEx. A VM do LabEx vem pré-instalada com o Docker Engine, então verificaremos a versão do Docker e executaremos um container "hello-world" simples para garantir que tudo esteja funcionando como esperado.

Primeiro, vamos verificar a versão do Docker. Abra um terminal na VM do LabEx. Você pode encontrar o ícone do terminal na área de trabalho ou no menu de aplicativos.

Execute o seguinte comando no terminal:

docker --version

Este comando exibirá a versão do Docker instalada no sistema. Você deve ver uma saída semelhante a:

Docker version 20.10.21, build xxxxxxx

Se você vir a versão do Docker, isso significa que o Docker está instalado corretamente. Se você encontrar um erro, entre em contato com o suporte.

Em seguida, vamos executar o container "hello-world". Este é um container simples que imprime uma mensagem no console e depois sai.

Execute o seguinte comando no terminal:

docker run hello-world

Antes de executar o comando, você precisa baixar a imagem hello-world do Docker Hub. Docker Hub é um registro público para imagens Docker.

Execute o seguinte comando para baixar a imagem:

docker pull hello-world

Este comando baixa a imagem hello-world do Docker Hub para sua máquina local. Você deve ver uma saída semelhante a:

Using default tag: latest
latest: Pulling from library/hello-world
...
Digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest

Agora, execute o comando docker run hello-world novamente:

docker run hello-world

Este comando executará o container hello-world. Você deve ver uma saída semelhante a:

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Esta mensagem indica que o Docker está funcionando corretamente e você executou com sucesso seu primeiro container!

Inicializar um Projeto Go com Docker Init

Nesta etapa, inicializaremos um novo projeto Go e usaremos docker init para gerar os arquivos Dockerfile e docker-compose.yml necessários. Isso fornecerá um ponto de partida para conteinerizar nossa aplicação Go.

Primeiro, vamos criar um novo diretório para nosso projeto Go. Abra um terminal na VM do LabEx e execute os seguintes comandos:

mkdir my-go-app
cd my-go-app

Esses comandos criam um novo diretório chamado my-go-app no diretório ~/project e, em seguida, alteram o diretório atual para my-go-app.

Em seguida, precisamos inicializar um módulo Go. Isso criará um arquivo go.mod que rastreia as dependências do nosso projeto.

Execute o seguinte comando no terminal:

go mod init my-go-app

Este comando inicializa um novo módulo Go chamado my-go-app. Você deve ver uma saída semelhante a:

go: creating new go.mod: module my-go-app
go: to add module requirements and sums:
        go mod tidy

Agora, vamos criar uma aplicação Go simples. Crie um novo arquivo chamado main.go no diretório my-go-app usando o editor nano:

nano main.go

Adicione o seguinte código ao arquivo main.go:

package main

import "fmt"

func main() {
 fmt.Println("Hello, Docker!")
}

Este é um programa Go simples que imprime "Hello, Docker!" no console.

Salve o arquivo e saia do editor nano pressionando Ctrl+X, depois Y e, em seguida, Enter.

Agora, usaremos docker init para gerar os arquivos Dockerfile e docker-compose.yml. No entanto, a VM do LabEx não tem o Docker Compose instalado por padrão. Precisamos instalá-lo primeiro.

Baixe a versão mais recente do Docker Compose usando curl:

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Torne o binário do Docker Compose executável:

sudo chmod +x /usr/local/bin/docker-compose

Verifique a instalação verificando a versão do Docker Compose:

docker-compose --version

Você deve ver uma saída semelhante a:

docker-compose version 1.29.2, build xxxxxxx

Agora que o Docker Compose está instalado, podemos prosseguir com docker init.

Execute o seguinte comando no terminal:

docker init

docker init fará uma série de perguntas para configurar os arquivos Dockerfile e docker-compose.yml. Aqui estão as respostas recomendadas para este laboratório:

  • What do you want to call this application? my-go-app (Qual o nome que você quer dar a esta aplicação?)
  • What port is this app listening on? 3000 (Em qual porta esta aplicação está ouvindo?) (Este é um espaço reservado, na verdade não usaremos uma porta neste exemplo simples)
  • What is the main file to execute? main.go (Qual é o arquivo principal a ser executado?)
  • Would you like to include the Docker Compose configuration? Yes (Você gostaria de incluir a configuração do Docker Compose?)
  • Please choose a Docker Compose version: 2.0 (Por favor, escolha uma versão do Docker Compose:)

Depois de responder a essas perguntas, docker init gerará um arquivo Dockerfile e um arquivo docker-compose.yml no diretório my-go-app.

Você pode visualizar o conteúdo dos arquivos gerados usando o comando cat:

cat Dockerfile
cat docker-compose.yml

Esses arquivos fornecem uma configuração básica para construir e executar nossa aplicação Go em um container Docker. Na próxima etapa, personalizaremos esses arquivos para melhor atender às nossas necessidades.

Personalizar o Dockerfile e o Arquivo Compose Gerados para Go

Nesta etapa, personalizaremos os arquivos Dockerfile e docker-compose.yml gerados na etapa anterior. Otimizaremos o Dockerfile para construir nossa aplicação Go e configuraremos o arquivo docker-compose.yml para executar nossa aplicação.

Primeiro, vamos examinar o Dockerfile gerado. Abra o Dockerfile no diretório my-go-app usando o editor nano:

nano Dockerfile

O Dockerfile gerado pode ter uma aparência semelhante a esta:

## syntax=docker/dockerfile:1

FROM golang:latest AS builder

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .

RUN go build -o my-go-app

FROM alpine:latest

WORKDIR /app

COPY --from=builder /app/my-go-app .

EXPOSE 3000

CMD ["./my-go-app"]

Este Dockerfile usa uma construção de múltiplas etapas (multi-stage build). A primeira etapa (builder) usa a imagem golang:latest para construir a aplicação Go. A segunda etapa usa a imagem alpine:latest para executar a aplicação.

Vamos modificar o Dockerfile para usar uma versão específica do Go e otimizar o processo de construção. Substitua o conteúdo do Dockerfile pelo seguinte:

## syntax=docker/dockerfile:1

FROM golang:1.17 AS builder

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .

RUN go build -o my-go-app

FROM alpine:latest

WORKDIR /app

COPY --from=builder /app/my-go-app .

CMD ["./my-go-app"]

Mudamos a imagem base para a etapa de construção para golang:1.17. Isso garante que estamos usando uma versão específica do Go para construir nossa aplicação.

Salve o arquivo e saia do editor nano.

Agora, vamos examinar o arquivo docker-compose.yml gerado. Abra o arquivo docker-compose.yml no diretório my-go-app usando o editor nano:

nano docker-compose.yml

O arquivo docker-compose.yml gerado pode ter uma aparência semelhante a esta:

version: "3.9"
services:
  my-go-app:
    build: .
    ports:
      - "3000:3000"

Este arquivo docker-compose.yml define um único serviço chamado my-go-app. Ele especifica que o serviço deve ser construído a partir do diretório atual (.) e que a porta 3000 deve ser exposta.

Como nossa aplicação não está realmente ouvindo em uma porta, podemos remover a seção ports. Modifique o arquivo docker-compose.yml para o seguinte:

version: "3.9"
services:
  my-go-app:
    build: .

Salve o arquivo e saia do editor nano.

Nesta etapa, personalizamos os arquivos Dockerfile e docker-compose.yml para melhor atender às nossas necessidades. Na próxima etapa, construiremos e executaremos nossa aplicação Go usando o Docker Compose.

Construir e Executar a Aplicação Go com Docker Compose

Nesta etapa, construiremos e executaremos nossa aplicação Go usando o Docker Compose. O Docker Compose simplifica o processo de construção e execução de aplicações com múltiplos containers. Em nosso caso, temos apenas um container, mas o Docker Compose ainda fornece uma maneira conveniente de gerenciar o processo de construção e execução.

Primeiro, navegue até o diretório my-go-app no terminal:

cd ~/project/my-go-app

Para construir a imagem Docker para nossa aplicação, execute o seguinte comando:

docker-compose build

Este comando construirá a imagem Docker com base no Dockerfile no diretório atual. Você deve ver uma saída semelhante a:

Building my-go-app
Sending build context to Docker daemon  3.072kB
Step 1/6 : FROM golang:1.17 AS builder
 ---> xxxxxxxxxxxxxxxx
Step 2/6 : WORKDIR /app
 ---> Using cache
 ---> xxxxxxxxxxxxxxxx
Step 3/6 : COPY go.mod go.sum ./
 ---> Using cache
 ---> xxxxxxxxxxxxxxxx
Step 4/6 : RUN go mod download && go mod verify
 ---> Using cache
 ---> xxxxxxxxxxxxxxxx
Step 5/6 : COPY . .
 ---> xxxxxxxxxxxxxxxx
Step 6/6 : RUN go build -o my-go-app
 ---> Running in xxxxxxxxxx
Removing intermediate container xxxxxxxxxx
 ---> xxxxxxxxxxxxxxxx
Successfully built xxxxxxxxxxxxxxxx
Successfully tagged my-go-app_my-go-app:latest

Esta saída indica que a imagem Docker foi construída com sucesso.

Agora, para executar a aplicação, execute o seguinte comando:

docker-compose up

Este comando iniciará o container definido no arquivo docker-compose.yml. Você deve ver uma saída semelhante a:

Starting my-go-app_my-go-app_1 ... done
Attaching to my-go-app_my-go-app_1
my-go-app_1  | Hello, Docker!
my-go-app_my-go-app_1 exited with code 0

Esta saída mostra que nossa aplicação Go foi executada e imprimiu "Hello, Docker!" no console. O container então saiu com o código 0, indicando execução bem-sucedida.

Para parar o container, pressione Ctrl+C no terminal.

Você também pode executar o container em modo detached (destacado) adicionando a flag -d ao comando docker-compose up:

docker-compose up -d

Isso iniciará o container em segundo plano. Para visualizar os logs do container, execute o seguinte comando:

docker logs my-go-app_my-go-app_1

Para parar o container em execução no modo detached, execute o seguinte comando:

docker-compose down

Este comando irá parar e remover o container.

Nesta etapa, construímos e executamos com sucesso nossa aplicação Go usando o Docker Compose. Isso demonstra como o Docker Compose pode simplificar o processo de gerenciamento de aplicações conteinerizadas.

Resumo

Neste laboratório, começamos verificando a instalação bem-sucedida do Docker Desktop na VM do LabEx. Isso envolveu a verificação da versão do Docker usando o comando docker --version e a confirmação de sua instalação adequada. Em seguida, prosseguimos para baixar a imagem hello-world do Docker Hub usando docker pull hello-world e, subsequentemente, executamos o container com docker run hello-world para garantir que o Docker estivesse funcionando como esperado, imprimindo uma mensagem de confirmação no console.

Esta etapa inicial estabeleceu um ambiente Docker funcional, preparando o terreno para as etapas subsequentes envolvendo o uso de docker init para conteinerizar uma aplicação Go.