利用Dockerfile打包部署本地C/C++程序

前言

上一篇帖子写了如何在Ubuntu18.04上部署Docker,并简单跑了hello-world容器。这一篇继续探索Docker,如何利用Dockerfile打包部署自己写的程序。作者了解的就是C/C++,今天就用C++写一个简单的计算器程序,并且发布到Docker Hub上。

前期准备工作

在当前目录新建一个docker文件夹

mkdir docker

进入docker文件夹

cd docker

新建一个CPP文件,并进入编辑模式(i)

vim wxmtest.cpp

输入以下代码:

#include <iostream>
using namespace std;
 
int main()
{
    char op;
    float num1, num2;
 
    cout << "输入运算符:+、-、*、/ : ";
    cin >> op;
 
    cout << "输入两个数: ";
    cin >> num1 >> num2;
 
    switch(op)
    {
        case '+':
            cout << num1+num2;
            break;
 
        case '-':
            cout << num1-num2;
            break;
 
        case '*':
            cout << num1*num2;
            break;
 
        case '/':
            if (num2 == 0)
            {
                cout << "error不能除以零";
                break;
            }
            else
            {
                cout << num1 / num2;
                break;
            }
 
        default:
            // 如果运算符不是 +, -, * 或 /, 提示错误信息
            cout << "Error!  请输入正确运算符。";
            break;
    }
 
    return 0;
}
复制代码

esc退出编辑模式 然后输入:wq!保存

新建一个dockerfile

vim my_dockerfile

输入以下代码:

FROM codenvy/cpp_gcc

RUN  mkdir /home/user/myapp

ADD wxmtest.cpp /home/user/myapp

WORKDIR /home/user/myapp

RUN  g++ wxmtest.cpp -o wxmtest

CMD ["./wxmtest"]
复制代码

以上这段代码是镜像构成的精髓,下面逐一分析。docker镜像是通过分层构建、分层存储的的,每一条指令都会创建一层镜像。使用dockerfile构建镜像有以下好处:

  • 像编程一样构建镜像,支持分层构建以及缓存;
  • 可以快速而精确地重新创建镜像以便于维护和升级;
  • 便于持续集成;
  • 可以在任何地方快速构建镜像。

关于docker镜像有个清晰的解释:

Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。 镜像不包含任何动态数据,其内容在构建之后也不会被改变。Docker设计时,就充分利用Union FS的技术,将其设计为分层存储的架构。 镜像实际是由多层文件系统联合组成。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

好了,以上概念就说这些。看看每一层是怎么构建的吧

1. FROM

FROM 指令用于设置在新映像创建过程期间将使用的基础容器映像。

格式:FROM

镜像可以通过docker search 命令去docker Hub上去找自己想要的基础镜像,由于我们想要编译一个C++文件,我们可以使用带有g++或者gcc的镜像作为基础镜像。

2. RUN

RUN 指令指定将要运行并捕获到新容器映像中的命令。 这些命令包括安装软件、创建文件和目录,以及创建环境配置等。

格式:

RUN [“”, “”, “”]

RUN

RUN命令是容器构建时需要的命令,后面带有的就是我们常见的linux命令,RUN mkdir /home/user/myapp就是构建一个myapp文件夹

3. ADD

ADD命令是将宿主机下的文件拷贝到镜像,也可以用COPY命令,不过ADD比COPY的功能更强大,ADD带有解压缩的功能。ADD 指令与 COPY 指令非常类似,但它包含更多功能。除了将文件从主机复制到容器映像,ADD 指令还可以使用 URL 规范从远程位置复制文件。

格式:

ADD<source> <destination>

示例:

ADD www.python.org/ftp/python/… /temp/python-3.5.1.exe.
此示例会将 Python for Windows下载到容器映像的 c:\temp 目录。

4. WORKDIR

WORKDIR 指令用于为其他 Dockerfile 指令(如 RUN、CMD)设置一个工作目录,并且还设置用于运行容器映像实例的工作目录。

格式:

WORKDIR

示例:

WORKDIR /app

6. CMD

CMD指令用于设置部署容器映像的实例时要运行的默认命令,指定容器创建完成后第一个运行的命令。
格式:

CMD [“<executable>”],本示例需要把CPP文件RUN成二进制可执行文件,也就是Dockerfile代码的第五步

CMD

7. ENTRYPOINT

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。每个 Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。

格式:

ENTRYPOINT [“”, “”]

8.ENV

ENV命令用于设置环境变量。这些变量以”key=value”的形式存在,并可以在容器内被脚本或者程序调用。这个机制给在容器中运行应用带来了极大的便利。

格式:

ENV==…

9.EXPOSE

EXPOSE用来指定端口,使容器内的应用可以通过端口和外界交互。

格式:

EXPOSE

示例:

EXPOSE 80

以上结构可以总结为以下这个图:

70544-20181203094342684-400475059.png

编译Dockerfile

编译dockerfile并生成镜像(名字自己取)

docker build -f ./my_dockerfile -t wxmtest_docker:v1.0 .

查看自己创建的镜像是否存在

sudo docker images

进入网站注册自己的仓库名,设置密码,例如wangxueming66

hub.docker.com/

远程登录镜像库

sudo docker login

输入以上注册的用户名和密码,显示登录成功

把镜像名打上标签,自己的用户名一定在前面,否侧上传失败

sudo docker tag wxmtest_docker:v1.0 wangxueming66/wxmtest_docker:v1.0

push自己的镜像,ps:一定要加自己的用户名

sudo docker push wangxueming66/wxmtest_docker:v1.0

拉取镜像,本机或其他主机

sudo docker pull wangxueming66/wxmtest_docker:v1.0

参考连接:https://www.freesion.com/article/4644878666/

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享