编程开发,C/C++&Java&Python&JavaScript&Go&PHP&Ruby&Perl&R&Erlang

使用Docker快速部署主流编程语言的开发、编译环境及其常用框架,包括C、C++、Java、Python、JavaScript、Go、PHP、Ruby、Perl、R、Erlang等。

在今后采用编程语言开发和测试时,将再也不用花费大量时间进行环境配置了,只需简单获取容器镜像,即可快速拥有相关的环境。

C/C++

C是一门古老的语言,在1969年由贝尔实验室设计开发,今天仍然是系统领域和高性能计算的主要选择。C语言具有高效、灵活、功能丰富、表达力强和较高的可移植性等特点。C++在C的基础上,支持了数据的抽象与封装、面向对象和泛型编程。功能与性能的平衡使C++成为了目前应用最广泛的系统编程语言之一。

三款流行的C/C++开发工具,GCC、LLVM和Clang。

GCC

GCC(GNU Compiler Collection)是一套由GNU开发的编程语言编译器,是一套以GPL及LGPL许可证所发行的自由软件,也是GNU计划的关键部分。GCC(特别是其中的C语言编译器)通常被认为是跨平台编译器的事实标准。

GCC可处理C/C++,以及Fortran、Pascal、Objective-C、Java、Ada等多种语言。

将C/C++代码运行在容器内的最简方法,就是将编译指令写入Dockerfile中,然后使用此Dockerfile构建自定义镜像,最后直接运行此镜像,即可启动程序。

FROM gcc:4.9
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN gcc -o myapp main.c
CMD ["./myapp"]

编辑main.c,内容如下:

#include
int main()
{
  printf("Hello World\n");
  return 0;
}

现在,就可以使用Dockerfile来构建镜像my-gcc-app:

$ docker build -t gcc-image .

创建并运行此容器,会编译并运行程序,输出Hello World语句。

$ docker run -it --rm --name gcc-container gcc-image

Hello World

如果只需要容器编译程序,而不需要运行它,可以使用如下命令:

$ docker run --rm -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp gcc gcc -o myapp main.c

以上命令会将当前目录("$(pwd)")挂载到容器的/usr/src/myapp目录,并执行gcc -o myapp myapp.c。GCC将会编译myapp.c代码,并将生成的可执行文件输出至/usr/src/myapp文件夹。

LLVM

LLVM(Low Level Virtual Machine)是伊利诺伊大学的一个研究项目,试图提供一个现代化的,基于SSA的编译策略,同时支持静态和动态编程语言。和之前为大家所熟知的JVM以及.net Runtime这样的虚拟机不同,这个虚拟系统提供了一套中立的中间代码和编译基础设施,并围绕这些设施提供了一套全新的编译策略(使得优化能够在编译、连接、运行环境执行过程中,以及安装之后以有效的方式进行)和其他一些非常有意思的功能。

Docker Hub中已经有用户提供了LLVM镜像。

$ docker pull imiell/llvm

Clang

Clang是一个由Apple公司用C++实现、基于LLVM的C/C++/Objective C/Objective C++编译器,其目标就是超越GCC成为标准的C/C++编译器,它遵循LLVM BSD许可。Clang很好地兼容了GCC。

Clang特性包括:

  1. 快:在OSX上的测试中,Clang比GCC 4.0快2.5倍。
  2. 内存占用小:Clang内存占用一般比GCC要小的多。
  3. 诊断信息可读性强:Clang对于错误的语法不但有源码提示,还会在错误的调用和相关上下文上有更好的提示。
  4. 基于库的模块化设计:Clang将编译过程分成彼此分离的几个阶段,将大大增强IDE对于代码的操控能力。

在Docker Hub中已经有用户提供了Clang的镜像:

$ docker pull bowery/clang

Java

Java是一种拥有跨平台、面向对象、泛型编程特点的编译型语言,广泛应用于企业级应用开发和移动应用开发领域,由SUN公司在1995年推出。Java是基于类的面向对象的高级语言,其设计理念是尽可能的减少部署依赖,致力于“开发一次,到处运行”。这就意味着Java的二进制编码不需要再次编译,即可运行在异构的JVM上。Java在大型互联网项目,特别是互联网金融和电子商务项目中非常受欢迎。

