開始
先放上這次 Hello World! 的“架構圖”(純屬搞笑)
技術棧
- 前端:vue
- 後端:gin
- http服務器:caddy
- docker
除了 vue,剩下的基本上算是 golang 全家桶了。
後端項目
mkdir hello
cd hello
go mod init hello
go get -u github.com/gin-gonic/gin
go get -u github.com/gin-contrib/cors
main.go
package main
import (
"net/http"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.Use(cors.Default()) // 前後端分離需要的跨域中間件
r.GET("/api/hello", func(c *gin.Context) {
c.String(http.StatusOK, "Hello World!")
})
r.Run()
}
Dockerfile
# 可以用 golang 鏡像編譯,也可以直接編譯
FROM golang as builder
WORKDIR /go/src/hello
ADD . .
# 設置 go 代理
ENV GOPROXY https://goproxy.cn
RUN CGO_ENABLED=0 go build
# 把二進制可執行文件放到 alpine 跑起來
FROM alpine
COPY --from=builder /go/src/hello/hello /usr/bin
ENTRYPOINT [ "hello" ]
製作鏡像,運行容器
docker build -t gin-hello .
docker run --rm -d -p 8080:8080 gin-hello
測試確認接口正常運行
前端項目
vue create hello
cd hello
yarn add axios
App.vue
從後端 api 獲取返回內容並顯示。
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld :msg="msg" />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
import axios from "axios";
export default {
name: "App",
components: {
HelloWorld
},
data() {
return {
msg: ""
};
},
mounted() {
axios
.get("/api/hello")
.then(res => {
this.msg = res.data;
})
.catch(() => {
this.msg = "Error!";
});
}
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
yarn build
Caddyfile
:80
root * /var/www/html
reverse_proxy /api/* 192.168.0.105:8080
file_server
監聽 80 端口,提供靜態文件服務,/api/
開頭的請求配置反向代理(192.168.0.105
是本機ip)
Dockerfile
FROM caddy:alpine
COPY Caddyfile /etc/caddy/Caddyfile
COPY dist /var/www/html
製作鏡像,運行容器
docker build -t vue-hello .
docker run --rm -d -p 80:80 vue-hello
不一樣的配方,一樣的 Hello World: