作者归档:admin

使用Docker Compose管理Docker容器

上一篇创建了一个PHP的运行环境,现在需要一个MySQL服务,直接运行:

root@thinkpad:~# docker run --name rocket-mysql -v /home/rocketfish/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

就自动下载并得到一个mysql版本为5.7的服务镜像。
这时候,要运行一个Web服务我们需要运行两次的docker run才可以,如果还有更多的Web容器或其他的服务容器呢?
Docker官方提倡一个容器仅提供一个服务,多个服务/容器可以使用docker-compose来管理。
docker-compose本身是一个Python写的工具,可以直接通过pip安装:

root@thinkpad:~# sudo pip install --upgrade pip

如果你本地并没有Python环境,也可以采用docker-compose的docker镜像来运行:

root@thinkpad:/home/compose-web# curl -L https://github.com/docker/compose/releases/download/1.8.0/run.sh > /usr/local/bin/docker-compose
root@thinkpad:/home/compose-web# docker-compose --version
#开始下载镜像,建议用第一种

查看帮助

root@thinkpad:~# docker-compose -h
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name (default: directory name)
  --verbose                   Show more output
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the name specified
                              in the client certificate (for example if your docker host
                              is an IP address)

Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pulls service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

这些命令包括了创建/启动/停止/暂停/继续运行容器。
首先要创建docker-compose.yml,这是一个YAML格式的文档

mkdir docker
cd docker
mkdir web
mkdir db
vim docker-compose.yml

内容如下:

version: '2'
services:
  db:
    image: mysql:5.7
    ports:
    - "3306:3306"
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: web
      MYSQL_USER: root
      MYSQL_PASSWORD: rootweb
    volumes:
    - ./db/data:/var/lib/mysql
  web:
    depends_on:
      - db
    image: nginx-php-fpm:phalcon
    ports:
    - "80:80"
    restart: always
    environment:
      WEB_DB_HOST: db:3306
      WEB_DB_PASSWORD: root
    volumes:
    - ./web/html:/var/www/html/
    links:
    - db

这里的environment定义了环境变量,比如host的MAC,就可以在docker容器的系统变量里面得到,各个编程语言都有获取系统环境变量的方法。这些变量也可以组织起来放在文件里面加载进去,参考这里
这里的volumes定义了要映射进容器的文件或文件夹或者数据容器,可以参考这里。注意,多个容器共享同一个目录,会出现写冲突,比如MySQL,多个实例,数据目录需要分开。所以设计好你的程序,哪一部分是需要只读的(可以共享),哪一部分是需要写的;写的部分是否可以放到各自临时目录,或者其他公共服务里面。
运行并查看

root@thinkpad:/home/compose-web# docker-compose up -d
Creating network "composeweb_default" with the default driver
Creating composeweb_db_1
Creating composeweb_web_1
root@thinkpad:/home/compose-web# docker-compose ps
      Name                   Command             State              Ports            
------------------------------------------------------------------------------------
composeweb_db_1    docker-entrypoint.sh mysqld   Up      0.0.0.0:3306->3306/tcp      
composeweb_web_1   /start.sh                     Up      443/tcp, 0.0.0.0:80->80/tcp 
#也可以使用原来的命令
root@thinkpad:/home/compose-web# docker ps
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                         NAMES
efbdaf257748        nginx-php-fpm:phalcon   "/start.sh"              13 seconds ago      Up 11 seconds       0.0.0.0:80->80/tcp, 443/tcp   composeweb_web_1
a6935d20911e        mysql:5.7               "docker-entrypoint.sh"   14 seconds ago      Up 13 seconds       0.0.0.0:3306->3306/tcp        composeweb_db_1

docker-compose up -d ,将会在后台启动并运行所有的容器。
docker-compose仅仅提供了对多个docker服务的管理,仍然可以在这些容器上运行原来的docker命令。检查下web容器的IP:

root@thinkpad:/home/compose-web# docker inspect composeweb_web_1 | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAddress": "172.18.0.3",

然后访问:http://172.18.0.3/ 就可以看到web页面了。
如果想要停止服务,可以用docker-compose stop:

root@thinkpad:/home/compose-web# docker-compose stop db
Stopping composeweb_db_1 ... done
root@thinkpad:/home/compose-web# docker-compose stop web
Stopping composeweb_web_1 ... done

