基於Docker和Golang搭建Web服務器

1 場景描述

  • 基於centos7的docker鏡像搭建golang開發環境
  • 在docker容器內,使用golang實現一個Web服務器
  • 啓動docker容器,並在容器內啓動Web服務器

我購買了一個最低配的阿里雲ECS服務器,並安裝好了git和docker,而後在本地實現Dockerfile和golang源代碼,並將源碼上傳到github,而後再到ECS服務器經過git下載代碼,並生成docker鏡像,最後啓動docker容器,場景圖示以下:
場景圖示git

2 你可能會問

  • 爲何不直接使用apache或其它http鏡像搭建Web服務器,而是本身實現Web服務?
    由於我要本身使用golang實現一個Web服務器,搭建服務器不是目的,練習golang和docker纔是目的。
  • 爲何不直接使用golang鏡像,而是本身搭建golang開發環境 ?
    由於我要部署本身的Web服務器,除了golang,我可能還須要其它操做系統服務,好比數據庫等。

總而言之,我要本身造一次輪子。github

3 搭建過程

3.1 使用golang實現一個簡易Web服務器

golang的http包讓搭建Web服務器比寫一個hello world還簡單:golang

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", home)
    http.ListenAndServe(":80", nil)
}

func home(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "welcome to yanzi travel")
}

 

除去包聲明、import語句以及函數頭,這個Web服務器的實現實際只有3行代碼。web

3.1.1 註冊路由

http.HandleFunc("/", home)docker

這行語句的做用是未來自相似http://127.0.0.1:80/的請求路由到home函數。固然,你還能夠註冊其它的路由,好比:數據庫

http.HandleFunc("/login", login)apache

http://127.0.0.1:80/login的請求路由到login函數。home和login函數的原型是:centos

func(ResponseWriter, *Request)瀏覽器

第一個參數爲Web服務器返回給客戶端的數據,第二個參數則是來自客戶端的請求數據。服務器

3.1.2 實現handler

func home(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "welcome to yanzi travel")
}

 

每次接收到http客戶端的請求後,該函數簡單地向客戶端返回一行語句就當即退出。

3.1.3 監聽80端口

http.ListenAndServe(":80", nil)

忽略地址意思是監聽全部地址上的80端口,第二個參數一般爲nil,http包會給它指定默認值DefaultServeMux。通過以上三步處理,一個最簡單的Web服務器就搭建成功了,若是不須要在容器內運行,使用go build命令編譯獲得可執行文件server.bin:

go build -o server.bin main.go

而後啓動server.bin,在瀏覽器內輸入http://127.0.0.1:80就能夠獲得服務器返回的結果:

簡易Web服務器

可是,咱們的目的是在docker容器內啓動這個Web服務器,那要怎麼作?請繼續往下看。

3.2 編寫Dockerfile

實際上,若是隻是爲了單次部署,能夠經過啓動並進入docker容器,而後搭建相應的服務,最後保存到自定義鏡像裏便可。可是如今生成的鏡像不可重現,由於單從鏡像文件啓動的容器信息很難反推當初本身作過什麼環境搭建和服務部署了。Dcokerfile的好處是讓這些過程變得透明,由於其中描述了鏡像生成的全過程,以及容器啓動的入口等。

3.2.1 指定基礎鏡像

FROM centos:7

MAINTAINER pirlo san <pirlo_san@163.com>

 

咱們會基於官方的centos7鏡像搭建golang開發環境,而後使用golang實現一個Web服務器,並在容器內啓動該服務。
MAINTAINER語句是指定這個鏡像的做者。

3.2.2 安裝goalng開發環境

# install gcc
# -y means saying yes to all questions
RUN yum install -y gcc

# install golang
RUN yum install -y go

 

由於golang可能依賴於gcc,所以須要先安裝gcc

3.2.3 配置golang環境變量

# config GOROOT
ENV GOROOT /usr/lib/golang
ENV PATH=$PATH:/usr/lib/golang/bin

# config GOPATH
RUN mkdir -p /root/gopath
RUN mkdir -p /root/gopath/src
RUN mkdir -p /root/gopath/pkg
RUN mkdir -p /root/gopath/bin
ENV GOPATH /root/gopath

 

GOROOT是golang的安裝路徑,GOPATH則是golang的開發包路徑,其中包括src/pkg/bin三個子目錄,分別用於存儲golang源代碼、golang編譯生成的包,以及編譯生成的可執行文件。除了設置GOROOT和GOPATH以外,還須要在操做系統的PATH變量內加入$GOROOT/bin,以讓go工具能夠被操做系統找到。

3.2.4 拷貝golang源代碼

# copy source files
RUN mkdir -p /root/gopath/src/server
COPY src/* /root/gopath/src/server/

 

在GOPATH的src目錄內建立server目錄,並將本地src目錄內的源文件所有拷貝進去。

3.2.5 編譯Web服務器

# build the server
WORKDIR /root/gopath/src/server
RUN go build -o server.bin main.go

 

WORKDIR將容器的工做目錄切換到server目錄,而後執行go build編譯獲得可執行文件server.bin。

3.2.6 指定容器入口

# startup the server
CMD /root/gopath/src/server/server.bin

 

CMD指定容器啓動後默認執行的程序,也就是咱們剛剛生成的Web服務器。

3.3 生成鏡像

Dockerfile生成之後,就能夠在Dockerfile所在目錄執行以下命令生成最終鏡像了,鏡像名稱爲server,版本號爲v0.1(注意最後的點哦):

docker build -t server:v0.1 .

 

3.4 啓動容器

終於到了啓動容器的時候了,還有點小激動呢。

docker run -d -p 80:80 server:v0.1

 -p參數的意思是將容器的80端口映射到本機的80端口,啓動完成後使用docker ps能夠看到咱們的容器被啓動了:

[root@iZuf69cwe60vsy9pmo1e9iZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
ae80a0b54134        server:v0.1         "/bin/sh -c /root/gop"   About an hour ago   Up About an hour    0.0.0.0:80->80/tcp   compassionate_heisenberg

 

4 客戶端訪問

個人阿里雲ECS服務器公網地址是101.132.163.20,在瀏覽器地址輸入 http://101.132.163.20便可驗證咱們的部署結果啦:

這裏寫圖片描述

相關文章
相關標籤/搜索