13.8.3 Revel

Revel是一个高生产力的Go语言Web框架。Revel从Rails和Play!中吸收了许多成熟的设计思想。Revel支持MVC设计模式,它是一个轻量级的高效Web开发框架。Revel+Xorm(ORM)的技术栈可以方便的构建各种基于Go语言的Web服务。

笔者在此简述一下Revel框架的特性:

·热编译:编辑、保存和刷新时,Revel自动编译代码和模板,如果代码编译错误,会给出一个错误提示,同时捕捉运行期错误。

·全栈功能:Revel支持路由、参数解析、验证、session/flash、模板、缓存、计划任务、测试、国际化等功能。

·高性能:Revel基于Go HTTP server构建。这是techempower发布的最新评测结果。在各种不同的场景下进行了多达三到十次的请求负载测试。

1.准备工作

第一步,安装Revel框架:

$ go get github.com/revel/revel

第二步,安装Revel命令行工具:

$ go get github.com/revel/cmd/revel

第三步,创建Revel应用:

$ revel new myapp

生成的目录结构如下:

第四步,打开浏览器访问http://localhost:9000,如图13-3所示。

2.使用Docker Hub镜像

读者可以使用Docker Hub中提供的第三方Revel镜像,下载并直接运行。笔者列出以下镜像供读者参考:

$ sudo docker pull taddev/revel-base

如果读者需要运行已有的Revel站点,或者需要自定义启动流程,则笔者推荐使用内含SSH服务的镜像,以此为基础定制Revel镜像。当然,读者也可以参考以下Dockerfile构建自定义镜像:

#安装基础镜像

FROM google/golang

# 获取Revel

RUN go get github.com/revel/cmd/revel

13.8.4 Martini

Martini是一个优雅的Go语言Web框架(Classy web framework for Go),它是专门为使用Go语言编写模块化Web应用而生的。
笔者在此简述以下Martini框架的特性:
·使用极其简单。
·无侵入式的设计。
·很好地与其他的Go语言包协同使用。
·超赞的路径匹配和路由。
·模块化的设计——容易插入功能件,也容易将其拔出来。
·已有很多的中间件可以直接使用。
·框架内已拥有很好的开箱即用的功能支持。
·完全兼容http.HandlerFunc接口。·更多中间件和功能组件,可参考代码仓库:http://github.com/martini-contrib。
1.准备工作
在读者安装了GO语言并设置了自己的GOPATH之后,创建自己的.go文件,这里我们假设它的名字叫做server.go:
package main
import "github.com/go-martini/martini"
func main() {
m := martini.Classic()
m.Get("/", func() string {
return "Hello world!"
})
m.Run()
} 然
后,安装Martini的包(注意Martini需要Go语言1.1或者以上的版本支持):
$ go get github.com/go-martini/martini
最后,运行server.go:
$ go run server.go
此时已经启动了一个Martini的Web服务,地址是:localhost:3000。
2.使用Docker Hub镜像
读者可以直接使用Docker Hub中提供的第三方Martini镜像,下载镜像并直接运行。笔者给出以下命令供读者参考:
$ sudo docker pull lgsd/docker-martini
3.定制镜像
如果读者需要加载已有的Martini站点,或者需要定制启动流程,则笔者推荐使用内含SSH服务的镜像,以此为基础进行定制,这样可以方便地使用SSH服务访问Martini容器中的站点。当然,读者也可
以参考以下Dockerfile构建自定义镜像:
# Dockerfile for Martini/GOLANG 1.2
# 下载基础镜像
FROM lgsd/saucy
# 更新系统
RUN sed 's/main$/main universe/' -i /etc/apt/sources.list && \
apt-get -qq update && \
apt-get -y upgrade && \
apt-get install -y wget tar ca-certificates git
# 下载Go语言源码安装包
# into /usr/local, creating a Go tree in /usr/local/go
RUN wget https://go.googlecode.com/files/go1.2.linux-amd64.tar.gz && \
tar -C /usr/local -xzf go1.2.linux-amd64.tar.gz && \
rm go1.2.linux-amd64.tar.gz
# 安装完成后使用apt进行清理
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# 设置环境变量
ENV GOPATH /go
ENV PATH $PATH:/usr/local/go/bin:$GOPATH/bin
# 安装Martini安装包
RUN go get github.com/codegangsta/martini
# 根据官方启动流程, 创建server.go文件, 并验证安装结果
ENV FILE $HOME/server.go
RUN echo 'package main' > $FILE && \
echo 'import "github.com/codegangsta/martini"' >> $FILE && \
echo 'func main() {' >> $FILE && \
echo ' m := martini.Classic()' >> $FILE && \
echo ' m.Get("/", func() string {' >> $FILE && \
echo ' return "Hello world!"' >> $FILE && \
echo ' })' >> $FILE && \
echo ' m.Run()' >> $FILE && \
echo '}' >> $FILE
# 使用3000端口运行Martini
localhost:3000
EXPOSE 3000
# 设置默认启动命令
CMD ["go", "run", "server.go"]

