Docker 部署Go Web应用


picture.image

   随着Go的逐渐流行,基于性能、高效及稳定部署,越来越多的企业开始将其应用框架移植至Go平台。本文主要基于Goland开发平台和Docker容器环境运行,简要介绍Go语言开发的Web项目的容器化部署相关操作。






   

以下Demo主要简单实现登陆、注册等相关功能,具体如下:

picture.image

   部分源码如下:

          
package main
          

          
import (
          
  "crypto/md5"
          
  "database/sql"
          
  "encoding/json"
          
  "fmt"
          
  _"github.com/go-sql-driver/mysql"
          
  "io"
          
  "net/http"
          
)
          

          
func main() {
          
  mux := http.NewServeMux()
          
  mux.HandleFunc("/login", login)
          
  mux.HandleFunc("/register", register)
          
  http.ListenAndServe(":9090", mux) //监听9090端口
          
}
          

          
type result struct { //定义返回数据格式
          
  Code int
          
  Msg  string
          
  Data []string
          
}
          

          
func login(w http.ResponseWriter, r *http.Request) { //登陆
          
  w.Header().Set("Access-Control-Allow-Origin", "*") //允许跨域
          
  r.ParseForm()
          
  username, found1 := r.Form["username"]
          
  password, found2 := r.Form["password"]
          
  if !(found1 && found2) {
          
    io.WriteString(w, "请勿非法访问")
          
    return
          
  }
          
  db, err := sql.Open("mysql", "root@tcp(192.168.1.1:3306)/demo?charset=utf8") //登陆msyql
          
  if err != nil {
          
    fmt.Println(err)
          
  }
          
  defer db.Close()
          

          
  var post_data PostData
          
  post_data.user_name = username[0]
          
  post_data.pass_word = password[0]
          

          
  var filter_data FilterData = post_data
          
  post_data = filter_data.formatData()
          

          
  var row *sql.Row
          
  row = db.QueryRow("select * from users where username = ? and password = ?", post_data.user_name, post_data.pass_word)
          
  var user_name, pass_word string
          
  var id int
          
  err = row.Scan(&id, &user_name, &pass_word) //遍历结果
          
  if err != nil {
          
    arr := &result{
          
      500,
          
      "登陆失败",
          
      []string{},
          
    }
          
    b, json_err := json.Marshal(arr) //json化结果集
          
    if json_err != nil {
          
      fmt.Println("encoding faild")
          
    } else {
          
      io.WriteString(w, string(b)) //返回结果
          
    }
          
  } else {
          
    arr := &result{
          
      200,
          
      "登陆成功",
          
      []string{},
          
    }
          
    b, json_err := json.Marshal(arr) //json化结果集
          
    if json_err != nil {
          
      fmt.Println("encoding faild")
          
    } else {
          
      io.WriteString(w, string(b)) //返回结果
          
    }
          
  }
          
}
          

          
func register(w http.ResponseWriter, r *http.Request) { //注册
          
  w.Header().Set("Access-Control-Allow-Origin", "*") //允许跨域
          
  r.ParseForm()
          
  username, found1 := r.Form["username"]
          
  password, found2 := r.Form["password"]
          
  if !(found1 && found2) {
          
    io.WriteString(w, "请勿非法访问")
          
    return
          
  }
          
  db, err := sql.Open("mysql", "root@tcp(192.168.1.1:3306)/demo?charset=utf8")
          
  if err != nil {
          
    io.WriteString(w, "连接数据库失败")
          
    return
          
  }
          
  defer db.Close() //在返回前关闭资源(延迟)
          

          
  var post_data PostData
          
  post_data.user_name = username[0]
          
  post_data.pass_word = password[0]
          

          
  var filter_data FilterData = post_data
          
  post_data = filter_data.formatData()
          

          
  _, err = db.Exec("insert into users(username, password) values(?,?)", post_data.user_name, post_data.pass_word) //插入数据
          
  if err != nil {
          
    arr := &result{
          
      500,
          
      "注册失败",
          
      []string{},
          
    }
          
    b, json_err := json.Marshal(arr) //json化结果集
          
    if json_err != nil {
          
      fmt.Println("encoding faild")
          
    } else {
          
      io.WriteString(w, string(b)) //返回结果
          
    }
          
  } else {
          
    arr := &result{
          
      200,
          
      "注册成功",
          
      []string{},
          
    }
          
    b, json_err := json.Marshal(arr) //json化结果集
          
    if json_err != nil {
          
      fmt.Println("encoding faild")
          
    } else {
          
      io.WriteString(w, string(b)) //返回结果
          
    }
          
  }
          
}
          

          
type FilterData interface { //定义数据接口
          
  formatData() PostData
          
}
          

          
type PostData struct { //定义传递数据结构体
          
  user_name string
          
  pass_word string
          
}
          

          
func (post_data PostData) formatData() PostData { //格式化数据
          
  post_data.pass_word = mdFormat(post_data.pass_word)
          
  return post_data
          
}
          

          
func mdFormat(data string) string { //对字符串进行md5加密
          
  t := md5.New()
          
  io.WriteString(t, data)
          
  return fmt.Sprintf("%x", t.Sum(nil))
          
}
      
   程序运行结果:

picture.image

   至此,一个简单的Go Web程序开发完成,现在我们将其进行容器化部署。






   编写Dockerfile文件,具体内容如下所示:  

          
[administrator@JavaLangOutOfMemory go-Pro ]% vi Dockerfile
          
FROM golang:latest
          

          
ENV GO111MODULE=on \
          
    CGO_ENABLED=0 \
          
    GOOS=linux \
          
    GOARCH=amd64
          

          
WORKDIR /build
          

          
COPY . .
          

          
RUN go build -o appDemo .
          

          
WORKDIR /dist
          

          
RUN cp /build/appDemo .
          

          
EXPOSE 9090
          

          
CMD ["/dist/appDemo"]
      
   在项目目录下,执行下面的命令创建镜像,并指定镜像名称为:go-web-appdemo,具体如下所示:

          
[administrator@JavaLangOutOfMemory go-Pro ]% docker build . -t go-web-appdemo      
          
Sending build context to Docker daemon  22.36MB
          
Step 1/9 : FROM golang:latest
          
 ---> 1463476d8605
          
Step 2/9 : ENV GO111MODULE=on     CGO_ENABLED=0     GOOS=linux     GOARCH=amd64
          
 ---> Using cache
          
 ---> ffaaa4db652f
          
Step 3/9 : WORKDIR /build
          
 ---> Using cache
          
 ---> d540d5215e29
          
Step 4/9 : COPY . .
          
 ---> 2ce72619b717
          
Step 5/9 : RUN go build -o appDemo .
          
 ---> Running in d6541a17758c
          
 ... ...
          
Successfully built 2ce72619b717
          
Successfully tagged go-web-appdemo:latest
      
    此时,go-web-appdemo容器镜像已构建完成,启动容器,如下所示:

        
            

          [administrator@JavaLangOutOfMemory go-Pro ]% docker run -itd -p 9090:9090 --name luga-go-web-appdemon go-web-appdem
        
      
    再次通过浏览器访问,结果如下:

picture.image

    至此,一个简单的Go Web容器构建完成,并运行成功。
  • END -

点击关注公众号:" 牧师架构之路 "

0
0
0
0
评论
未登录
暂无评论