再次启动,得到相同名称的服务:

root@thinkpad:/home/compose-web# docker-compose up -d
Starting composeweb_db_1
Starting composeweb_web_1

各个容器的名称也可以在配置文件里面通过参数container_name来指定。
docker-compose的配置还有很多其他的参数,可以参考这里。比如刚才我们通过docker inspect来查找容器IP,也可以配置成静态IP:

version: '2'

services:
  app:
    image: nginx-php-fpm:phalcon
    networks:
      app_net:
        ipv4_address: 172.18.0.10
        ipv6_address: 2001:3984:3989::10

networks:
  app_net:
    driver: bridge
    driver_opts:
      com.docker.network.enable_ipv6: "true"
    ipam:
      driver: default
      config:
      - subnet: 172.18.0.0/24
        gateway: 172.18.0.1
      - subnet: 2001:3984:3989::/64
        gateway: 2001:3984:3989::1

也可以自定义网络
刚才我们的配置文件里面直接指定了镜像,也可以指定Dockerfile镜像构建,假如Dockerfile在web目录下面:

build:
  context: ./web

或者直接指明Dockerfile:

build:
  context: .
  dockerfile: Dockerfile-alternate

实际上,docker-compose的配置已经覆盖了Dockerfile的配置项,也可以直接用于构建多个docker服务,比如指定运行的命令

command: [/bin/bash]

这里的入口程序,如果不能持续运行的话,运行完成后,docker就会退出。所以如果你需要可以后台运行的docker容器,那么入口程序,就必须保持一个程序在前台运行,不退出,比如运行crontab的镜像,入口程序可以是:

cron && bash

cron这个程序是在后台运行的,如果不配合前台程序bash,容器执行玩cron就会退出了。其他运行crontab的容器,大都是强制一个程序在前台不退出,比如这个

cron && tail -f /var/log/cron.log

这里需要注意一下,通过docker设置的environment values在容器内的cli下面执行时取不到的,比如printenv,使用cron后台运行时取不到外部设置的变量,但是手动执行时又可以。这些外部环境变量只能在ENTRYPOINT或者CMD所执行的shell里面去设置,比如在CMD执行start.sh:

printenv | grep -E "^HOST" > /root/env.conf && cron && bash

Docker compose还可以跟Docker Swarm结合。

参考链接:
Install Docker Compose
Quickstart: Docker Compose and WordPress
YAML 模板文件
Introduction to Docker Compose Tool for Multi-Container Applications
Dockerfile基本结构
How to Get Environment Variables Passed Through docker-compose to the Containers
Access environment variables from crontab into a docker container
How can I access Docker set Environment Variables From a Cron Job
Dockerfile里指定执行命令用ENTRYPOING和用CMD有何不同?
What is the difference between CMD and ENTRYPOINT in a Dockerfile?
Docker difference between run, cmd, entrypoint commands

基于Docker的Nginx + PHP-FPM + Phalcon镜像

上一篇简单介绍了Docker的安装,运行,这一篇来构建一个基于Nginx和PHP-FPM的Phalcon镜像。在官方找了以下,单独的Nginx和PHP镜像更加流行,混合的反倒不是很受欢迎。其实官方并不提倡在一个容器里面运行多个服务,最好是一个容器只对外提供一个服务:一个容器启动时仅仅运行一个命令(其实里面可以包含多个),也方便部署扩展升级。多个服务之间可以使用Docker Compose来管理。但是Docker并不阻止创建包含多个服务器的镜像,为了方便,所以我们仍然可以自己构建。
构建镜像可以有好几种方式,比如基于Alpine Linuxphusion/baseimage-docker构建,或者基于Ubuntu,CentOS等构建,又或者在PHP,Nginx的基础镜像上构建。注意:如果要采用Ubuntu或者CentOS构建,可能需要一些额外的工作,以便保持镜像轻量稳定运行。
这里采用已有的richarvey/nginx-php-fpm来构建,它是一个基于Nginx官方镜像来构建的。
Github上拉取相关文件从Dockerfile构建:

$ sudo git clone https://github.com/ngineered/nginx-php-fpm
$ sudo docker build -t nginx-php-fpm:latest .

关于Dockerfile的相关解释,可以参考这里。当然也可以直接拉取镜像使用

$ sudo docker pull richarvey/nginx-php-fpm
# 也可以直接运行,会自动拉取
#$ sudo docker run -d richarvey/nginx-php-fpm

查看本地的镜像,连单独的nginx也来了:

root@thinkpad:~# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx-php-fpm       latest              4fc9ac9f2945        7 hours ago         228.5 MB
nginx               mainline-alpine     00bc1e841a8f        5 days ago          54.21 MB

这里的mainline-alpine是指基于Alpine Linux构建的。Alpine Linux是一个仅有5M大小的linux系统,采用apk add/search来安装/查找相应软件,有许多镜像都是基于它构建的,官方PHP镜像也有基于它构建的Docker镜像。
然后运行nginx-php-fpm:

root@thinkpad:~# docker run --name web -d richarvey/nginx-php-fpm

docker inspect命令用来查看容器的相关信息,查看下分配的IP:

root@thinkpad:~# docker inspect web | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",

然后在浏览器里面访问:http://172.17.0.2/就可以看到phpinfo的页面。到这里,Nginx + PHP的web容器就已经运行起来了,对应的Nginx和PHP进程可以在宿主机器上直接查看:

root@thinkpad:~# ps aux | grep nginx
root     18167  0.0  0.0  13696  4300 pts/6    S    01:47   0:00 nginx: master process /usr/sbin/nginx
systemd+ 18168  0.0  0.0  14144  1868 pts/6    S    01:47   0:00 nginx: worker process
systemd+ 18169  0.0  0.0  14144  1868 pts/6    S    01:47   0:00 nginx: worker process
systemd+ 18170  0.0  0.0  14144  1868 pts/6    S    01:47   0:00 nginx: worker process
systemd+ 18171  0.0  0.0  14144  1868 pts/6    S    01:47   0:00 nginx: worker process
systemd+ 18172  0.0  0.0  14144  1868 pts/6    S    01:47   0:00 nginx: worker process
root     18190  0.0  0.0  21292  1012 pts/18   S+   01:47   0:00 grep --color=auto nginx
root@thinkpad:~# ps aux | grep php-fpm
root     18166  0.0  0.2 167880 23364 pts/6    S    01:47   0:00 php-fpm: master process (/etc/php5/php-fpm.conf)
systemd+ 18173  0.0  0.1 167880  8620 pts/6    S    01:47   0:00 php-fpm: pool www
systemd+ 18174  0.0  0.1 167880  8620 pts/6    S    01:47   0:00 php-fpm: pool www
systemd+ 18175  0.0  0.1 167880  8620 pts/6    S    01:47   0:00 php-fpm: pool www
root     18192  0.0  0.0  21292  1032 pts/18   S+   01:47   0:00 grep --color=auto php-fpm

接下来要为这个容器添加Phalcon扩展。首先要进入容器里面,使用docker attach命令进入:

root@thinkpad:~# docker attach web



结果在这里等了半天进不去。。。。查看下当前镜像入口程序:

root@thinkpad:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
94176348a939        nginx-php-fpm       "/start.sh"         6 seconds ago       Up 5 seconds        80/tcp, 443/tcp     web

这个容器启动的时候运行的是start.sh这个脚本,这个脚本运行了Supervisor工具。于是重新启动容器,运行/bin/bash

#终止容器运行
root@thinkpad:~# docker stop web
web
#删除容器
root@thinkpad:~# docker rm web
web
#重新运行
root@thinkpad:~# docker run --name web -d -t -i nginx-php-fpm /bin/bash
ea21e10df702644a83ed75930b30c7764a786c4feabdf17cd868f86640137c47
root@thinkpad:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ea21e10df702        nginx-php-fpm       "/bin/bash"         6 seconds ago       Up 5 seconds        80/tcp, 443/tcp     web
root@thinkpad:~# docker attach web
#进来了
bash-4.3# ls
bin       etc       lib       media     proc      run       srv       sys       usr
dev       home      linuxrc   mnt       root      sbin      start.sh  tmp       var

就可以进去了。
先安装编译相关工具包:

bash-4.3# apk --no-cache add php5-dev
bash-4.3# apk --no-cache add gcc
bash-4.3# apk --no-cache add make
bash-4.3# apk --no-cache add autoconf
bash-4.3# apk --no-cache add libc-dev
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz
(1/2) Installing musl-dev (1.1.14-r12)
(2/2) Installing libc-dev (0.7-r0)
OK: 334 MiB in 106 packages

编译安装Phalcon:

bash-4.3# cd /home
bash-4.3# git clone --depth=1 git://github.com/phalcon/cphalcon.git
bash-4.3# cd cphalcon/build
bash-4.3# ./install
bash-4.3# ls -la /usr/lib/php5/modules/ | grep phalcon
-rwxr-xr-x    1 root     root       5045264 Sep 28 17:34 phalcon.so

更改PHP扩展的配置:

bash-4.3# cd /etc/php5/conf.d/
bash-4.3# vi phalcon.ini
#添加以下内容
#extension=phalcon.so

#检查扩展是否加载成功
bash-4.3# php -i | grep phalcon
/etc/php5/conf.d/phalcon.ini,
phalcon
phalcon => enabled
phalcon.db.escape_identifiers => On => On
phalcon.db.force_casting => Off => Off
phalcon.orm.cast_on_hydrate => Off => Off
phalcon.orm.column_renaming => On => On
phalcon.orm.enable_implicit_joins => On => On
phalcon.orm.enable_literals => On => On
phalcon.orm.events => On => On
phalcon.orm.exception_on_failed_save => Off => Off
phalcon.orm.ignore_unknown_columns => Off => Off
phalcon.orm.late_state_binding => Off => Off
phalcon.orm.not_null_validations => On => On
phalcon.orm.virtual_foreign_keys => On => On
OLDPWD => /home/cphalcon/build
_SERVER["OLDPWD"] => /home/cphalcon/build
_ENV["OLDPWD"] => /home/cphalcon/build

加载成功了,需要保持本次镜像变更。首先退出容器:

bash-4.3# cd /home
#删除各种不必要的东西,比如gcc
bash-4.3# rm -rf cphalcon/
bash-4.3# exit
exit

然后查看版本并提交变更:

root@thinkpad:~# docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
ea21e10df702        nginx-php-fpm       "/bin/bash"         31 minutes ago      Exited (0) 6 seconds ago                       web
root@thinkpad:~# docker commit ea2 nginx-php-fpm:phalcon
sha256:bb388df328ecc33fac02dba69759d5c992a145f650a0e5b20ca29a4b122fa933

docker commit命令可以用来提交变更,ea2是container id的前三位,也可以写全;然后跟的是要提交的镜像。这里提交到phalcon这个标签下,以便与原来的区分开。查看所有镜像,发现有两个不同的标签:

root@thinkpad:~# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx-php-fpm       phalcon             bb388df328ec        11 seconds ago      364.4 MB
nginx-php-fpm       latest              4fc9ac9f2945        4 hours ago         228.5 MB

采用新镜像来运行,这里要讲程序运行入口改回/start.sh,以便能正常启动Nginx和PHP-FPM:

root@thinkpad:~# docker rm web
web
root@thinkpad:~# docker run --name web -d -t -i nginx-php-fpm:phalcon /start.sh
deecb19467cda2676b24248e3f55970a2481255c6022a80ffbf5087792ccb559
root@thinkpad:~# docker ps
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES
deecb19467cd        nginx-php-fpm:phalcon   "/start.sh"         4 seconds ago       Up 3 seconds        80/tcp, 443/tcp     web

入口程序改变了,需要再提交一次变更:

root@thinkpad:~# docker stop web
web
root@thinkpad:~# docker ps -l
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS                       PORTS               NAMES
c7600e62733d        nginx-php-fpm:phalcon   "/start.sh"         34 seconds ago      Exited (137) 8 seconds ago                       web
root@thinkpad:~# docker commit c76 nginx-php-fpm:phalcon
sha256:1c97ee169a551dd8441f42b40beafd102c71f3e887e2317dc11ce0ef136ceaf0

运行最终的镜像:

root@thinkpad:~# docker rm web
web
root@thinkpad:~# docker run --name web -d -t -i nginx-php-fpm:phalcon
cb5b0c9e55913a538539e46c53ac7905b21def84a05eb00ef81c4b500853576c
root@thinkpad:~# docker ps
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES
cb5b0c9e5591        nginx-php-fpm:phalcon   "/start.sh"         4 seconds ago       Up 3 seconds        80/tcp, 443/tcp     web

访问http://172.17.0.2/,便可以在页面找到phalcon扩展。
通常我们会将程序和数据分开,挂载外部文件目录到容器里面去:

