(一))
实战案例编程开发1、C/C1.1、GCC1.1.1、使用官方镜像1.1.2、定制镜像1.2、LLVM1.2.1、使用官方镜像1.2.2、定制镜像1.3、Clang1.3.1、使用官方镜像1.3.2、定制镜像1.3.3、相关资源2、Java2.1、使用官方镜像2.2、Spring Boot2.3、相关资源3、Python3.1、使用官方镜像3.2、使用PyPy3.3、使用Django3.3.1、使用Django镜像3.3.2、使用Compose搭建Django应用3.3.3、使用Docker Hub镜像3.3.4、自定义uWSGINginxDjango镜像3.4、使用Flask3.4.1、使用Docker Hub镜像3.4.2、使用Compose构建FlaskMongoDB服务3.5、使用Sentry3.6、相关资源4、JavaScript4.1、使用Node.js4.1.1、使用官方镜像4.1.2、使用alpine精简版Node镜像4.2、相关资源1、C/CC是一门古老的语言在今天仍然是系统领域和高性能计算的主要选择它在1969年由贝尔实验室设计开发。C语言具有高效、灵活、功能丰富、表达力强和较高的可移植性等特点。C在C的基础上支持了数据的抽象与封装、面向对象和泛型编程。功能与性能的平衡使C成为目前应用最广泛的系统编程语言之一。1.1、GCCGCCGNU Compiler CollectionGNU编译器套装是一套由GNU开发的编程语言编译器是一套根据GPL及LGPL许可证发行的自由软件也是GNU计划的关键部分。GCC特别是其中的C语言编译器通常被认为是跨平台编译器的事实标准。GCC可处理C/C、Fortran、Pascal、Objective-C、Java、Ada等多种语言。1.1.1、使用官方镜像将C/C代码运行在容器内的最简方法就是将编译指令写入Dockerfile中然后使用此Dockerfile构建自定义镜像最后直接运行此镜像即可启动程序。如果对GCC版本有要求则可以在以上命令中加入镜像标签并在下一步Dockerfile的FROM指令中明确GCC版本号。然后在Dockerfile中加入需要执行的GCC编译命令FROM gcc:4.9 COPY.usr/src/myapp WORKDIR /usr/src/myapp RUN gcc-omyapp main.c CMD[./myapp]编辑main.c内容如下#includestdio.hintmain(){printf(Hello World\n);return0;}现在就可以使用Dockerfile来构建镜像my-gcc-appdockerbuild-tgcc-image.用户可以使用docker images命令查看生成的镜像$dockerimages i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA gcc-image:latest 0ff8c88cbf541.37GB 0B创建并运行此容器会编译并运行程序输出Hello World语句$dockerrun-it--rm--namegcc-container gcc-image Hello World如果只需要容器编译程序而不需要运行它则可以使用如下命令dockerrun--rm-v$(pwd):/usr/src/myapp-w/usr/src/myapp gcc gcc-omyapp1.1.2、定制镜像下面笔者给出了基于buildpack-deps:wheezy镜像创建GCC镜像的Dockerfile供读者参考1.2、LLVMLLVMLow Level Virtual Machine底层虚拟机是美国伊利诺伊大学的一个研究项目试图提供一个现代化的基于SSA的编译策略同时支持静态和动态编程语言。和之前为大家所熟知的JVM以及.net Runtime这样的虚拟机不同这个虚拟系统提供了一套中立的中间代码和编译基础设施并围绕这些设施提供了一套全新的编译策略使得优化能够在编译、连接、运行环境执行过程中以及安装之后以有效的方式进行和其他一些非常有意思的功能。LLVM包括若干重要的子项目其中Clang将在后面讲解。1.2.1、使用官方镜像Docker Hub中已经有用户提供了LLVM镜像读者可以直接下载使用不再赘述1.2.2、定制镜像读者可以基于前面提到的SSHD基础镜像来定制GCC镜像构建后直接运行。也可以使用Docker Hub中提供的第三方Dockerfile定制或修改后构建镜像然后运行容器即可。1.3、ClangClang是一个由Apple公司用C实现、基于LLVM的C/C/Objective-C/Objective-C编译器其目标就是超越GCC成为标准的C/C编译器它遵循LLVM BSD许可。Clang很好地兼容了GCC。Clang的特性包括以下几点。快在OSX上的测试中Clang比GCC 4.0快2.5倍。内存占用小Clang内存占用一般比GCC要小得多。诊断信息可读性强Clang对于错误的语法不但有源码提示还会在错误的调用和相关上下文上有更好的提示。基于库的模块化设计Clang将编译过程分成彼此分离的几个阶段将大大增强了IDE对于代码的操控能力。1.3.1、使用官方镜像在Docker Hub中已经有用户提供了Clang的镜像读者可以直接下载使用读者可以通过Docker Hub的镜像详情查看实际安装指令确认是否符合需求如下所示1.3.2、定制镜像如前文所说读者可以基于SSHD镜像自定义Dockerfile也可以使用Docker Hub中的第三方镜像构建Clang容器。这里以ubuntu:bionic系统为例给出了示例Dockerfile文件1.3.3、相关资源GCC官网https://gcc.gnu.org/。GCC官方镜像https://hub.docker.com/_/gcc/。GCC官方镜像仓库https://github.com/docker-library/gcc。LLVM官网http://llvm.org/。2、JavaJava是广受欢迎的编程语言和开发平台有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今Java仍是企业和开发人员的首选开发平台全球有数百万开发人员运行超过60亿台Java虚拟机。Java是一种跨平台、面向对象、泛型编程的编译型语言广泛应用于企业级应用开发和移动应用开发领域由SUN公司在1995年推出。Java是基于类的面向对象的高级语言其设计理念是尽可能减少部署依赖致力于允许Java应用的开发者“开发一次到处运行”。这就意味着Java的二进制编码不需要再次编译即可运行在异构的JVM上。Java在大型互联网项目特别是互联网金融和电子商务项目中非常受欢迎。OpenJDK(Open Java Development Kit)是免费开源的Java平台支持Java SE(Standard Edition)。从Java7开始OpenJDK就是官方的Java SE环境。2.1、使用官方镜像在容器中运行Java代码最简单的方法就是将Java编译指令直接写入Dockerfile。然后使用此Dockerfile构建并运行此镜像即可启动程序。首先从官方仓库获取某版本Java基础镜像dockerpull eclipse-temurin:8-jdk然后在本地新建一个空目录在其中创建Dockerfile文件。在Dockerfile中加入需要执行的Java编译命令例如FROM eclipse-temurin:8-jdk COPY./usr/src/javaapp WORKDIR /usr/src/javaapp RUN javac HelloWorld.java CMD[java,HelloWorld]publicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.println(Hello World!);}}如果希望使用最新的Java 10则可以修改基础镜像为FROM eclipse-temurin:10-jdk。下面继续使用此Dockerfile构建镜像java-imagedockerbuild-tjava-image.用户可以通过docker images命令查看生成的镜像$dockerimages i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA eclipse-temurin:8-jdk 1f884d67c72d 314MB 0B然后运行此镜像即自动编译程序并执行$dockerrun-it--rm--namejava-container java-image Hello World!如果只需要在容器中编译Java程序而不需要运行则可以使用如下命令dockerrun--rm-v$(pwd):/usr/src/javaapp-w/usr/src/javaapp eclipse-temurin:8-jdk javac HelloWorld.java以上命令会将当前目录(“$(pwd)”)挂载为容器的工作目录并执行javac HelloWorld.java命令编译HelloWorld.java代码然后生成HelloWorld.class类文件至当前目录下$lsDockerfile HelloWorld.class HelloWorld.java2.2、Spring BootSpring Boot是由Pivotal团队开发的框架其设计目的是简化新Spring应用的初始搭建以及开发过程。SpringBoot致力于在蓬勃发展的快速应用开发领域成为领导者旨在简化创建产品级的Spring应用和服务。Spring Boot是一个基于Spring框架的快速开发的框架可以用来创建独立、可运行的、生产级别的Spring应用程序。使用Spring Boot可以大大简化Spring应用程序的开发过程通过自动配置Spring和第三方库减少了大量烦琐的配 置从而让开发人员更加专注于业务代码的编写。下图显示了Spring Boot在Spring生态中的位置。Spring Boot的特性包括创建独立的Spring应用。内嵌Tomcat、Jetty或Undertow无须部署WAR文件。提供starter POM简化Maven配置。尽可能地实现Spring项目配置自动化。提供工业级特性如Metrics、健康检查等。不生成代码不需要XML配置。使用compose搭建Spring Boot应用下面介绍如何使用compose搭建Spring Boot应用环境要求是JDK 1.8或以上版本Maven 3.0或以上版本。下面创建一个Spring Boot应用。第一步先下载并解压Spring Boot应用模板代码然后编辑代码文件’src/main/java/hello/Application.java’内容如下SpringBootApplication和RestController表示Java类Application已经准备好被Spring MVC调用并提供HTTP服务。注解RequestMapping(“/”)表示context path/的请求路由到方法home中进行处理main方法中的 SpringApplication.run()用来启动一个Spring Boot应用。第二步容器化spring boot应用。首先新建src/main/docker/Dockerfile内容如下然后使用docker-maven-plugin构建镜像pom.xml文件内容如下此处镜像的名称为registry.aliyuncs.com/linhuatest/gs-spring-boot-docker其中registry.aliyuncs.com是阿里云镜像仓库的域名linhuatest是用户的命名空间gs-spring-boot-docker是用户某个仓库的名称此处没有镜像tag默认为latestDockerfile文件所在的目录可以理解为Dockerfile的context用于保存Dockerfile依赖的资源要将资源复制到Dockerfile文件所在的目录即context中用户只需要编译出jar文件。最后用户可以构建和推送镜像到任何一个镜像仓库如下所示2.3、相关资源Java官方镜像https://registry.hub.docker.com/_/java/。Java官方镜像标签https://registry.hub.docker.com/_/java/tags/manage/。Spring Boot官网http://projects.spring.io/spring-boot/。3、PythonPython是一种解释型动态语言是功能强大的面向对象语言集成了模块(module)、异常处理(exception)、动态类型(dynamic typing)、高级数据结构元组、列表、序列、类(class)等高级特性。Python设计精良语法简约表达能力很强。目前所有主流操作系统Windows、Linux、类UNIX系统都支持Python。3.1、使用官方镜像首先推荐用户使用Docker官方提供的Python镜像作为基础镜像。第一步新建项目目录py-official进入此目录然后使用docker pull命令拉取官方镜像dockerpull python接下来在项目中新建一个Dockerfile文件内容如下FROM python COPY./usr/src/py WORKDIR /usr/src/py CMD[python,./sample.py]新建sample.py文件计算Fibonacci数列deffib(n):a,b0,1whilean:print(a,end )a,bb,abprint()fib(1000)新建requirements.txt依赖文件读者可以在此文件中加入项目依赖程序如Django等。此处仅新建空文件touchrequirements.txt第二步使用docker build命令构建名为py3-image的镜像dockerbuild-tpy3-image.可见至此用户已经成功构建了镜像可以通过dockerimages命令进行查看$dockerimages i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA py3-image:latest 111c004ee5b21.12GB 0B第三步通过docker [container] run命令创建并运行容器$dockerrun-it--rm--namepy3-container py3-image01123581321345589144233377610987如果只需要运行单个Python脚本那么无须使用Dockerfile构建自定义镜像而是通过以下命令直接使用官方Python镜像带参数运行容器dockerrun-it--rm--namemy-running-script-v$(pwd):/usr/src/myapp-w/usr/src/myapp python:3 python your-daemon-or-script.py如果读者希望深入了解Python的官方镜像包括镜像的原始Dockerfile、ONBUILD指令的具体执行内容等则可以参考GitHub上的docker-library/official-images仓库。3.2、使用PyPyPyPy是一个Python实现的Python解释器和即时编译(JIT)工具它专注于速度、效率和CPython的完全兼容性。通过JIT技术PyPy可以使Python的运行速度提高近十倍同时保证兼容性。使用官方镜像首先设置项目目录并新建hi.py实例程序然后在根目录新建Dockerfile其内容基于pypy3的onbuild版本镜像如果用户需要使用pypy2则可以使用FROM pypy:2-onbuild。onbuild版本的镜像内含若干onbuild触发器它们可以在镜像构建期间完成一些必要的初始化操作便于项目直接运行。pypy的onbuild镜像会复制一个requirements.txt依赖文件运行RUN pip install安装依赖程序然后将当前目录复制到/usr/src/app。下面用户开始构建和运行此镜像如果用户只需要运行单个pypy脚本并希望避免新建Dockerfile那么可以直接使用如下指令如果需要使用pypy2运行则可以使用如下指令3.3、使用DjangoDjango是一个开放源代码的Web应用框架是基于Python实现的流行的Web框架之一于2005年7月在BSD许可证下发布。Django采用了MVC模型、视图、控制器的经典软件设计模式主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django注重组件的重用性和可插拔性以及敏捷开发和DRY(Don’t Repeat Yourself)法则。相比Tornado、Flask、Web.py等框架Django要“重”一些但它自带了很多工具包包括认证系统、站点管理系统、评论系统等便于进行中小型站点的快速开发。3.3.1、使用Django镜像在本地可通过pip安装Django十分简单下面创建一个容器镜像。第一步新建项目目录django-official新建一个名为dockerdjango的Django项目新建Dockerfile文件内容如下使用onbuild标签意味着在执行docker build命令的过程中docker engine会执行ONBUILD命令中的操作。具体的ONBUILD命令可以在GitHub上的docker-library仓库中看到即第二步新建requirements.txt文件内容为Django第三步使用docker build命令构建此Django镜像可见Django镜像构建成功并生成相应的镜像。下面用户可以使用docker[container]run命令运行此镜像并得到相应的容器ID使用docker ps命令可见Django容器已暴露8000端口但是没有绑定访问端口再次使用docker ps命令可见Django容器不仅暴露8000端口还映射到了本地端口32768第四步通过浏览器访问主机的32768端口来访问此Django服务如图所示。还可以通过docker logs django-container命令查看日志。还可以使用docker[container]run的entrypoint进入容器执行更多操作3.3.2、使用Compose搭建Django应用Compose是一个定义和运行服务多容器应用的官方工具。用户可以通过一个Compose配置文件定义服务然后使用up命令创建并启动服务。关于Compose的详细讲解可参阅本书第四部分相关章节。首先安装docker-compose下面用户使用Docker Compose来配置和运行一个简单的Django/PostgreSQL应用。第一步用户需要创建一个Dockerfile一个Python依赖文件还有一个docker-compose.yml文件。新建一个项目文件夹例如命名为djangocompose并在其根目录新建一个Dockerfile文件文件内容如下在项目文件夹的根目录新建一个requirements.txt文件文件内容如下注意psycopg2是Python与PostgreSQL的数据库连接池。最后在项目文件夹的根目录新建一个docker-compose.yml文件内容如下第二步新建一个Django项目在其中用docker-compose命令新建一个Django项目第三步配置Django的数据库连接。进入项目文件夹编辑djangocompose/settings.py文件。设置DATABASES…字段运行docker-compose up命令此时用户的Django应用已经开始运行了访问容器的8000端口即可看到运行效果如图所示。下面用户可以登录容器查看此Django应用的运行状态。首先使用docker ps查看当前主机运行的容器可见Web服务的容器ID是eb078d59a780用户可以使用docker exec命令登录到容器的bash环境中3.3.3、使用Docker Hub镜像DjangouWSGINginx的技术组合拥有优异的性能也是常用的Django Web技术栈。下面用户使用Docker Hub上的dockerfiles/django-uwsgi-nginx镜像构建Django应用。首先使用docker pull命令获取镜像然后使用build命令构建名为django-uwsgi-nginx-image的Django镜像用户可以使用docker images查看镜像信息然后构建并运行django-uwsgi-nginx-image镜像这里的-d参数表示后台运行容器并打印出容器ID。用户可以使用docker ps-a查看所有容器3.3.4、自定义uWSGINginxDjango镜像用户也可以通过本地编译自定义uWSGINginxDjango镜像。首先新建Dockerfile文件内容如下然后在Dockerfile同级目录下新建app文件夹内含requirements.txt文件文件内容如下然后新建Nginx配置文件django.conf内容如下新建run.sh文件内容如下新建supervisord.conf文件内容如下新建uwsgi.ini文件内容如下新建uwsgi_params文件内容如下下面用户可以使用docker create构建镜像使用dockerpush将镜像提交至仓库然后用户可以登录到生产环境使用docker pull从仓库拉取此镜像最后运行此镜像目前容器内的默认卷地址是/opt/django/app读者可以挂载特定的应用卷例如至此用户可以成功地在NginxuWSGI环境下运行Django应用了。3.4、使用FlaskFlask是一个使用Python编写的轻量级Web应用框架该框架基于Werkzeug WSGI工具箱和Jinja2模板引擎。Flask使用BSD授权也被称为microframework因为它仅仅使用简单的核心使用extension来增加其他功能。Flask的特色内置开发用服务器和debugger。支持集成单元测试(unit testing)。支持RESTful请求调度。支持使用Jinja2模板引擎。支持Secure Cookies客户端sEssion。与WSGI 1.0 100%兼容。基于Unicode。有详细的文件、教学手册。与Google App Engine兼容。可用Extensions增加其他功能。Flask是目前广受欢迎的常用Python Web方案之一。3.4.1、使用Docker Hub镜像第一步项目准备工作。构建Flask App目录run.py内容如下__init.py_内容如下第二步获取Docker Hub的Flask镜像第三步创建并运行Flask容器Flask的App代码作为Docker数据卷3.4.2、使用Compose构建FlaskMongoDB服务MongoDB是一个基于分布式文件存储的数据库旨在为Web应用提供可扩展的高性能数据存储解决方案。MongoDB是介于关系数据库和非关系数据库之间的产品是非关系数据库当中功能最丰富最像关系数据库的。将Flask与MongoDB结合使用是一种简单高效的Web服务架构可以以较高的性能支撑图片服务等各种常见Web服务。第一步新建mongo-flask项目文件夹并新建Flask框架的核心文件app.py内容如下第二步新建templates文件夹放置Flask框架的前端模板文件index.html内容如下第三步回到项目根目录新建requirements.txt文件内容如下第四步新建Dockerfile文件内容如下第五步新建docker-compose.yml文件内容如下3.5、使用SentrySentry是一个实时的事件日志和聚合平台基于Django构建。Sentry可以将Python程序的所有异常自动记录下来然后在一个好用的UI上呈现和搜索。处理异常是每个程序的必要部分所以Sentry是Python后端系统常用的组件。使用Docker Hub镜像为了使用Sentry服务用户需要按照以下步骤操作1)启动一个功能完整的Sentry实例2)配置初始化用户3)配置环境变量。启动一个功能完整的Sentry实例的步骤如下。首先启动一个Redis容器之后启动一个Postgres容器最后生成一个新的密钥供所有Sentry容器使用。SENTRY_SECRET_KEY环境变量即此密钥如果用户需要升级可以使用以下命令现在用户可以启动Sentry服务默认配置需要一个Celery Beat任务调度器和CeleryWorker执行具体任务的工作进程用户可以按需启动相应数量的Worker工作进程每个Worker独占名称。启动Celery Beat和Celery Worker此时用户可以通过docker ps命令查看当前运行的容器用户可以使用标准的容器端口映射在运行docker[container]run命令时添加-p 8080:9000参数然后打开浏览器输入http://localhost:8080或http://host-ip:8080即可访问Sentry服务。关于用Sentry配置初始化用户以及环境变量可以参考Sentry官方镜像文档。3.6、相关资源Python官网https://www.python.org/。Python Dockerfilehttps://github.com/docker-library/python/。Python官方镜像https://registry.hub.docker.com/_/python/。PyPy官网http://pypy.org/。Django官网https://www.djangoproject.com/。Flask官网http://flask.pocoo.org/。uwsgi官方仓库https://github.com/unbit/uwsgi。Sentry官网https://getsentry.com/welcome/。4、JavaScriptJavaScript(JS)是主流浏览器上支持的脚本语言这也是早期JavaScript的唯一用途。Node.js自2009年发布使用Google Chrome浏览器的V8引擎。Node.js的出现让服务端应用也可以基于JavaScript进行编写。它采用事件驱动性能优异同时还提供了很多系统级API如文件操作、Socket、HTTP网络编程等支持主流操作系统。Node.js应用通过非驻塞IO和异步事件将系统吞吐能力和效率最大化。4.1、使用Node.jsNode.js是基于Chrome V8引擎的JavaScript运行时环境可用于构建服务端应用程序。Node.js具有以下优点。高性能Node.js采用事件驱动、非阻塞I/O模型能够处理大量并发连接提高Web应用程序的响应速度和吞吐量。跨平台Node.js可在Windows、Linux、macOS等多个操作系统上运行具有很好的跨平台兼容性。易于学习和使用Node.js的API简单易用语法与前端JavaScript类似容易上手学习。强大的社区支持Node.js拥有庞大的社区有很多优秀的第三方模块和工具可供使用且社区活跃度高。可扩展性强Node.js的模块化开发方式和NPM包管理工具使得应用程序的开发和维护更加容易可扩展性强。同构渲染Node.js可用于实现前后端同构渲染提高Web应用程序的性能和SEO效果。适用于实时通信Node.js的Socket.IO库可用于构建实时通信应用程序如聊天室、游戏等。4.1.1、使用官方镜像可以通过docker run命令直接使用官方镜像dockerrun-itnode:latestbashroot7bfbcc718209:/# node --versionv26.11.1Node.js拥有3种官方镜像node:version、node:version-alpine、node:version-slim。其中常用的是带有版本标签的以及带有onbuild标签的Node镜像。首先在Node.js项目中新建一个DockerfileFROMnodeCOPY./usr/src/node WORKDIR /usr/src/node EXPOSE8888然后新建server.js文件内容如下use strict;varconnectrequire(connect);varserveStaticrequire(serve-static);varappconnect();app.user(/,serveStatic(.,{index:[index.html]}));app.listen(8080);console.log(MyApp is ready at http://localhost:8080);之后通过npm init命令来新建Node项目必需的package.json文件下面使用docker build命令构建Node镜像用户可以通过docker images命令查看已创建的Node镜像此时可以使用浏览器查看到MyApp应用的服务页面。首先使用docker ps命令查看端口绑定情况也可以使用curl命令访问访问效果如图所示。如果出现无法访问等问题可以使用entrypoint参数进入容器进行操作如果需要使用netstat等网络工具可以在容器内使用以下命令进行安装如果需要查看容器日志可以使用docker log命令如果只需要运行单个Node脚本的容器则无须通过Dockerfile构建镜像可以使用以下指令也可以参考Node官方提供的最佳实践https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md。4.1.2、使用alpine精简版Node镜像随着Docker官方提供基于alpine精简系统的各类镜像这种平均大小只有10MB的镜像可以方便地应用于各种开发测试或生产环境中。读者可以在Node官方镜像页面查找所需版本并使用docker run命令直接运行进入Node环境。若需查看官方镜像对应的Dockerfile则可以进入Node的GitHub官方仓库nodejs/docker-node/20/alpine3.17/Dockerfile查看。4.2、相关资源JavaScript入门http://www.w3schools.com/js/。Node.js官网http://www.nodejs.org/。Node.js官方镜像https://hub.docker.com/_/node。