13.8.5 相关资源

Go语言官网:https://golang.org/
Go Docker官方镜像:https://registry.hub.docker.com/_/golang/
Go Docker官方镜像标签:https://registry.hub.docker.com/_/golang/tags/manage/
Docker Hub中Google提供的Go镜像:
https://registry.hub.docker.com/u/google/golang-hello/
https://registry.hub.docker.com/u/google/golang-runtime/
https://registry.hub.docker.com/u/google/golang/
Beego官网:http://beego.me/
Beego Docker Hub镜像:https://registry.hub.docker.com/u/cloudcube/beego/
Boogo Dockerfile:https://registry.hub.docker.com/u/cloudcube/beego/dockerfile/
Revel官网:http://www.gorevel.cn/Revel中国官网:http://gorevel.cn/
Revel Docker Hub镜像:https://registry.hub.docker.com/u/taddev/revel-base/
Revel Dockerfile:https://registry.hub.docker.com/u/taddev/revel-base/dockerfile/
Martini官网:http://martini.codegangsta.io/
Martini Docker Hub镜像:https://registry.hub.docker.com/u/lgsd/docker-martini/
Martini Dockerfile:https://registry.hub.docker.com/u/lgsd/docker-martini/dockerfile/

13.9 本章小结

在本章中,笔者主要介绍了如何使用Docker搭建主流编程语言及其常用开发框架的Docker环境。由于时间仓促且水平有限,所以笔者重点阐述了PHP语言的Docker环境。其他编程语言的自定义Docker环境与PHP环境下的操作流程大同小异:均是基于内含SSH服务的镜像,定制Dockerfile,随后构建并运行镜像即可。这样读者可以方便地使用SSH服务访问自定义容器中的站点或程序。当然,读者也可以直接使用官网的编程语言镜像,通过适当的配置也可以构建自定义镜像并正常使用容器。如果读者对本章内容有任何疑问,可以前往DockerPool社区(http://dockerpool.com)。由于编程语言的更新迭代比较频繁,所以本章内容会在DockerPool社区持续更新,敬请关注。

第14章 使用私有仓库

在使用Docker一段时间后,往往会发现手头积累了大量的自定义镜像文件,这些文件通过公有仓库进行管理并不十分方便;另外有时候只是希望内部用户之间进行分享。

在这种情况下,就有必要搭建一个本地的私有仓库服务器。在第一部分中,笔者讲解了快速使用docker-registry镜像搭建一个私有仓库的方法。本章将具体介绍docker-registry开源项目的使用细节,并通过具体案例来展示如何搭建一个本地的仓库服务器。

在搭建完成本地的私有仓库服务器后,接下来会介绍如何编写脚本来批量上传本地镜像到私有仓库中。最后会对docker-registry项目的配置文件以及各种选项进行剖析。

14.1 使用docker-registry

docker-registry是一个基于Python的开源项目,可以用于构建私有的镜像注册服务器。官方仓库中也提供了docker-registry的镜像,因此用户可以通过容器运行和源码安装两种方式来使用dockerregistry。

在第一部分中,笔者简单介绍了基于容器运行docker-registry的过程。首先,获取并运行官方registry镜像:
$ sudo docker run -d -p 5000:5000 registry
启动后比较关键的参数是指定配置文件和仓库存储路径。
通过如下命令,可以指定本地路径(如/home/user/registry-conf)下的配置文件:
$ sudo docker run -d -p 5000:5000 -v /home/user/registry-conf:/registry-conf -e DOCKER_REGISTRY_CONFIG=/registry-conf/config.yml registry
通过-v参数来配置仓库路径。例如下面的例子将镜像存储到本地/opt/data/registry目录:
$ sudo docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
本地安装运行
有时候需要本地运行仓库服务,可以通过安装包或源码方式进行。
对于Ubuntu或CentOS行发行版,可以直接通过源安装。
·Ubuntu版的安装:
$ sudo apt-get install -y build-essential python-dev libevent-dev python-pip
liblzma-dev
$ sudo pip install gunicorn pyyaml flask flask-cors rsa
$ sudo pip install docker-registry
·CentOS版的安装:
$ sudo yum install -y python-devel libevent-devel python-pip gcc xz-devel
$ sudo pip install gunicorn pyyaml flask flask-cors rsa gevent
$ sudo python-pip install docker-registry
也可以从docker-registry(https://github.com/docker/docker-registry)项目下载源码进行安装:
$ sudo apt-get install build-essential python-dev libevent-dev python-pip
libssl-dev liblzma-dev libffi-dev$ git clone https://github.com/docker/docker-registry.git
$ cd docker-registry
然后基于样例配置创建配置文件:
$ cp config/config_sample.yml config/config.yml
修改local模板段的storage_path到本地的存储仓库的路径,例如:opt/data/registry。
local: &local
<<: *common
storage: local
storage_path: _env:STORAGE_PATH:/opt/data/registry
然后执行安装操作:
$ sudo python setup.py install
对于通过软件包方式安装的,配置文件一般需要放在/usr/local/lib/python2.7/dist-packages/docker_registry/config/config.yml。
此时,可以通过下面的命令来启动:
$ sudo gunicorn --access-logfile /var/log/docker-registry/access.log --error-logfile /var/log/docker-registry/server.log -k gevent --max-requests 100 --graceful-timeout 3600 -t 3600 -b 1
此时使用访问本地的5000端口,看到输出docker-registry的版本信息说明运行成功:
$ sudo curl 127.0.0.1:5000
"docker-registry server (dev) (v0.8.1)"
配置服务脚本
一般通过服务脚本来管理registry服务会更加方便,以Ubuntu 14.04系统为例。
首先,创建/etc/init/docker-registry.conf文件,内容为:
description "Docker Registry"
start on runlevel [2345]
stop on runlevel [016]
respawn
respawn limit 10 5
script
exec gunicorn --access-logfile /var/log/docker-registry/access.log --error-logfile /var/log/docker-registry/server.log -k gevent --max-requests 100 --graceful-timeout 3600 -t 3600 -b loc
end script
然后,执行service docker-registry start,将在本地的15000端口启动registry服务。

14.2 用户认证

通常在生产场景中,对私有仓库还需要进行访问代理和提供认证和用户管理。
配置Nginx代理
使用Nginx来代理registry服务的原理十分简单,在上一节中,我们让registry服务监听在127.0.0.1:15000,这意味着只允许本机才能通过15000端口访问到,其他主机是无法访问到的。
为了让其他主机访问到,可以通过Nginx监听在对外地址的5000端口,当外部访问请求到达5000端口时,内部再将请求转发到本地的15000端口。
首先,安装Nginx。
$ sudo apt-get -y install nginx
在/etc/nginx/sites-available/目录下,创建新的站点配置文件/etc/nginx/sites-available/docker-registry.conf,代理本地的5000端口转发到15000端口。
配置文件内容为:
#本地的registry服务监听在15000端口
upstream docker-registry {
server localhost:15000;
}#
代理服务器监听在5000端口
server {
listen 5000;
server_name private-registry-server.com;
# ssl on;
# ssl_certificate /etc/ssl/certs/docker-registry;
# ssl_certificate_key /etc/ssl/private/docker-registry;
proxy_set_header Host $http_host; # required for Docker client sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
chunked_transfer_encoding on;
location / {
# 配置转发对于/的访问请求到registry服务
proxy_pass http://docker-registry;
}l
ocation /_ping {
# 配置转发对于/ping的访问请求到registry服务
auth_basic off;
proxy_pass http://docker-registry;
}l
ocation /v1/_ping {
# 配置转发对于/v1/ping的访问请求到registry服务
auth_basic off;
proxy_pass http://docker-registry;}
} 建
立配置文件软连接,放到/etc/nginx/sites-enabled/下面,让Nginx启用它,最后重启Nginx服务。
$ sudo ln -s /etc/nginx/sites-available/docker-registry.conf /etc/nginx/sites-enabled/docker-registry.conf
$ service nginx restart
之后,可以通过上传镜像来测试服务是否正常。测试上传本地的ubuntu:latest镜像:
$ sudo docker tag ubuntu:14.04 127.0.0.1:5000/ubuntu:latest
$ sudo docker push 127.0.0.1:5000/ubuntu:latest
添加用户认证
公共仓库DockerHub是通过注册索引(index)服务来实现的。由于index服务并没有完善的开源实现,在这里介绍基于Nginx代理的用户访问管理方案。
Nginx支持基于用户名和密码的访问管理。
首先,在配置文件的location/字段中添加两行。
http://www.hzcourse.com/resource/readBook?path=/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...
location / {
# let Nginx know about our auth file
auth_basic "Please Input username/password";
auth_basic_user_file docker-registry-htpasswd;
proxy_pass http://docker-registry;
}h
ttp://www.hzcourse.com/resource/readBook?path=/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...
auth_basic "Please Input username/password";行说明启用认证服务,不通过的请求将无法转发。
auth_basic_user_file docker-registry-htpasswd;指定了验证的用户名密码存储文件为本地(/etc/nginx/下)的docker-registry-htpasswd文件。
docker-registry-htpasswd文件中存储用户名密码的格式为每行放一个用户名、密码对:
http://www.hzcourse.com/resource/readBook?path=/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...
user1:password1
user2:password2
http://www.hzcourse.com/resource/readBook?path=/openresources/teach_ebook/uncompressed/15029/OEBPS/Text/...
需要注意的是,密码字段存储的并不是明文,而是使用crypt函数加密过的字符串。
要生成加密后的字符串,可以通过htpasswd工具,首先安装apache2-utils:
$ sudo aptitude install apache2-utils -y
创建用户user1,并添加密码。
例如,如下的操作会创建/etc/ngix/docker-registry-htp asswd文件来保存用户名和加密后的密码信息,并创建user1和对应密码。
$ sudo htpasswd -c /etc/nginx/docker-registry-htpasswd user1
$ New password:
$ Re-type new password:
$ Adding password for user user1
添加更多用户,可以重复上面的命令(密码文件存在后,不需使用-c选项重新创建)。
最后,重新启动Nginx服务。
$ sudo service nginx restart
此时,通过浏览器访问本地的服务http://127.0.0.1:5000/v1/search,会弹出对话框,提示需要输入用户名和密码。
通过命令行访问,需要在地址前面带上用户名和密码才能正常返回:
$ curl USERNAME:PASSWORD@localhost:5000/v1/search

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