I have the following tree structure for my application:
application:
ª Dockerfile
ª go.mod
ª README.md
ª
+---cmd
ª +---web
ª main.go
ª
+---pkg
ª +---config
ª ª config.go
ª ª
ª +---handlers
ª ª handlers.go
ª ª
ª +---models
ª ª templatedata.go
ª ª
ª +---render
ª render.go
ª
+---templates
ª base.layout.html
ª coffee.page.html
ª drinks.page.html
ª empty.layout.html
ª home.page.html
ª new.page.html
ª popular.page.html
ª recs.page.html
ª request.page .html
ª response.page .html
ª yelp-select.page.html
ª
+---static
bkg.png
Recommendo.png
response.json
ServingDish.jpg
user.png
my main.go file (in ./cmd/web) relies on the handlers package (./pkg/handlers) which in turn relies on the render package (./pkg/render) to render the static templates which are housed in (./templates). From the root directory (application) I can run:
go build ./cmd/web/main.go
And correctly a binary file is generated in the root application directory which I can then execute and the webserver correctly starts and is accessible via browser. When I migrate to ./cmd/web and then try to build directly:
go build main.go
A binary file is created in ./cmd/web which this binary fails to start the webserver properly as the ./templates relative path does not exist (this result is expected).
Now my question, I’m attempting to put this into a Docker container, how do I employ the build statement that worked correctly above (build the binary in the root folder using the path to main.go), or alternatively, how do I go about building the binary properly so that it can properly reference my templates?
Here is what my dockerfile currently looks like (which builds but does not properly start):
FROM golang:1.22-alpine
# Creates an app directory to hold your app’s source code
WORKDIR /App
# Copies everything from your root directory into /App
COPY . .
# Installs Go dependencies
RUN go mod download
# Builds builds the binary
RUN go build ./cmd/web/main.go
# Tells Docker which network port to listen
EXPOSE 6060
# Specifies the executable command that runs when the container starts
CMD ["/App/main"]
I also have tried the Dockerfile below, which correctly puts the binary in /App, however the server does not start when I run the container. Is there another line I need to add inside of the Dockerfile so that when I run the image the webserver starts?:
FROM golang:1.22-alpine
# Creates an app directory to hold your app’s source code
WORKDIR /App
# Copies everything from your root directory into /App
COPY . .
# Installs Go dependencies
RUN go mod download
# Builds builds the binary
RUN go build ./cmd/web/main.go
# Tells Docker which network port to listen
EXPOSE 6060
# Specifies the executable command that runs when the container starts
CMD ["./main"]