手记

Docker部署--腾讯云和Mac

Docker是一个跨平台的轻量级容器,可移植性非常高,一次部署,终生可用。网上这方面的概述一大堆,就不细写了。这一套搭建下来,其实就是Docker镜像、Registry仓库、Docker容器。我们可以在本地自己生产镜像(下面会有具体操作),也可以直接下载别人或者官方的现成镜像,然后pull到Registry仓库(文中使用DockerHub(https://hub.docker.com/)是默认的 Registry,由 Docker 公司维护,上面有数以万计的镜像,用户可以自由下载和使用。)。这个时候我们可以在任何地方安装了Docker的地方push我们的镜像,build  and  run.....

腾讯云安装Docker

  1. 先登录腾讯云后台,可以直接登录后台,也可以用本地终端

ssh ubuntu@ip地址   //注意腾讯云用户名是ubuntu,不是root再输入密码即可~

先登录腾讯云后台.png

  1. 使用sudo passwd root设置root的密码

  2. 切换到root用户

ubuntu@VM-42-54-ubuntu:~$ su rootPassword: root@VM-42-54-ubuntu:/home/ubuntu#
  1. 在服务器下载Docker
    官方安装指南

1.更新apt软件包索引。
$ sudo apt-get update2.安装最新版本的Docker CE,或转到下一步安装特定版本。任何现有的Docker安装都会被替换。
$ sudo apt-get install docker-ce

在这里我遇到了错误E: Unable to locate package docker-ce
有人在stack overflow给出答案

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"sudo apt-get update
sudo apt-get install docker-ce

检测安装成功了没

root@VM-42-54-ubuntu:/home/ubuntu# docker versionClient:
 Version:   17.12.1-ce
 API version:   1.35
 Go version:    go1.9.4
 Git commit:    7390fc6 Built: Tue Feb 27 22:17:40 2018
 OS/Arch:   linux/amd64Server:
 Engine:
  Version:  17.12.1-ce
  API version:  1.35 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   7390fc6  Built:    Tue Feb 27 22:16:13 2018
  OS/Arch:  linux/amd64  Experimental: false

服务器Docker安装完毕~

Mac端安装Docker

官方下载地址谁用谁知道,整整下了我一下午!!!
百度云:链接:https://pan.baidu.com/s/1ppYSk24VfhUGS3XLHe4hZw  密码:9uly

根据晚上资料发现以前好像是使用了boot2docker或者docker toolbox。但现在docker for Mac全搞定了,也就不去查看以前的一些工具了。一键安装完毕后打开,右上角小鲸鱼出现了


小鲸鱼.png

打开终端:

localhost:~ ljb48229$ docker versionClient:
 Version:   17.12.0-ce
 API version:   1.35
 Go version:    go1.9.2
 Git commit:    c97c6d6 Built: Wed Dec 27 20:03:51 2017
 OS/Arch:   darwin/amd64Server:
 Engine:
  Version:  17.12.0-ce
  API version:  1.35 (minimum version 1.12)
  Go version:   go1.9.2
  Git commit:   c97c6d6  Built:    Wed Dec 27 20:12:29 2017
  OS/Arch:  linux/amd64  Experimental: true

本地安装完毕~

注册Docker hub

官网注册自己的Docker ID
用来存放自己的镜像~

开始玩Docker

先在本地生成一个镜像,在pull到Dockerhub,然后在服务器push这个镜像,运行~

  • 在本地列出已经下载下来的镜像,可以使用 docker images 命令。

localhost:~ ljb48229$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

可以看到现在本地的镜像没有。
现在将firstwenapp包打包成镜像~


image.png


在main.go文件中

package mainimport (    "fmt"
    "net/http")func handler(rw http.ResponseWriter, req *http.Request) {
    fmt.Fprintf(rw, "hello world, %s", req.URL.Path[1:])
}func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

监听8080端口,访问时返回hello world + 请求参数,功能很简单~
可以看到我们在项目根目录下增加了Dockerfile文件。

Dockerfile文件

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

FROM golang

ADD . $GOPATH/src/github.com/jiangboLee/go_web_study/firstwebapp 
WORKDIR $GOPATH/src/github.com/jiangboLee/go_web_study/firstwebapp 
RUN go install github.com/jiangboLee/go_web_study/firstwebapp 

ENTRYPOINT /go/bin/firstwebapp

EXPOSE 8080
FROM 指定基础镜像

所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。而 FROM 就是指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。这里是指定golang的环境。

ADD

如果 <源路径> 为一个 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令将会自动解压缩这个压缩文件到 <目标路径> 去。
在 Docker 官方的最佳实践文档中要求,尽可能的使用 COPY,因为 COPY 的语义很明确,就是复制文件而已,而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。
另外需要注意的是,ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。
因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD。

WORKDIR 指定工作目录

格式为WORKDIR <工作目录路径>

使用WORKDIR指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR会帮你建立目录。

之前提到一些初学者常犯的错误是把 Dockerfile 等同于 Shell 脚本来书写,这种错误的理解还可能会导致出现下面这样的错误:

RUN cd /app
RUN echo "hello" > world.txt

如果将这个 Dockerfile 进行构建镜像运行后,会发现找不到 /app/world.txt文件,或者其内容不是hello。原因其实很简单,在 Shell 中,连续两行是同一个进程执行环境,因此前一个命令修改的内存状态,会直接影响后一个命令;而在 Dockerfile 中,这两行 RUN 命令的执行环境根本不同,是两个完全不同的容器。这就是对 Dokerfile 构建分层存储的概念不了解所导致的错误。

每一个 RUN都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN cd /app 的执行仅仅是当前进程的工作目录变更,一个内存上的变化而已,其结果不会造成任何文件变更。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。

因此如果需要改变以后各层的工作目录的位置,那么应该使用 WORKDIR指令。

RUN 执行命令

RUN指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:

shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockrfile 中的 RUN 指令就是这种格式。
RUN go install github.com/jiangboLee/go_web_study/firstwebapp
exec 格式:RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式。
既然 RUN 就像 Shell 脚本一样可以执行命令,那么我们是否就可以像 Shell 脚本一样把每一层构建需要的命令写出来,比如这样:

FROM debian:jessie

RUN buildDeps='gcc libc6-dev make' \
    && apt-get update \
    && apt-get install -y $buildDeps \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
    && mkdir -p /usr/src/redis \
    && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    && make -C /usr/src/redis \
    && make -C /usr/src/redis install \
    && rm -rf /var/lib/apt/lists/* \
    && rm redis.tar.gz \
    && rm -r /usr/src/redis \
    && apt-get purge -y --auto-remove $buildDeps

仅仅使用一个 RUN指令,并使用&&将各个所需命令串联起来。在撰写 Dockerfile 的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每一层该如何构建。

并且,这里为了格式化还进行了换行。Dockerfile 支持 Shell 类的行尾添加 \的命令换行方式,以及行首#进行注释的格式。良好的格式,比如换行、缩进、注释等,会让维护、排障更为容易,这是一个比较好的习惯。

此外,还可以看到这一组命令的最后添加了清理工作的命令,删除了为了编译构建所需要的软件,清理了所有下载、展开的文件,并且还清理了 apt 缓存文件。这是很重要的一步,我们之前说过,镜像是多层存储,每一层的东西并不会在下一层被删除,会一直跟随着镜像。因此镜像构建时,一定要确保每一层只添加真正需要添加的东西,任何无关的东西都应该清理掉。

很多人初学 Docker 制作出了很臃肿的镜像的原因之一,就是忘记了每一层构建的最后一定要清理掉无关文件。

ENTRYPOINT

ENTRYPOINT命令指令指示/go/bin/firestwebapp设置为随容器启动

EXPOSE声明端口

EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P时,会自动随机映射 EXPOSE的端口。

要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口>区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
更多指令参考

开始构建镜像

docker build -t firstwebapp .

localhost:firstwebapp ljb48229$ docker build -t firstwebapp .
Sending build context to Docker daemon  3.072kB
Step 1/6 : FROM golang
latest: Pulling from library/golang3e731ddb7fc9: Downloading [===============>                                   ]  13.67MB/45.13MB47cafa6a79d0: Download complete 
79fcf5a213c7: Downloading [==================================>                ]  2.961MB/4.335MB68e99216b7ad: Waiting 
9fc7abc9c77e: Waiting 
ba4ddae991a2: Waiting 
3f3987c89b39: Waiting

会比较慢,耐心等吧。也可以使用DaoCloud注册后找到

DaoCloud.png


里面3个平台的加速都有,下方怎么配置也很清楚。


构建结束后可在本地运行
localhost:firstwebapp ljb48229$ docker build -t firstwebapp .
Sending build context to Docker daemon  3.072kB
Step 1/6 : FROM golanglatest: Pulling from library/golang3e731ddb7fc9: Pull complete 
47cafa6a79d0: Pull complete 
79fcf5a213c7: Pull complete 
68e99216b7ad: Pull complete 
9fc7abc9c77e: Pull complete 
ba4ddae991a2: Pull complete 
3f3987c89b39: Pull complete 
Digest: sha256:6eb41fbcc928d0ddbd1099c6dca11ba4e4055ce8392292c0340bf06471a42f8eStatus: Downloaded newer image for golang:latest
 ---> 1c1309ff8e0d
Step 2/6 : ADD . $GOPATH/src/github.com/jiangboLee/go_web_study/firstwebapp
 ---> 6bf65c3822b6
Step 3/6 : WORKDIR $GOPATH/src/github.com/jiangboLee/go_web_study/firstwebapp
Removing intermediate container 6189eea41a54
 ---> 7c7b58c22b69
Step 4/6 : RUN go install github.com/jiangboLee/go_web_study/firstwebapp
 ---> Running in e22c727c8817
Removing intermediate container e22c727c8817
 ---> 3f7f25083caa
Step 5/6 : ENTRYPOINT /go/bin/firstwebapp
 ---> Running in 0691889223e9
Removing intermediate container 0691889223e9
 ---> ef2d999edd12
Step 6/6 : EXPOSE 8080
 ---> Running in ed2b63c75d71
Removing intermediate container ed2b63c75d71
 ---> ef66341d11f1
Successfully built ef66341d11f1
Successfully tagged firstwebapp:latestlocalhost:firstwebapp ljb48229$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
firstwebapp         latest              ef66341d11f1        11 seconds ago      786MB
golang              latest              1c1309ff8e0d        3 weeks ago         779MBlocalhost:firstwebapp ljb48229$ docker run -p 80:8080 --rm firstwebapp

这时候打开浏览器http://localhost/ljb,效果如下:

image.png


-p 80:8080标志打开HTTP端口80并将其映射至前面通过EXPOSE命令暴露的8080端口,而--rm标志则指示Docker在容器已经存在的情况下,先移除已有的容器,然后再创建并启动新容器。

localhost:~ ljb48229$ docker ps //查看已启动容器CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES363e265c7e66        firstwebapp         "/bin/sh -c /go/bin/…"   3 minutes ago       Up 3 minutes        0.0.0.0:80->8080/tcp   suspicious_joliot
localhost:~ ljb48229$ docker stop 363e265c7e66 //关闭容器363e265c7e66
localhost:~ ljb48229$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
localhost:~ ljb48229$
将镜像上传
docker login
docker push 注册用户名/镜像名

再去登录自己的dockerHub,就能看到上传的镜像~
参考

服务器拉去镜像

docker pull 注册用户名/镜像名
然后运行
docker run -p 80:8080 --rm firstwebapp
这个时候只需要在浏览器输入您的ip地址就会有hello world

结束

这个流程大概已经走了一遍。接下来就是丰富代码,然后构建新的镜像,推,拉~就是这么简单 ~可能更高级的用法值得探索哈 ~



作者:iOS小白白
链接:https://www.jianshu.com/p/ea3078dae4fb


0人推荐
随时随地看视频
慕课网APP