在容器中运行Java代码最简单的方法就是将Java编译指令直接写入Dockerfile。然后使用此Dockerfile构建并运行此镜像,即可启动程序。

在本地新建一个空目录,在其中创建Dockerfile文件。在Dockerfile中,加入需要执行的Java编译命令,例如:

FROM java:7
COPY . /usr/src/javaapp
WORKDIR /usr/src/javaapp
RUN javac HelloWorld.java
CMD ["java", "HelloWorld"]

使用此Dockerfile构建镜像java-image:

$ docker build -t java-image .

然后,运行此镜像即自动编译程序并执行:

$ docker run -it --rm --name java-container java-image

Hello, World

如果只需要在容器中编译Java程序,而不需要运行,则可以使用如下命令:

$ docker run --rm -v "$(pwd)":/usr/src/javaapp -w /usr/src/javaapp java:7 javac HelloWorld.java

Python

Python是一种解释型的动态语言,面向对象设计,功能十分强大。它集成了模块(modules)、异常处理(exceptions)、动态类型(dynamic typing)、高级数据结构(元组、列表、序列)、类(classes)等高级特性。Python设计精良,语法简约,表达能力很强。目前,所有主流操作系统(Windows、所有Linux、类Unix系统)都支持Python。

使用官方的Python镜像

推荐用户使用Docker官方提供的Python镜像作为基础镜像。

第一步,创建Dockerfile文件:

新建项目目录py-official,进入此目录,新建一个Dockerfile文件,内容如下:

FROM python:3-onbuild
CMD [ "python3.5", "./py3-sample.py" ]

新建py3-sample.py文件,计算Fibonacci数列:

def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
fib(1000)

新建requirements.txt依赖文件,可以在此文件中加入项目依赖程序,如Django等。此处仅新建空文件。

$ touch requirements.txt

第二步,使用docker build命令构建名为py2.7-sample-app的镜像:

$ docker build -t py3-image .

第三步,通过docker run命令创建并运行容器:

$ docker run -it --rm --name py3-container py3-image

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

如果只需要运行单个Python脚本,那么无需使用Dockerfile构建自定义镜像,而是通过以下命令直接使用官方Python镜像,带参数运行容器:

$ docker run -it --rm --name my-running-script -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp python:3 python your-daemon-or-script.py

使用PyPy

PyPy是一个Python实现的Python解释器和即时编译(JIT)工具,它专注与速度、效率,以及和CPython完全的兼容性。PyPy通过JIT技术可以使得Python运行速度提高近十倍,同时保证兼容性。

首先,设置项目目录,并新建hi.py实例程序:

for animal in ["dog", "cat", "mouse"]:
print "%s is a mammal" % animal

然后,在根目录新建Dockerfile,基于pypy3的onbuild版本镜像:

FROM pypy:3-onbuild
CMD [ "pypy3", "./hi.py" ]

如果用户需要使用pypy2,则可以使用:FROM pypy:2-onbuild。

onbuild版本的镜像内含若干onbuild触发器,它们可以再镜像构建期间完成一些必要的初始化操作,便于项目的直接运行。pypy的onbuild镜像会拷贝一个requirements.txt依赖文件,运行RUN pip install安装依赖程序,然后将当前目录拷贝至/usr/src/app。

下面,用户开始构建和运行此镜像:

$ docker build -t my-python-app .

$ docker run -it --rm --name my-running-app my-python-app

如果用户只需要运行单个pypy脚本,并希望避免新建Dockerfile,那么用户可以直接使用以下指令:

$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp pypy:3 pypy3 your-daemon-or-script.py

如果需要使用pypy2运行,则可以使用如下指令:

$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp pypy:2 pypy your-daemon-or-script.py

JavaScript

JavaScript是目前所有主流浏览器上唯一支持的脚本语言,这也是早期JavaScript的唯一用途。Node.js的出现,让服务端应用也可以基于JavaScript进行编写。

Node.js自2009年发布,使用Google Chrome浏览器的V8引擎,采用事件驱动,性能优异。同时还提供了很多系统级API,如文件操作、网络编程等。

使用Node.js环境

Node.js拥有3种官方镜像:node:、node:onbuild、node:slim。

其中常用的是带有版本标签的,以及带有onbuild标签的node镜像。

