I wanted to use docker for a personal project I set up it's written in go few services. So at the beging my "architecture" was spliting each service in diferent folder each service has it's own main which starts the srvice initialize what it needs opens a specific port for it. So far so good. So I wanted to use docker so when i started reading about it I wanted to introduce dockerfile for each service, but since I used combined go.mod file the docker image could not build.
So my question is how is the right architecture for these kind of stuff, should I introduce new go.mod file for each service, or somehow use combined go.mod which is for the entire project, but somehow split all services to be deployed seperately having their own ports and stuff. I am NEW to docker so I am looking for suggestion how this kind of stuff should be build?
I was looking into video of some guy explaining that every service should have it's own go.mod, but I was looking into some open source projects and it looked to me that they use only one go.mod file and somehow still deploy services as different services.
CodePudding user response:
It depends the way you want to build and deploy it. In my company we use a mono repo with different services inside cmd folder using the same go.mod file.
# Accept the Go version for the image to be set as a build argument.
ARG GO_VERSION=1.19
# First stage: build the executable.
FROM golang:${GO_VERSION}-alpine
# Install the Certificate-Authority certificates for the app to be able to make
# calls to HTTPS endpoints.
# Git is required for fetching the dependencies.
RUN apk add --no-cache bash ca-certificates openssh build-base curl
RUN go env -w GO111MODULE=on && \
go env -w GOFLAGS=-buildvcs=false
# Set the working directory outside $GOPATH to enable the support for modules.
WORKDIR /src
RUN go install github.com/jteeuwen/go-bindata/... && \
go install github.com/cortesi/modd/cmd/modd@latest
Docker compose file:
version: "2.4"
x-build:
&build
build:
context: .
dockerfile: <your-docker-folder>>/Dockerfile
entrypoint: modd
command: -f modd.conf
volumes:
- gopath:/go
- ./:/<your-source-folder>
environment:
<<: *env
networks:
- your-network
services:
fast-api:
<<: *build
container_name: your-service-name
ports:
- "8080:8080"
This project is using https://github.com/cortesi/modd which is a flexible developer tool that runs processes and responds to filesystem changes and you can benefit of having hot reload when developing locally with docker but we are using https://github.com/cosmtrek/air for new projects.
I hope I could have helped you. I'll keep looking this thread and see if you could solve your issue.
Good luck.
CodePudding user response:
You can use single go.mod file and still build diffrent services executables for docker, if services are related more like a single project than a independent releasebale module.
By specifying the main file name instead of . or ./... you will be able to build the execs for the different services
e.g. for service dir as
├── go.mod
├── go.sum
├── m1
│ ├── m1_code.go
│ └── cmd
│ └── m1_main.go
├── m2
├── m2_code.go
└── cmd
└── m2_main.go
Dockerfile for m1 can be as below, similarly for m2.
FROM golang:alpine AS builder
RUN mkdir /app
WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download
ADD . /app
RUN go build -o main_m1 ./m1/cmd/main.go
FROM alpine:latest AS production
COPY --from=builder /app/main_m1 .
ENTRYPOINT [ "./main_m1" ]
Dockerfiles can be in the m1/m2 folders or you can use a common Dockerfile with build-args to specify the main.go path and output file name for the build