Template rendering
Now most of the web project is the separation of front and back side, we could start with the previous template rendering what is used in the framework of Gin, after the template is a good web page in the back-end process rendering sent directly to the user’s browser, the browser page almost don’t do any operation, is conducive to SEO, web page rendering speed is much faster. Gin needs to specify the path to match the static files when using template rendering, and package all files into it when compiling. I recently made a very simple demo showing a few static pages of a course, using a template rendering. To recap, first create a new TemplateTest folder, create a new main.go file in that folder and type:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main(a) {
r := gin.Default()
r.LoadHTMLGlob("tem/**/*") //** stands for folder, * stands for file, must be specified to the lowest file will not error
r.GET("/index".func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello Earthy Excavator".// We can prove that the framework is normal
})
})
r.GET("/class".func(c *gin.Context) {
class := c.DefaultQuery("class"."1") // Accept the URL argument
c.HTML(http.StatusOK, "class"+class+".html", gin.H{"title": class}) // Concatenate the template file path to pass the render parameters
})
r.Run()
}
Copy the code
Create a folder TMP under TemplateTest, and create a folder HTML under TMP to save the HTML files. Create several NEW HTML files as shown below:
Then execute two commands to initialize the project’s go.mod and download the dependencies:
go mod init TemplateTest
Copy the code
go mod tidy
Copy the code
Run the go run main.go directly from the project root directory and access the index route, then test the access to the class path and the class parameter
Perfectly functioning,r.LoadHTMLGlob("tem/**/*")
This code refers to the template folder, so the return path is directly specified when the file name, without the previous class folder and TEM folder, can still be usedengine.Static("./static", "static")
Register static files to be used directly in HTMLstatic
Specifies the location of the static file.
Many section of the building
Ok, the project has been written, let’s try to package the project using Docker, first do a simple packaging demonstration to see how big the image is, and then see how big the image is using multi-terminal packaging. Create a new Dockerfile in the project root directory and enter the following contents:
Compile and run with this image
FROM golang:alpine
Set the working path
WORKDIR /build
Copy all project files to the root folder of the image
ADD . ./
Set environment variables for the Go language and enable the Go Module mode. Set the package download source to facilitate quick package download
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn
# Download the package inside go.mod
RUN go mod download
# compiler
RUN go build -o gin_docker .
# open port
EXPOSE 8080
# Run the project
ENTRYPOINT ["./gin_docker"]
Copy the code
In the use of docker command to read Dockerfile content generated image
docker build -t gin:v1 .
Copy the code
Try running a container from this image
docker run -itd --name gin -p 8080:8080 gin:v1
Copy the code
Run the test successfully
The downside is that the packaged image is too big, just a few dozen lines of code, a few files and folders, and takes up 400MB of space
When I learned Docker, I learned its multi-section construction, which is a new feature after Docker17.05. I didn’t encounter this before using PHP to package images, but I happened to encounter it in Go, so I just used it. Because Go is a compiled language, it needs to be compiled into binary files before it can run. We can separate the compiled image from the running image. Now LET me change the Dockerfile file and look at the following example, which is very clear and simple:
# #
# ---------- building ----------
# #
# Compile with this image
FROM golang:alpine AS builder
Set the working path
WORKDIR /build
Copy all project files to the root folder of the image
ADD . ./
Set environment variables for the Go language and enable the Go Module mode. Set the package download source to facilitate quick package download
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn
# Download the package inside go.mod
RUN go mod download
# compiler
RUN go build -o gin_docker .
# #
# ---------- run ----------
# #
# Change the mirror image
FROM alpine:latest
Use the same working directory
WORKDIR /build/
Copy the compiled file to the directory where the image is running
COPY --from=builder /build .
# open port
EXPOSE 8080
# Run the project
ENTRYPOINT ["./gin_docker"]
Copy the code
Package V2 image:
docker build -t gin:v2 .
Copy the code
Run the container (delete the previous container, otherwise there will be port conflicts) :
docker run -itd --name gin -p 8080:8080 gin:v2
Copy the code
It works perfectly. Mirror size difference is 20 times
As you can see, many dependency files are required at compile time, and few dependencies are required at run time as binary files. As you can see, using a multi-segment build saves a lot of storage costs and time costs.