先来了解一下 Alpine Linux:Alpine Linux是一个由社区开发的Linux操作系统,该操作系统以安全为理念,面向x86路由器防火墙虚拟专用网、IP电话盒及服务器而设计。目前比较流行的 rootfs 应该就是 alpine 了,因为他的体积特别小,最简单的环境只需要 5M 。Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。
下面以ZeroMQ官网的示例程序为例,实现在alpine基础镜像中,集成g++编译环境以及zmq运行环境并制作镜像,之后运行查看效果。

部署步骤

第一步:基础镜像准备

首先拉去一下 alpine 镜像:

  1. docker pull alpine

看一下大小:

  1. # docker images
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. centos latest 831691599b88 6 days ago 215MB
  4. debian latest 1b686a95ddbf 2 weeks ago 114MB
  5. alpine latest a24bb4013296 3 weeks ago 5.57MB
  6. ubuntu latest 1d622ef86b13 2 months ago 73.9MB

只有4m多,作为基础镜像应该是很理想的。相比于 CentosdebianUbuntu 在体积上确实很有优势。
下载完镜像,可以把这个迷你的linux启动起来,进去玩玩

  1. docker run -it alpine /bin/sh

alpine 的软件包管理系统是 APK ,比如安装 gccg++ 编译环境,需要运行如下命令:

  1. // 修改国内源
  2. echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/main" > /etc/apk/repositories
  3. echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/community" >> /etc/apk/repositories
  4. // 安装gccg++
  5. apk add gcc
  6. apk add g++

如果要安装 libzmq 则执行下面代码:

  1. apk add zeromq-dev

第二步:创建Dockerfile文件,制作镜像

建议新建一个文件夹放Dockerfile文件,后面需要放入Docker容器的文件也可以放在该文件夹中,方便管理。

  1. mkdir docker_zmq_server
  2. cd docker_zmq_server

在文件夹中新建 Dockerfile 文件,以下是文件参考内容:

  1. FROM alpine:latest as centos_zmq_server
  2. MAINTAINER tlsong <songtianlun@frytea.com>
  3. RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/main" > /etc/apk/repositories
  4. RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.8/community" >> /etc/apk/repositories
  5. RUN apk add zeromq-dev
  6. RUN apk add g++
  7. COPY hw_server.cpp /home/
  8. WORKDIR /home
  9. RUN g++ hw_server.cpp -o hw_server -lzmq
  10. CMD ["./hw_server"]

其中涉及到的 hw_server.cpp 代码如下,来自官网,文件需放入刚刚创建的文件夹:

  1. // Hello World server
  2. #include <zmq.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <assert.h>
  7. int main (void)
  8. {
  9. // Socket to talk to clients
  10. void *context = zmq_ctx_new ();
  11. void *responder = zmq_socket (context, ZMQ_REP);
  12. int rc = zmq_bind (responder, "tcp://*:5555");
  13. assert (rc == 0);
  14. while (1) {
  15. char buffer [10];
  16. zmq_recv (responder, buffer, 10, 0);
  17. printf ("Received Hello\n");
  18. sleep (1); // Do some 'work'
  19. zmq_send (responder, "World", 5, 0);
  20. }
  21. return 0;
  22. }

下面创建镜像:

  1. $ docker build -t docker_zmq_server docker_zmq_server

默认情况下 docker build -t testx . 命令中的 . 表示 build 上下文为当前目录。在这里我们指定一个目录作为上下文, COPY 命令只能拷贝上下文目录中的内容到Docker中,否则会报错。
看一下创建好的镜像:

  1. $ docker images
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. docker_zmq_server latest c9c5d01c213c 2 hours ago 157MB

第三步:运行docker

跑起来看一下效果:

  1. $ docker run -it docker_zmq_server /bin/sh
  2. /home # ls
  3. ???@@??@8 hw_client hw_client.cpp hw_client_host

完成,这样就完成了C/C++程序在Docker中的编译部署。

参考文献