Home  >  Article  >  Backend Development  >  Hands On Docker For Beginners Golang Dev

Hands On Docker For Beginners Golang Dev

Susan Sarandon
Susan SarandonOriginal
2024-11-04 05:36:29864browse

Table of Content

  1. Overview
  2. Prerequisite
  3. Dockerfile
  4. Docker Compose
    • Nginx
    • Mysql
    • Migrate
    • API
    • Custom
  5. References

Overview

This Article wouldn't explain how Docker works on the hood, instead this Article will explain what the purpose on each code that written on Dockerfile and docker-compose.yml file so we can write our Docker configuration for other project.

Prerequisite

We need some project with Dockerfile and docker-compose for example, here we would use Golang Project named Ecom as example. For using Dockerfile you need to setup Local Database as mentioned on README.


Dockerfile

Dockerfile used to create a container image.(6)

# Build application from source
FROM golang:1.23.0 AS build-stage
    WORKDIR /app

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

    COPY . .

    RUN CGO_ENABLED=0 GOOS=linux go build -o /api ./cmd/main.go
  • FROM golang:1.23.0 AS build-stage this is an Image for our App, it's similar like we download Go engine to our Machine, Docker need specific Image to run our Code.(1)(2)

  • WORKDIR /app this is the working directory we want our Code to be executed at /app.

  • COPY go.mod go.sum ./ this code will copying go.mod and go.sum file from local machine to ./ directory on Docker.

  • RUN go mod download this will executed command go mod download on Docker

  • COPY . . this code will copy all file and folder project from local machine to Docker.

  • RUN CGO_ENABLED=0 GOOS=linux go build -o /api ./cmd/main.go this code will executed command to build Golang app on linux OS to folder /api on Docker.

# Deploy application binary into a lean image
FROM scratch AS build-realease-stage
    WORKDIR /

    COPY --from=build-stage /api /api

    EXPOSE 8080

    ENTRYPOINT [ "/api" ]
  • FROM scratch AS build-realease-stage scratch used to create minimal images containing only just what an application needs.

  • WORKDIR / we will using root / as working directory.

  • COPY --from=build-stage /api /api this will copying directory /api from image build-stage to /api on build-realease-stage image.

  • EXPOSE 8080 this will expose port 8080 so we can access API with port 8080 outside Docker.

  • ENTRYPOINT [ "/api" ] this will set default executable at /api

Let's try our Dockerfile.

sudo docker build .

docker build to build our project into an Image. You can add tags -t project-ecom to easier identify Images you build.(3)

Hands On Docker For Beginners Golang Dev

You can check the Image list with command sudo docker image ls

Hands On Docker For Beginners Golang Dev

# Build application from source
FROM golang:1.23.0 AS build-stage
    WORKDIR /app

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

    COPY . .

    RUN CGO_ENABLED=0 GOOS=linux go build -o /api ./cmd/main.go

Then Run our Docker Image
--rm to remove container when stopped
--network host to connect docker app to localhost machine (4),(5)
--env-file .env to access environment value through .env file
98bc0128576e docker image ID

Hands On Docker For Beginners Golang Dev

Congratulation

You now can testing to Consume API with Postman or other apps.

Hands On Docker For Beginners Golang Dev


Docker Compose

Docker Compose used to make multiple container services and run it inside Docker. In this project docker-compose.yml there are 4 services that we will explain.

Nginx Proxy

# Build application from source
FROM golang:1.23.0 AS build-stage
    WORKDIR /app

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

    COPY . .

    RUN CGO_ENABLED=0 GOOS=linux go build -o /api ./cmd/main.go
  • nginx: this is the service name
  • image: nginxproxy/nginx-proxy:1.6 this is the Image that we will use, similar to FROM at Dockerfile.
  • networks: this is the network inside Docker the service will use.
  • ports: this is to set port for service to use : , 80 is default port for HTTP
  • volumes: this is persistent Volume to store data for this service, : :ro (read-only).
  • environment: this is to use environment variable.(8)

Mysql

