5、构建 app
[root@dev_08 portainer]# grunt build
如果遇到这样的错误:
Building portainer for linux-amd64
/go/src/github.com/portainer/portainer/crypto/crypto.go:4:2: cannot find package "golang.org/x/crypto/bcrypt" in any of:
/usr/local/go/src/golang.org/x/crypto/bcrypt (from $GOROOT)
/go/src/golang.org/x/crypto/bcrypt (from $GOPATH)
/go/src/github.com/portainer/portainer/http/handler/websocket.go:21:2: cannot find package "golang.org/x/net/websocket" in any of:
/usr/local/go/src/golang.org/x/net/websocket (from $GOROOT)
/go/src/golang.org/x/net/websocket (from $GOPATH)
mv: cannot stat ‘api/cmd/portainer/portainer-linux-amd64’: No such file or directory
Warning: Command failed: build/build_in_container.sh linux amd64
mv: cannot stat ‘api/cmd/portainer/portainer-linux-amd64’: No such file or directory
Use --force to continue.
Aborted due to warnings.
那是因为网络可达性问题,国内访问 golang.org 异常。
[root@dev_08 portainer]# host golang.org
golang.org is an alias for golang-consa.l.google.com.
golang-consa.l.google.com has address 216.239.37.1
解决方法:
[root@dev_08 portainer]# go get github.com/golang/crypto/tree/master/bcrypt
[root@dev_08 portainer]# go get github.com/golang/net/tree/master/websocket
[root@dev_08 portainer]# cd $GOPATH/src
[root@dev_08 src]# mkdir golang.org/x -p
[root@dev_08 src]# mv github.com/golang/* golang.org/x/
然后再切换到源码目录,调整构建脚本:
[root@dev_08 src]# cd /opt/portainer
[root@dev_08 portainer]# vim build/build_in_container.sh
挂载本地的 $GOPATH/src/golang.org 到容器路径:/go/src/golang.org
docker run --rm -tv $(pwd)/api:/src -e BUILD_GOOS="$1" -e BUILD_GOARCH="$2" portainer/golang-builder:cross-platform /src/cmd/portainer
调整为:
docker run --rm -tv $(pwd)/api:/src -v $GOPATH/src/golang.org:/go/src/golang.org -e BUILD_GOOS="$1" -e BUILD_GOARCH="$2" portainer/golang-builder:cross-platform /src/cmd/portainer
10、测试上述镜像
[root@dev_08 portainer]# mkdir -p /data/portainer_dev
[root@dev_08 portainer]# docker run -d -p 9001:9000 -v /var/run/docker.sock:/var/run/docker.sock -v /data/portainer_dev:/data --name portainer_dev opera443399/portainer:dev
[root@dev_08 portainer]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cbd986df765b opera443399/portainer:dev "/portainer" 8 seconds ago Up 7 seconds 0.0.0.0:9001->9000/tcp portainer_dev
首次使用时将初始化一个管理员账户(本例使用 httpie 来提交)
[root@dev_08 portainer]# http POST :9001/api/users/admin/init Username="admin" Password="Develop"
HTTP/1.1 200 OK
Content-Length: 0
Content-Type: text/plain; charset=utf-8
Date: Tue, 10 Oct 2017 08:18:19 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
访问页面:your_dev_ip:9001
验证功能:符合预期
清理:
[root@dev_08 portainer]# docker rm -f portainer_dev
三、开发需求示例
可结合 github 的搜索功能来查找关键字。
1、需求:在 'Container list' 页面,设定初始化时,默认不显示所有容器(即默认不勾选 'Show all containers' 这个复选框)
注1:从 1.14.1 版本开始使用 cookie 来记录是否显示所有的状态(Persist the status of the show all containers filter: #1198),其实完全可以不更改代码,去掉 checkbox 的选择后,下次登录还是 unchecked 的状态,本例仅作为修改代码的一个 howto 来展示。
注2:从 1.14.1 版本开始,新增了针对资源的限制(Add the ability to manage CPU/MEM limits & reservations for Swarm services: #516),不妨一试。
https://github.com/portainer/portainer/releases
五、FAQ
1、为何不能统一管理 swarm mode 集群下的资源?
状态:
我理解,这个UI的开发理念是一个简单通用的docker UI
目前的方式是:每个 node 都是一个 endpoint,要切换 endpoint 来执行 docker API 指令获取该 node 上的容器等信息。
未来计划增加 swarm mode 集群管理的功能。
具体的讨论,还请跟踪下这个 issue 相关的内容:
[FEATURE REQUEST] Be able to use all the Portainer built-in functionalities in all the containers running in a swarm cluster #461
https://github.com/portainer/portainer/issues/461
4)提交的信息格式
<type>(<scope>): <subject>
不要超过 100 字符,整洁的 commit log 示例:
#271 feat(containers): add exposed ports in the containers view
#270 fix(templates): fix a display issue in the templates view
#269 style(dashboard): update dashboard with new layout
有如下几类 type
feat: A new feature
fix: A bug fix
docs: Documentation only changes
style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
refactor: A code change that neither fixes a bug or adds a feature
test: Adding missing tests
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
Scope
关于 scope :表示
提交的代码是改动了哪一块的内容,例如:networks, containers, images 可以使用 area 标签来关联 issue (例如:标签 area/containers 使用 containers 作为a scope)
关于 subject :表示
简明的描述本次提交做了那些改变
使用祈使句和现在时: "change" not "changed" nor "changes"
不要大些第一个字母
语句最后不要使用点 (.)