Deployment Guide

This project is designed to be deployed using containers, and it includes a Dockerfile and a compose.yaml file to facilitate this process.

Building the Docker Image

The Dockerfile in the project root is a multi-stage build file that creates a small, optimized production image.

Dockerfile Stages

  1. builder Stage: This stage uses the golang:1.20.7-alpine base image, which contains the full Go toolchain. It copies the source code, installs dependencies, and compiles the application into a single static binary named engine.
  2. distribution Stage: This stage uses the lightweight alpine:latest base image. It copies only the compiled binary from the builder stage. This results in a minimal final image that doesn't contain the source code or Go build tools, making it smaller and more secure.

File: Dockerfile

# Builder
FROM golang:1.20.7-alpine3.17 as builder

RUN apk update && apk upgrade && \
    apk --update add git make bash build-base

WORKDIR /app

COPY . .

RUN make build

# Distribution
FROM alpine:latest

RUN apk update && apk upgrade && \
    apk --update --no-cache add tzdata && \
    mkdir /app 

WORKDIR /app 

EXPOSE 9090

COPY --from=builder /app/engine /app/

CMD /app/engine

Build Command

You can build the Docker image using the provided Makefile command or a standard docker build command.

Using Make:

make image-build
This command will tag the image as go-clean-arch.

Using Docker CLI:

docker build -t go-clean-arch:latest .

Running with Docker Compose

The compose.yaml file is the recommended way to run the application and its database together in a production-like environment.

File: compose.yaml

version: "3.7"
services:
  web:
    image: go-clean-arch
    container_name: article_management_api
    ports:
      - 9090:9090
    depends_on:
      mysql:
        condition: service_healthy
    volumes:
      - ./config.json:/app/config.json

  mysql:
    image: mysql:8.3
    container_name: go_clean_arch_mysql
    command: mysqld --user=root
    volumes:
      - ./article.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - 3306:3306
    environment:
      - MYSQL_DATABASE=article
      - MYSQL_USER=user
      - MYSQL_PASSWORD=password
      - MYSQL_ROOT_PASSWORD=root
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      timeout: 5s
      retries: 10

Services

  • web: This is the Go application service.
    • It uses the go-clean-arch image you built previously.
    • It maps port 9090 of the container to port 9090 on the host machine.
    • depends_on with service_healthy ensures that the web service will only start after the mysql service is ready to accept connections.
    • The volumes section shows how you could mount a configuration file, although this project uses environment variables instead.
  • mysql: This is the database service.
    • It uses the official mysql:8.3 image.
    • It exposes the MySQL port 3306 to the host.
    • It uses a volume to mount article.sql into the container's initialization directory. This script will be executed automatically on the first run, creating the database schema and populating it with data.
    • The environment section configures the database, user, and passwords. These should match the values in your .env file for the application to connect successfully.

Launching the Stack

To launch the entire stack, ensure you have a .env file configured for the Docker environment (the default one works if you keep DATABASE_HOST=localhost). Then run:

docker-compose up

To run in detached mode:

docker-compose up -d