# Deploy application binary into a lean image
FROM scratch AS build-realease-stage
    WORKDIR /

    COPY --from=build-stage /api /api

    EXPOSE 8080

    ENTRYPOINT [ "/api" ]
  • db: this is the service name
  • image: mysql:8.0 this service using Image mysql version 8.0
  • networks: this service using custom network named new then the new network using alias-name database
  • healthcheck: this is to check the service operation by running a test, test: mysqladmin ping -h database -u ${DB_USER} --password=${DB_PASSWORD} this testing ping a mysql database.
  • volumes: this is to store persistent data inside volume.
  • ports: this is port the service will use, in this service we use 3308 as local-machine port because port 3306 already used for mysql on our local-machine.
  • environment: this is to using environment variable, in this mysql service we need root password and database name.(7)

Migrate

sudo docker build .
  • migrate-up: this is the service name
  • image: migrate/migrate this service use migrate Image
  • networks: this service using network new same as db service
  • volumes: the migrations data from local ./cmd/migrate/migrations got copied to service directory /migrations
  • command: this is to run a command on this service, ["-path", "/migrations", "-database", "${CONNECT_DB}", "-verbose", "up"] this command similar to migrate -path /migrations -database mysql://root:some-secret-password@tcp(database:3306)/ecom -verbose up. (9)
  • links: this to link service to another service, this migrate service linked to db service
  • depends_on: this to make this service executed after certain condition, db: condition: service_healthy this mean migrate-up service will executed when db service test got result service_healthy.

API

# Build application from source
FROM golang:1.23.0 AS build-stage
    WORKDIR /app

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

    COPY . .

    RUN CGO_ENABLED=0 GOOS=linux go build -o /api ./cmd/main.go
  • api: this is the service name
  • networks: this is network for this service, this service using network new so it can connect to service db, also connect to network default used by service nginx.
  • build: this is to build the service, thi service using Dockerfile.
  • restart: this service will restart whenever the service on-failure
  • volumes: this is persistent data that stored on volume /go/src/api.
  • ports: port for this service.
  • environment: environment value this service needed.
  • links: this service linked to db service because its need to consume mysql database.
  • depends_on: this service will executed on several condition, when migrate-up: already service_completed_successfully, when db test result is service_healthy, and when nginx service_started

Custom

# Deploy application binary into a lean image
FROM scratch AS build-realease-stage
    WORKDIR /

    COPY --from=build-stage /api /api

    EXPOSE 8080

    ENTRYPOINT [ "/api" ]
  • volumes: this created custom volume named db_data:
  • networks: this created custom networks named new

Let's try our Docker Compose

sudo docker build .

This command will create images for each services and run each container.

Hands On Docker For Beginners Golang Dev


sudo docker run --rm --network host --env-file .env 98bc0128576e

You can check the container our docker-compose.yml created.

Hands On Docker For Beginners Golang Dev


  nginx:
    image: nginxproxy/nginx-proxy:1.6
    networks:
      - default
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    environment:
      HTTPS_METHOD: nohttps

You can check volume our docker-compose.yml created.

Hands On Docker For Beginners Golang Dev


  db:
    image: mysql:8.0
    networks:
      new:
        aliases:
          - database
    healthcheck:
      test: mysqladmin ping -h database -u ${DB_USER} --password=${DB_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3308:3306"
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}

You can check images our docker-compose.yml created.

Hands On Docker For Beginners Golang Dev


Congratulation

You can test Consume API from our project based on documentation on README with Postman or other apps.

if you have done you can stop the container with,

  migrate-up:
    image: migrate/migrate
    networks:
      - new
    volumes:
      - ./cmd/migrate/migrations:/migrations
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    command: ["-path", "/migrations", "-database", "${CONNECT_DB}", "-verbose", "up"]
    links:
      - db
    depends_on:
      db:
        condition: service_healthy

Hands On Docker For Beginners Golang Dev

Or if you want to delete all container service inside docker compose you can run,

# Build application from source
FROM golang:1.23.0 AS build-stage
    WORKDIR /app

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

    COPY . .

    RUN CGO_ENABLED=0 GOOS=linux go build -o /api ./cmd/main.go

Hands On Docker For Beginners Golang Dev


References

(1)Dockerfile Reference
(2)Docker Base Image
(3)Docker Build
(4)Docker Network Tutorials
(5)Docker Network Drivers
(6)Writing a Dockerfile
(7)Docker Hub Mysql
(8)Nginx-Proxy Docs
(9)Golang Migrate

The above is the detailed content of Hands On Docker For Beginners Golang Dev. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn