kike
kike

Reputation: 738

Why my docker file does not copy the HTML files?

My directory is:

-Dockerfile
app/
    -main.go
media/
    /css
    /html
    /img
    /svg

Inside the html folder, I have subfolders to organise my HTML files, so the path to the HTML files is media/html/*/*.html

And I have my Dockerfile as follows:

FROM golang:alpine

# Set necessary environmet variables needed for our image
ENV GO111MODULE=on \
    CGO_ENABLED=0 \
    GOOS=linux \
    GOARCH=amd64

# Copy the code into the container
COPY media .

# Move to working directory /build
WORKDIR /build

# Copy the code from /app to the build folder into the container
COPY app .

# Configure the build (go.mod and go.sum are already copied with prior step)
RUN go mod download

# Build the application
RUN go build -o main .

WORKDIR /app

# Copy binary from build to main folder
RUN cp /build/main .

# Export necessary port
EXPOSE 8080

# Command to run when starting the container
CMD ["/app/main"]

and my main.go is:

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    // We create the instance for Gin
    r := gin.Default()

    // Path to the static files. /static is rendered in the HTML and /media is the link to the path to the  images, svg, css.. the static files
    r.StaticFS("/static", http.Dir("../media"))

    // Path to the HTML templates. * is a wildcard
    r.LoadHTMLGlob("../media/html/*/*.html")

    r.NoRoute(renderHome)
    // This get executed when the users gets into our website in the home domain ("/")
    r.GET("/", renderHome)
    r.Run(":8080")
}

func renderHome(c *gin.Context) {
    c.HTML(http.StatusOK, "my-html.html", gin.H{})
}

Problem is, I can run without problem my app in Golang with go run main.go, I can build the Docker image without problems, but on the moment to run a Docker container from the image, I got the error: panic: html/template: pattern matches no files: ../media/html/*/*.html

The path is correct (since is also proven because I can run it in plain go) and it seems that Docker is not coping the files correctly, or at least not in the right directory. What is failing? The full simple project can be found here

Upvotes: 1

Views: 1893

Answers (1)

rustyx
rustyx

Reputation: 85452

media is a bad choice for a Docker folder, because a typical Linux container already has a /media folder.

But that's not the root cause.

The root cause is that COPY media . copies the contents of media folder to /. You probably want COPY media/ /media/ if you want to preserve the media folder itself (or use WORKDIR /media).

As a debug tool, you can run your container with a shell as entrypoint to "look around" it without starting your app:

docker build . -t test
docker run -it --rm test sh
/app # ls /media
cdrom   floppy  usb                                                                                                                                             
/app # ls -R /html
/html:
website

/html/website:
my-html.html

As you can see your media/html folder is located at /html.

Some more notes:

It's a good idea to move go mod download to before COPY app so that the downloaded modules can be cached:

FROM golang:alpine

WORKDIR /build
COPY app/go.mod app/go.sum ./
RUN go mod download

COPY app .
RUN go build -o main .

WORKDIR /app
RUN cp /build/main .

COPY media /media/

EXPOSE 8080

CMD ["/app/main"]

As a next step you can look into two-stage builds to not depend on the golang image for running the compiled app (is only needed for building really).

Upvotes: 4

Related Questions