root@thinkpad:~# docker stop web
web
root@thinkpad:~# docker rm web
web
root@thinkpad:~# docker run --name web -d -t -i -v /home/docker/nginx-php-fpm/src:/var/www/html/ nginx-php-fpm:phalcon
ffd64793fe8e7a2a95b68f514e221b7ec3b6cadfe668c016f55a7bb6d48bc702

-v参数可以用来挂载目录或者文件,可以又多个-v参数。
刚才容器里面做的那些已经添加到Dockerfile里面去,你直接使用它来构建。
至此Nginx + PHP-FPM + Phalcon镜像构建完成,介绍绍了如何进入容器,提交变更,网络访问和文件挂载。

参考链接:
A minimal Ubuntu base image modified for Docker-friendliness
eboraas/phalcon
基于Docker的PHP开发环境
Docker for PHP Developers
Docker在PHP项目开发环境中的应用
使用 Supervisor 来管理进程
PHP C扩展框架Phalcon
Alpine Linux,一个只有5M的Docker镜像

Ubuntu 16.04 上安装Docker

Docker是一个轻量级的虚拟化容器技术,既可以为不同应用程序提供了隔离空间(内存,资源,网络),又可以将应用程序与环境一起打包,发布到其他机器上,避免环境的差异,这点像Vagrant。 但是,它又与传统的虚拟机不容(如VirtualBox),它的应用程序仍然是跑在宿主机上面的,并且镜像里面通常仅包含所必须的组件而非完整的系统,因此拥有极高的性能。这又有点像Python的Virtual Environment,不过Docker更加强大,本质是是个Linux,可以打包的不同语言的应用程序。
Docker要求linux内核版本大于3.10,可以在通过以下命令查看是否支持

$ uname -r
4.4.0-38-generic

需要先更新以下apt仓库

$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates
$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
[/sell]
检查以下是否已经创建Docker软件仓库文件,如果没有需要手动创建,并添加以下内容

root@thinkpad:~# cat /etc/apt/sources.list.d/docker.list
deb https://apt.dockerproject.org/repo ubuntu-xenial main
[/sell]
确认是否配置成功

root@thinkpad:~# sudo apt-get update
root@thinkpad:~# apt-cache policy docker-engine
docker-engine:
  Installed: 1.12.1-0~xenial
  Candidate: 1.12.1-0~xenial
  Version table:
 *** 1.12.1-0~xenial 500
        500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages
        100 /var/lib/dpkg/status
     1.12.0-0~xenial 500
        500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages
     1.11.2-0~xenial 500
        500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages
     1.11.1-0~xenial 500
        500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages
     1.11.0-0~xenial 500
        500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages

Docker容器建立在Auf文件系统之上,以便支持将不同的目录挂载到同一虚拟文件系统下面,并设置不同的读写权限。需要安装linux-image-extra:

$ sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
[/sell]
现在可以开始安装Docker了:

$ sudo apt-get install docker-engine
$ sudo service docker start

试运行一下:

root@thinkpad:~# docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

如果你本地没有hello-world这个镜像,它是会自动去Docker官网上下载的。
查看最近运行过的容器,不加参数-l,是查看正在运行的容器

root@thinkpad:~# docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
1931765938dc        hello-world         "/hello"            4 minutes ago       Exited (0) 4 minutes ago                       suspicious_lichterman

运行镜像的时候也可以指定名称(而不是suspicious_lichterman)

root@thinkpad:~# docker run --name hello hello-world

Hello from Docker!
...

root@thinkpad:~# docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
e4773606e6cf        hello-world         "/hello"            7 seconds ago       Exited (0) 6 seconds ago                       hello

但是再次运行同样名称为hello的容器时会报错

root@thinkpad:~# docker run --name hello hello-world
docker: Error response from daemon: Conflict. The name "/hello" is already in use by container e4773606e6cf4222b786d5301ab38e4dddb90e11a0358f64d33109bf829f0b5a. You have to remove (or rename) that container to be able to reuse that name..
See 'docker run --help'.

这时候需要先把旧的给删掉,再运行就不会了

root@thinkpad:~# docker rm hello
hello

通过Docker stop停止运行指定容器。
查看本地的Docker镜像

