基于Docker和Golang搭建阿里云Web服務器

基于Docker和Golang搭建Web服務器

1 場景描述

  • 基于centos7的docker鏡像搭建golang開發(fā)環(huán)境
  • 在docker容器內,使用golang實現(xiàn)一個Web服務器
  • 啟動docker容器,并在容器內啟動Web服務器

我購買了一個最低配的阿里云ECS服務器,并安裝好了git和docker,然后在本地實現(xiàn)Dockerfile和golang源代碼,并將源碼上傳到github,然后再到ECS服務器通過git下載代碼,并生成docker鏡像,最后啟動docker容器,場景圖示如下:


場景圖示

2 你可能會問

  • 為什么不直接使用apache或其它http鏡像搭建Web服務器,而是自己實現(xiàn)Web服務?
    因為我要自己使用golang實現(xiàn)一個Web服務器,搭建服務器不是目的,練習golang和docker才是目的。
  • 為什么不直接使用golang鏡像,而是自己搭建golang開發(fā)環(huán)境 ?
    因為我要部署自己的Web服務器,除了golang,我可能還需要其它操作系統(tǒng)服務,比如數(shù)據庫等。

總而言之,我要自己造一次輪子。

3 搭建過程

3.1 使用golang實現(xiàn)一個簡易Web服務器

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

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語句以及函數(shù)頭,這個Web服務器的實現(xiàn)實際只有3行代碼。

3.1.1 注冊路由

http.HandleFunc("/", home)

這行語句的作用是將來自類似http://127.0.0.1:80/的請求路由到home函數(shù)。當然,你還可以注冊其它的路由,比如:

http.HandleFunc("/login", login)

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

func(ResponseWriter, *Request)

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

3.1.2 實現(xiàn)handler

func home(w http.ResponseWriter, r *http.Request) {

fmt.Fprintf(w, ``"welcome to yanzi travel"``)

}

每次接收到http客戶端的請求后,該函數(shù)簡單地向客戶端返回一行語句就立即退出。

3.1.3 監(jiān)聽80端口

http.ListenAndServe(":80", nil)

忽略地址意思是監(jiān)聽所有地址上的80端口,第二個參數(shù)通常為nil,http包會給它指定默認值DefaultServeMux。經過以上三步處理,一個最簡單的Web服務器就搭建成功了,如果不需要在容器內運行,使用go build命令編譯得到可執(zhí)行文件server.bin:

go build -o server.bin main.go

然后啟動server.bin,在瀏覽器內輸入http://127.0.0.1:80就可以得到服務器返回的結果:

簡易Web服務器

但是,我們的目的是在docker容器內啟動這個Web服務器,那要怎么做?請繼續(xù)往下看。

3.2 編寫Dockerfile

實際上,如果只是為了單次部署,可以通過啟動并進入docker容器,然后搭建相應的服務,最后保存到自定義鏡像里即可。但是如此生成的鏡像不可重現(xiàn),因為單從鏡像文件啟動的容器信息很難反推當初自己做過什么環(huán)境搭建和服務部署了。Dcokerfile的好處是讓這些過程變得透明,因為其中描述了鏡像生成的全過程,以及容器啟動的入口等。

3.2.1 指定基礎鏡像

FROM centos:7

MAINTAINER pirlo san <pirlo_san@163.com>

|

我們會基于官方的centos7鏡像搭建golang開發(fā)環(huán)境,然后使用golang實現(xiàn)一個Web服務器,并在容器內啟動該服務。
MAINTAINER語句是指定這個鏡像的作者。

3.2.2 安裝goalng開發(fā)環(huán)境

# 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環(huán)境變量

# 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的開發(fā)包路徑,其中包括src/pkg/bin三個子目錄,分別用于存儲golang源代碼、golang編譯生成的包,以及編譯生成的可執(zhí)行文件。除了設置GOROOT和GOPATH之外,還需要在操作系統(tǒng)的PATH變量內加入$GOROOT/bin,以讓go工具可以被操作系統(tǒng)找到。

3.2.4 拷貝golang源代碼

# copy source files

RUN mkdir -p /root/gopath/src/server

COPY src/* /root/gopath/src/server/

|

在GOPATH的src目錄內創(chuàng)建server目錄,并將本地src目錄內的源文件全部拷貝進去。

3.2.5 編譯Web服務器

# build the server

WORKDIR /root/gopath/src/server

RUN ``go build -o server.bin main.``go

WORKDIR將容器的工作目錄切換到server目錄,然后執(zhí)行go build編譯得到可執(zhí)行文件server.bin。

3.2.6 指定容器入口

# startup the server

CMD /root/gopath/src/server/server.bin

CMD指定容器啟動后默認執(zhí)行的程序,也就是我們剛剛生成的Web服務器。

3.3 生成鏡像

Dockerfile生成以后,就可以在Dockerfile所在目錄執(zhí)行如下命令生成最終鏡像了,鏡像名稱為server,版本號為v0.1(注意最后的點哦):

docker build -t server:v0.1 .

3.4 啟動容器

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

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

-p參數(shù)的意思是將容器的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即可驗證我們的部署結果啦:

這里寫圖片描述
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容