首先,在Node.js项目中新建一个Dockerfile:

FROM node:4-onbuild
EXPOSE 8888

然后,新建server.js文件,内容如下:

'use strict';
var connect = require('connect');
var serveStatic = require('serve-static');
var app = connect();
app.use('/', serveStatic('.', {'index': ['index.html']}));
app.listen(8080);
console.log('MyApp is ready at http://localhost:8080');

之后,通过npm init命令来新建node项目所必须的package.json文件:

$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (node) node
version: (1.0.0)
description: node-sample
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/faxi/Docker/js/node/package.json:
{
"name": "node",
"version": "1.0.0",
"description": "node-sample",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this ok? (yes) yes

下面使用docker build指令构建node镜像:

$ docker build -t node-image .

最后,创建并运行node容器:

$ docker run -it -P node-image

npm info it worked if it ends with ok
npm info using npm@2.15.1
npm info using node@v4.4.3
npm info prestart node@1.0.0
npm info start node@1.0.0
> node@1.0.0 start /usr/src/app
> node server.js
MyApp is ready at http://localhost:8080

此时可以使用浏览器查看到MyApp应用的服务页面。

首先,使用docker ps指令查看端口绑定情况:

$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

7b6f666d4808 node-image "npm start" xxxago Up xx 0.0.0.0:32771->8888/tcp node-container

如果只需要运行单个node脚本的容器,则无需通过Dockerfile构建镜像,可以使用以下指令:

$ docker run -it --rm --name my-running-script -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp node:0.10 node your-daemon-or-script.js

Go

Go语言(也称Golang)是一个由Google主导研发的编程语言,于2009年推出。它的语法清晰明了,设计精良,拥有一些先进的特性,还有一个庞大的标准库。Go的基本设计理念是:编译效率、运行效率和开发效率要三者兼顾。使用Go开发,既可以得到很多灵活的语法支持,又可以拥有C/C++的运行和编译效率。此外,Go提供了轻量级的协程,支持大规模并发的场景。

搭建并运行Go容器

1.使用官方镜像

运行Go语言环境的最简方法是使用官方golang镜像。可以使用docker run指令直接启动Go语言的交互环境:

$ docker run -it golang /bin/bash

root@79afc2b64b06:/go# go versiongo version go1.7 linux/amd64

还可以将Go编译指令写入Dockerfile中,基于此Dockerfile构建自定义镜像。具体步骤如下。

第一步,新建项目文件夹,并在根目录新建Dockerfile:

FROM golang:1.6-onbuild          
#显示声明基础镜像版本,利于后期维护。onbuild版本Dockerfile的具体内容如下:
FROM golang:1.6 RUN mkdir -p /go/src/app WORKDIR /go/src/app CMD ["go-wrapper", "run"] #通过`go-wrapper`程序执行当前目录下的主函数 ONBUILD COPY . /go/src/app #拷贝当前项目代码至运行目录 ONBUILD RUN go-wrapper download #下载依赖,具体实现参考`go-wrapper`源码 ONBUILD RUN go-wrapper install #安装依赖,具体实现参考`go-wrapper`源码 # `go-wrapper`源码地址:`https://github.com/docker-library/golang/blob/master/go-wrapper` # Dockerfile源码地址: `https://github.com/docker-library/golang/blob/master/1.6/onbuild/Dockerfile`

第二步,新建自定义go程序go-sample.go:

package main
import "fmt"
func main() {
fmt.Println("Hello,世界")
}

第三步,使用docker build指令构建镜像:

$ docker build -t golang-image .

最后,使用docker run指令运行Go容器:

$ docker run -it --rm --name golang-container golang-image + exec app

Hello,世界

至此成功运行了Go语言的实例容器。

如果需要在容器中编译Go代码,但是不需要在容器中运行它,那么可以执行如下命令:

$ docker run --rm -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp golang go build -v_/usr/src/myapp

这会将Go项目文件夹作为Docker数据卷挂载起来并作为运行目录。然后,Docker会在工作目录中编译代码,执行go build命令并输出可执行文件至myapp。

2.Go项目容器化

首先,下载Golang官方提供的outyet示例项目:

$ mkdir outyet

$ cd outyet

#使用go get下载:

$ go get github.com/golang/example/outyet

#或者直接使用wget下载:

$ wget https://github.com/golang/example/archive/master.zip

$ unzip master.zip

$ cd example-master/outyet

$ ls

Dockerfile containers.yaml main.go main_test.go

示例项目搭建成功后,可以按照以下模板去自定义项目的Dockerfile:

#使用golang基础镜像。基于Debian系统,安装最新版本的golang环境。工作空间(GOPATH)配置是"/go"
FROM golang
#将本地的包文件拷贝至容器工作目录。
ADD . /go/src/github.com/golang/example/my-go
#在容器中构建my-go。可以在这里手动或者自动(godep)管理依赖关系。
RUN go install github.com/golang/example/my-go
#设定容器自动运行my-go。
ENTRYPOINT /go/bin/my-go-app
#监听8080端口。
EXPOSE 8080

如果使用onbuild版本的基础镜像,那么源文件拷贝、构建与配置等过程就会自动完成,无需在Dockerfile中逐一配置,如下所示:

FROM golang:onbuild
EXPOSE 8080

下面开始构建与运行此Golang项目。在outyet项目根目录执行docker build指令,使用本地目录下的Dockerfile:

$ docker build -t outyet .

构建过程中,Docker会从Docker Hub中获取golang基础镜像,拷贝本地包文件,构建项目并给镜像打上outyet标签。

下面,使用docker run指令运行此镜像:

$ docker run -p 6060:8080 --name test --rm outyet

此时,实例项目的容器已经在运行状态。打开浏览器访问http://localhost:6060/即可看到运行界面。

Beego

Beego是一个使用Go的思维来帮助开发者构建并开发Go应用程序的开源框架。Beego使用Go开发,思路来自于Tornado,路由设计来源于Sinatra。

使用方法如下。

第一步,下载安装:

go get github.com/astaxie/beego

第二步,创建文件hello.go:

package main
import "github.com/astaxie/beego"
func main() {
beego.Run()
}

第三步,编译运行:

go build -o hello hello.go

./hello

第四步,打开浏览器并访问http://localhost:8080。

至此,一个Beego项目成功构建了。

Gogs:基于Go的Git服务

Gogs的目标是打造一个最简单、轻松的方式搭建自助Git服务。使用Go语言开发使得Gogs能够通过独立的二进制分发,并且支持Go语言支持的所有平台,包括Linux、Mac OS X、Windows以及ARM平台。

可以使用docker run直接创建并运行镜像:

$ docker run --rm --name gogs gogs/gogs

如果需要停止此镜像,可以使用docker stop与docker rm指令:

$ docker stop gogs; docker rm gogs

如果需要将数据持久化,可以先新建数据文件夹,然后将其作为数据卷挂载至gogs容器中:

$ mkdir -p /srv/lxc/gogs/data

$ docker run -d --name gogs \ -p 8300:3000 -p 8322:22 -v /srv/lxc/gogs/data:/data gogs/gogs

PHP

PHP(Hypertext Preprocessor,超文本预处理器)是一种通用的开源脚本语言。语法吸收了C、Java和Perl等语言的特点,利于学习,使用广泛,主要适用于Web开发领域。PHP执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执行编译后代码,编译可以达到加密和优化代码运行,使代码运行更快。

1.使用官方镜像

第一步,在PHP项目的根目录中新建一个Dockerfile:

FROM php:5.6-cli
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
CMD [ "php", "./hello.php" ]

新建hello.php文件:

echo "hello php\n"

第二步,运行docker build命令构建镜像:

$ docker build -t php-image .

最后,执行以下命令去运行Docker镜像:

$ docker run -it --rm --name php-container php-image

hello php

2.挂载PHP项目

需要运行简单的,甚至单文件的PHP项目,那么每次都写Dockerfile会很麻烦。

这种情况下,可以用以下命令挂载PHP项目:

$ docker run -it --rm --name my-running-script -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp php:5.6-cli php your-script.php

3.配合Apache使用

通常情况下,PHP项目需要和Apache httpd/Nginx一起运行,这样就需要PHP容器中内含Apache Web Server。

可以使用带有apache标签的镜像,如php:5.6-apache。

第一步,在PHP项目的根目录中新建一个Dockerfile,并使用Docker Hub官方的基础镜像:

FROM php:5.6-apache
COPY src/ /var/www/html/

其中,src/是当前包含所有PHP代码的目录。

第二步,使用此Dockerfile构建自定义镜像:

$ docker build -t my-php-app .

第三步,创建并运行此镜像:

$ docker run -it --rm --name my-running-app my-php-app

建议添一个自定义的php.ini配置文件,将其拷贝到/usr/local/lib。这样可以对PHP项目做更多的定制化,如开启某些PHP插件,或者对PHP解释器进行一些安全/性能相关的配置。

添加方法很简单:

FROM php:5.6-apache
COPY config/php.ini /usr/local/lib/
COPY src/ /var/www/html/

src/是当前存放PHP代码的文件夹,config/文件夹包含php.ini文件。

如果读者希望直接使用官方镜像运行PHP项目,可以执行如下命令:

$ docker run -it --rm --name my-apache-php-app -v "$(pwd)":/var/www/html php:5.6-apache

Ruby

Ruby是一种动态的面向对象的脚本语言,具有支持反射、跨平台、设计精简等特点,在Web应用领域应用颇多。Ruby的设计受到Perl、Smalltalk、Eiffel、Ada和Lisp的影响。Ruby支持多种编程范式,如函数编程、面向对象编程、CLI交互式编程。Ruby还有动态的数据类型系统和自动的内存管理。

使用Ruby官方镜像

首先,在Ruby项目中创建一个Dockerfile:

FROM ruby:2.1.2-onbuild
CMD ["./rb-sample.rb .rb"]

然后,新建rb-sample.rb例子程序:

say = "I love Ruby"
3.times { puts say }

将以上文件放在app的根目录(与Gemfile同级)。

使用的官方镜像带有onbuild标签,意味着包含了启动大部分Ruby项目所需的基本指令。

在构建镜像的时候,Docker会执行COPY./usr/src/app以及RUN bundle install。

然后,构建名为ruby-image的镜像:

$ docker build -t ruby-image .

最后,创建并运行此镜像:

$ docker run -it --name ruby-container ruby-image

由于在构建时使用了带有onbuild标签的镜像,所以在app目录下需要有Gemfile.lock文件。

可以在App的根目录运行以下命令:

$ docker run --rm -v "$(pwd)":/usr/src/app -w /usr/src/app ruby:2.1.2 bundle install --system

如果只需要运行单个的Ruby脚本,那么无需使用Dockerfile构建自定义镜像,而是通过以下命令直接使用官方Ruby镜像,带参数运行容器:

$ docker run -it --rm --name my-running-script -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp ruby:2.1.2 ruby your-daemon-or-script.rb

JRuby

JRuby类似于Python的Jython,它可运行于JVM上并支持Java的接口和类。

第一步,用户在JRuby项目中创建一个Dockerfile:

FROM jruby:.1.7.24-onbuild
CMD ["./jruby-sample.rb"]

第二步,新建Ruby示例代码jruby-sample.rb:

say = "I love JRuby"
3.times { puts say }

将此文件放在app的根目录(与Gemfile同级)。

使用的官方镜像带有onbuild标签,意味着包含了启动大部分JRuby项目所需的基本指令。在构建镜像的时候,会执行COPY./usr/src/app以及RUN bundle install。

第三步,构建自定义镜像:

$ docker build -t jruby-image .

第四步,创建并运行此镜像:

$docker run -it --name jruby-container jruby-image

由于在构建时使用了带有onbuild标签的镜像,所以在app目录下需要有Gemfile.lock文件。这时可以在app的根目录运行以下命令:

$ docker run --rm -v "$(pwd)":/usr/src/app -w /usr/src/app jruby:1.7.15 bundleinstall --system

如果只需要运行单个的JRuby脚本,那么无需使用Dockerfile构建自定义镜像,而是通过以下命令直接使用官方JRuby镜像,带参数运行容器:

$ docker run -it --rm --name my-running-script -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp jruby:1.7.15 jruby your-daemon-or-script.rb

Ruby on Rails

Rails是使用Ruby语言编写的网页程序开发框架,目的是为开发者提供常用组件,简化网页程序的开发。只需编写较少的代码,就能实现其他编程语言或框架难以企及的功能。经验丰富的Rails程序员会发现,Rails让程序开发变得更有乐趣。

1.使用官方镜像

第一步,用户在Rails项目中创建一个Dockerfile,将此文件放在项目根目录(与Gemfile同级)。

Dockerfile内容如下:

FROM rails:onbuild

可见用户使用了onbuild标签,即此基础镜像会自行完成一些基本的构建工作并包含了大部分启动一个Rails项目所需的基本指令。

Dockerfie内容如下:

FROM ruby:2.3
# throw errors if Gemfile has been modified since Gemfile.lock
RUN bundle config --global frozen 1
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ONBUILD COPY Gemfile /usr/src/app/
ONBUILD COPY Gemfile.lock /usr/src/app/
ONBUILD RUN bundle install
ONBUILD COPY . /usr/src/app

第二步,构建自定义镜像:

$ docker build -t rails-image .

第三步,创建并运行此镜像:

$ docker run --name rails-container -d rails-image

此时用户可以使用浏览器访问http://container-ip:3000查看服务,当然,也可以映射到本地主机端口。

$ docker run --name some-rails-app -p 8080:3000 -d my-rails-app

现在可以使用浏览器访问http://localhost:8080或者http://host-ip:8080。

2.使用Compose搭建Rails应用

下面使用Docker Compose来配置和运行一个简单的Rails+PostgreSQL应用。

第一步,确定项目文件夹内容。新建一个名为rails-compose-example的项目文件夹,在其根目录新建一个Dockerfile文件,内容如下:

FROM ruby:2.2.0
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
RUN mkdir /code
WORKDIR /code
ADD Gemfile /code/Gemfile
ADD Gemfile.lock /code/Gemfile.lock
RUN bundle install
ADD . /code

Gemfile内容如下:

source 'https://rubygems.org'

gem 'rails', '4.2.0'

下面用户新建docker-compose.yml文件,内容如下:

version: '2'
services:
db:
image: postgres
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db

第二步,构建Rails项目。可以使用docker-compose run指令构建并启动此Rails项目:

$ docker-compose run web rails new . --force --database=postgresql --skip-bundle

Perl

Perl是一个高级的、动态的解释型脚本语言,它的设计借鉴了C、Shell、awk和sed。Perl最重要的特性是它内部集成了正则表达式的功能,以及巨大的第三方代码库CPAN。Perl像C一样强大,同时像awk、sed等脚本语言一样富有表达性。Perl常见于系统管理和文件处理等程序,Perl多数情况下属于Web方案中的胶水语言。

可以使用Docker官方的Perl镜像作为基础,在此之上进行必要的定制。

第一步,下载官方的Perl镜像:

$ docker pull perl

如果对Perl的版本有要求,可以在以上命令中加入Tag标签,以便于在下一步的Dockerfile的FROM指令中明确Perl版本号。官方镜像都有明确的标签信息。

第二步,在Perl项目中新建Dockerfile:

FROM perl:5.20
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
CMD [ "perl", "./perl-sample.pl" ]

新建perl-sample.pl文件:

#!/usr/bin/perl
print "Hello, World!\n";

第三步,通过此Dockerfile,构建自定义的镜像:

$ docker build -t perl-image .

构建成功后,用户可以通过docker images查看:

$ docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

perl-image latest bc28eba086ad About a minute ago 654.9 MB

最后,创建容器并运行:

$ docker run -it --rm --name perl-container perl-image

Hello, World!

如果只需要运行单个的Perl脚本,那么无需使用Dockerfile构建自定义镜像,而是通过以下命令直接使用官方Perl镜像,带参数运行容器:

$ docker run -it --rm --name perl-container -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp perl:5.20 perl perl-sample.pl

Hello, World!

如果需要运行Perl的Web项目,则最好先自建内置SSH服务的镜像,然后以此为基础定制Perl容器,这样可以方便地通过SSH服务访问Perl容器。

R

R是一个面向统计分析和绘图的语言,是由新西兰奥克兰大学统计学系的Ross Ihaka和Robert Gentleman共同创立。R带有大量的统计软件包,如常见的贝叶斯推断、聚类分析、机器学习、空间统计、稳健统计等,在生物信息、统计学等领域应用广泛。

Rocker项目是一个Docker官方支持的项目,它提供了R语言的容器环境支持。官方提供的r-base镜像就是基于Rocker项目的。

1.运行交互式R语言环境

可以直接运行官方提供的r-base镜像,进入交互模式的R环境:

$ docker run -ti --rm r-base

退出交互命令行时,可以使用quit()指令,此时可以选择是否保存工作空间:

> quit()

Save workspace image? [y/n/c]:

2.运行R语言批量模式

可以通过连接工作目录,来运行R语言的批量指令。把一个卷(volume)连接至容器时,最好使用一个非根用户,这样可以避免权限问题:

$ docker run -ti --rm -v "$PWD":/home/docker -w /home/docker -u docker r-base R

3.运行R语言命令行模式

可以直接进入R容器的bash命令行:

$ docker run -ti --rm r-base bash

root@4a0bba3f4cb4:/#

在bash中如果希望进入R语言交互命令行,可以直接输入R:

root@4a0bba3f4cb4:/bin# R

>

可以使用vim.tiny编辑器,新建r-demo.R脚本:

print("Hello,World!")

保存后,就可以使用Rscript指令运行此脚本:

root@4a0bba3f4cb4:/bin# Rscript demo.R

Rscript demo.R

[1] "Hello,World!"

还可以在R语言交互命令行中运行R脚本。

首先,在容器中新建hi.R脚本:

hello <- function( name ) {
sprintf( "Hello, %s", name );
}

然后直接输入R指令进入交互命令行,使用source()函数加载脚本,再使用hello()函数调用用户的打印逻辑:

> source('/bin/hi.R')
> hello('docker')
[1] "Hello, docker"
>

4.使用自定义容器

在用户将手头的R项目容器化的过程中,往往需要加入自己的环境构建逻辑,也需要运行自定义容器。

这种情况下,用户就需要基于官方提供的r-base基础镜像,完成自定义的Dockerfile,例如:

FROM r-base:latest
COPY . /usr/local/src/r-scripts
WORKDIR /usr/local/src/r-scripts
CMD ["Rscript", "running-r-scripts.R"]

其中running-r-scripts.R内容可以简写为:print("My R Container!")

然后,使用docker build指令构建:

$ docker build -t my-r-container /directry/of/Dockerfile

然后使用docker run指令运行容器,并通过docker ps指令查看运行状态:

$ docker run -d my-r-container

e86739e8226a081372d9bb0fb9f62a32405814b5172a543487b0751839c2e57f

Erlang

Erlang是一种用来构建大规模弹性、实时、高并发、高可用系统的编程语言,被广泛应用于电信、银行、电子商务和即时消息领域。Erlang的运行时系统内置支持并发、分布式和容错机制。Erlang由爱立信所辖的CS-Lab于1987年开发,目的是创造一种可以应对大规模并发活动的编程语言和运行环境。

1.使用官方镜像

可以使用erlang镜像,直接进入Erlang交互命令行Eshell:

$ docker run -it --rm erlang:latest

Erlang/OTP 18 [erts-7.3.1] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.3.1  (abort with ^G)
1> uptime().
3 minutes and 3 seconds
ok
2>

可以使用ctl+G进入任务切换模式,其中j为列出所有任务:

User switch command
--> j
1* {shell,start,[init]}
--> q

$ docker run -it --rm -h erlang.local erlang erl -name allen

Erlang/OTP 18 [erts-7.3.1] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.3.1  (abort with ^G)
(allen)1> erlang:system_info(otp_release).
"18"
(allen)2>
User switch command
--> q

2.直接运行Erlang脚本

可以直接使用docker run指令,通过escript运行Erlang脚本。

下面以斐波那契数列作为例子进行讲解。

首先,新建fab.erl文件:

#!/usr/bin/env escript
%% -*- erlang -*-
main([String]) ->
try
N = list_to_integer(String),
F = fac(N),
io:format("factorial ~w = ~w\n", [N,F])
catch
_:_ ->
usage()
end;
main(_) ->
usage().
usage() ->
io:format("usage: factorial integer\n"),
halt(1).
fac(0) -> 1;
fac(N) -> N * fac(N-1).

保存后,使用docker run指令运行:

$ docker run -it --rm --name erlang-inst1 -v "$PWD":/usr/src/myapp -w /usr/src/myapp erlang escript fab.erl 5

factorial 5 = 120

可见已输出factorial 5=120计算结果。