root@thinkpad:~# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx-php-fpm       phalcon             1c97ee169a55        3 hours ago         364.5 MB
nginx-php-fpm       latest              4fc9ac9f2945        7 hours ago         228.5 MB
ubuntu              16.04               c73a085dc378        47 hours ago        127.1 MB
ubuntu              latest              c73a085dc378        47 hours ago        127.1 MB
nginx               mainline-alpine     00bc1e841a8f        5 days ago          54.21 MB
mysql               5.7                 4b3b6b994512        5 weeks ago         384.5 MB
hello-world         latest              c54a2cc56cbb        12 weeks ago        1.848 kB

这里先简单的介绍Docker的安装、运行,后续将介绍Docker命令行交互,网络,文件存储等。

参考链接:
Docker Overview
Docker:利用Linux容器实现可移植的应用部署
Installation
on Ubuntu

Docker:具备一致性的自动化软件部署
Docker — 从入门到实践
Docker简介与入门
剖析Docker文件系统:Aufs与Devicemapper
What is the runtime performance cost of a Docker container
Docker – The Linux Container
当流浪者(Vagrant)遇见码头工人(Docker): 实战

Centos 6.4 安装 Python 2.7

终于又开始学Python了,不过这次是在Centos 6.4 上面,也碰到了好多问题。Centos6.4
并不能通过yum安装Python 2.7,系统自带的yum等使用的都是Python2.6.6,将系统的Python软链接指向2.7版本会有各种问题,包括依赖库等等;或者只能创建新的可执行命令,如Python27。最终按照这篇文章的介绍成功安装了Python2.7。
首先安装相关的工具,要不然等下编译Python会报各种各样的错:

$sudo yum groupinstall "Development tools"
$sudo yum install zlib-devel
$sudo yum install bzip2-devel
$sudo yum install openssl-devel
$sudo yum install ncurses-devel
$sudo yum install sqlite-devel

然后下载Python并安装,注意这里是make altinstall而不是make install,参考这里

$ wget https://www.python.org/ftp/python/2.7.11/Python-2.7.11.tar.xz
$ tar xf Python-2.7.11.tar.xz
$ cd Python-2.7.11
$ ./configure --prefix=/usr/local
$ sudo make 
$ sudo make altinstall

检查一下是不是安装到了/usr/local/bin/python2.7下面去了,后面Python 2.7相关的库也将安装到这里

$ ls -ltr /usr/local/bin/python*

检查一下Python2.6是不是还在/usr/bin/下面

$ ls -ltr /usr/bin/python*

检查一下系统路径变量PATH,保证/usr/local/bin在/usr/bin之前,然后将Python的软链接指向2.7。

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
$ ln -s /usr/local/bin/python2.7 /usr/local/bin/python

这样子普通用户登录的时候就可以使用Python2.7了,而root用户(sudo)仍然使用Python2.6,yum等才不会出错。

$ which python
/usr/local/bin/python
$ python -V
Python 2.7.11

$ sudo -s
which python
#/usr/bin/python
python -V
#Python 2.6.6
exit

安装Python 2.7的包管理工具

$ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py
$ sudo /usr/local/bin/python2.7 ez_setup.py
$ sudo /usr/local/bin/easy_install-2.7 pip

检查一下是不是对了

$ which pip
/usr/local/bin/pip

$ which easy_install
/usr/local/bin/easy_install

在普通用户下面操作使用easy_install 就是安装到Python2.7的目录下面去了

$ easy_install requests

这时候会报错,因为相关的Python 2.7目录并没有写的权限

$ sudo chmod 664 /usr/local/bin

或者

sudo /usr/local/bin/easy_install-2.7 requests

注意:如果是在root用户或者sudo命令下,使用的仍然是Python 2.6,所以必须要指明使用那个版本的easy_install。
接下来就可以愉快的使用pip安装Python2.7相关的库了。

参考链接:
Installing python 2.7 on centos 6.3. Follow this sequence exactly for centos machine only
How To Set Up Python 2.7.6 and 3.3.3 on CentOS 6.4
How to install Python 2.7 and Python 3.3 on CentOS 6
Centos 6.4 python 2.6 升级到 2.7
CENTOS 6.5 安装 Python 2.7 总结
Difference in details between “make install” and “make altinstall”
Common Python Tools: Using virtualenv, Installing with Pip, and Managing Packages