Docker 学习笔记 - 使用 LaraDock 搭建 PHP 开发环境

一、简介

LaraDock 致力于简化创建开发环境过程,能够帮助我们在 Docker 上快速搭建 PHP 开发环境。 它预装了 Docker 镜像,为我们提供了一站式的开发环境,而不需要再去在本地机器安装 PHP、Nginx、MySQL 以及其他任何开发过程中需要的软件。

相关资料:

LaraDock 官网:http://laradock.io
LaraDock Github:https://github.com/LaraDock/laradock

二、安装

请确保已安装Docker,LaraDock 镜像的原理先不介绍,直接进入安装步骤。

1. 建立工作目录

新建 webroot 目录,laradock 和项目的代码都将放在该目录下(也可以直接使用以前的 web 根目录):

$ mkdir webroot

2. 克隆 LaraDock 代码

进入 webroot 目录,执行以下命令:

$ git clone https://github.com/Laradock/laradock.git

3. 生成 LaraDock 配置文件

进入 laradock 目录,执行以下命令:

$ cp env-example .env

如需配置 Nginx 端口、Mysql 密码等,均在 .env 文件中设置即可。

4. 开启容器

在 laradock 目录下执行以下命令,可以选择自己需要启动的容器:

$ docker-compose up -d nginx mysql redis

LaraDock 提供了很多容器,可以根据自己的选择启动。具体如下:

nginx, hhvm, php-fpm, mysql, redis, postgres, mariadb, neo4j, mongo, apache2, caddy, memcached, beanstalkd, beanstalkd-console, workspace

5. 访问 web 服务

在浏览器中访问 http://localhost,发现已经可以访问 nginx 服务,只不过报 404 而已。

三、详解

1. 404 解决方法

打开 laradock/nginx/sites/default.conf,发现 root 为 /var/www/public。在不改配置文件的情况下,只需在 webroot 目录下新建 public/index.html 文件, http://localhost即可正常访问。

2. 数据卷

通过 docker-compose.yml 文件可以看到, webroot/ 目录被映射到 workspace 容器内 /var/www 下作为数据卷。

applications:
  image: tianon/true
  volumes:
    - ${APPLICATION}:/var/www       

3. Nginx 配置虚拟主机

laradock/nginx/sites/ 目录下新建 test.conf,内容如下:

server {

    listen 80;
    listen [::]:80;

    server_name test.com;
    root /var/www/test;
    index index.php index.html index.htm;

}

webroot 目录下新建 test/index.php 文件

hosts 文件中做域名映射 127.0.0.1 test.com

停止、构建、重启容器,在 laradock 目录下执行以下命令即可:

$ docker-compose down
$ docker-compose build nginx
$ docker-compose up -d nginx mysql redis

访问 test.com

Docker 学习笔记 - 使用 Dockerfile 创建镜像

一、概念

Dockerfile 是一种文件格式的配置文件,用户可以使用 Dockerfile 来快速创建自己的镜像。

二、示例

Dockerfile 由一行行命令语句组成,并支持以 # 开头的注释行。一般而言,Dockerfile 分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

下面演示基于 ubuntu 镜像创建 nginx 镜像。

1. 准备 Dockerfile 和所需文件

新建目录 nginx,在该目录下新建 index.html 文件,内容为 Hello Docker!;在该目录下新建 Dockerfile 文件,内容如下:

# 基于 ubuntu 镜像
FROM ubuntu

# 维护者是 myl
MAINTAINER myl

# 安装 nginx,并设置默认 index.html 文件
RUN apt-get update
RUN apt-get install -y nginx
COPY index.html /var/www/html

# 指定镜像的默认入口
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

# 暴露 80 端口
EXPOSE 80

2. 生成镜像

在 nginx 目录下执行以下命令生成镜像 yanlongma/nginx

$ docker build -t yanlongma/nginx .
$ docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
yanlongma/nginx                   latest              e79f65bd053f        24 minutes ago      216MB

成功生成镜像后,使用 docker images 即可查看到。

3. 运行镜像

使用 Dockerfile 生成的镜像和其它镜像一样使用,下面使用刚刚生成的 yanlongma/nginx 镜像启动一个容器:

$ docker run -d -p 8080:80 yanlongma/nginx
564e7509ff45416f3c99653dc79403ba4e66fdb4b078ae27de824877429f4cdc
$
$ curl http://localhost:8080
hello docker!

容器启动成功后,访问 http://localhost:8080 即可出现我们设置的 index.html 页面中内容。


本文为博主学习笔记,首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Docker 学习笔记 - 端口映射与容器互联

一、前言

在实际应用中,经常会碰到需要多个服务组件容器共同协作的情况,这往往需要多个容器之间有能够互相访问到对方的服务。

除了通过网络访问外,Docker 还提供了两个很方便的功能来满足服务访问的基本需求:

  1. 端口映射:允许映射容器内应用的服务端口到本地宿主主机;
  2. 容器互联:提供了互联机制实现多个容器间通过容器名来快速访问。

二、端口映射

Docker 端口映射即映射容器内应用的服务端口到本机宿主机器。

当容器中运行一些网络应用,要让外部访问这些应用时,可以通过 -P 或 -p 参数两种方式来指定端口映射。

1. 随机映射

使用 -P 参数时,Docker 会随机映射一个端口到内部容器开放的网络端口,如下开启一个 nginx 服务:

$ docker run -d -P nginx
e93349d539119dc48dc841e117f6388d6afa6a6065b75a5b4aedaf5fb2a051fc
$ 
$ docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
e93349d53911        nginx               "nginx -g 'daemon ..."   11 seconds ago      Up 9 seconds        0.0.0.0:32769->80/tcp   zen_kirch

使用 docker ps 看到,本地主机的 32769 端口被映射到了容器的 80 端口,这时我们通过本机浏览器访问 http://localhost:32769 就会出现 nginx 欢迎页面。

2. 指定端口

使用 -p 参数时,可以指定要映射的端口,并且在一个指定的端口上只可以绑定一个容器。支持的格式有:

  • IP:HostPort:ContainerPort
  • IP:ContainerPort
  • HostPort:ContainerPort

下面开启一个 nginx 服务,将本机 8080 端口映射到容器的 80 端口:

$ docker run -d -p 8080:80 nginx
23e725098712d061a1382f33d6fe54da23ae37597a62f8debdd3731b5f9cc4b9
$ 
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
23e725098712        nginx               "nginx -g 'daemon ..."   8 seconds ago       Up 6 seconds        0.0.0.0:8080->80/tcp    frosty_ptolemy

使用 docker ps 看到,本地主机的 8080 端口被映射到了容器的 80 端口,这时我们通过本机浏览器访问 http://localhost:8080 就会出现 nginx 欢迎页面。

3. 查看映射端口

使用 docker port 命令来查看当前映射的端口配置,也可以查看到绑定的地址。命令格式如下:

$ docker port CONTAINER [PRIVATE_PORT[/PROTO]]

容器有自己的内部网络和 IP 地址,可以使用 docker inspect + 容器ID 获取容器的具体信息。

三、容器互联

容器的互联(linking)是一种让多个容器中应用进行快速交互的方式。它会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不是指定具体的 IP 地址。

下面使用 mysql 和 wordpress 镜像来搭建 wordpress 运行环境,演示容器互联的使用。

1. 自定义容器名

连接系统依据容器的名称来执行。虽然创建容器时系统会默认分配一个名字,但建议自己自定义命名。

首先启动一个 mysql 容器,使用 --name 标记自定义容器名为 db:

$ docker run --name db -d -e MYSQL_ROOT_PASSWORD=123456 mysql:latest
35bd73d4d41370bb5218818f58b7f1b89744728c4cb6317d85634abdb47da461
$ 
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
35bd73d4d413        mysql:latest        "docker-entrypoint..."   11 seconds ago      Up 10 seconds       3306/tcp            db

使用 docker ps 可以看到该容器的 NAMES 为 db。

注:-e MYSQL_ROOT_PASSWORD=123456 是为 mysql 服务设置密码,具体可以查看 mysql 镜像的使用。

2. 容器互联

使用 --link 参数可以让容器之间安全地交互。--link 的参数格式为 --link name:alias,其中 name 是要连接的容器名称,alias 是这个连接的别名。

下面启动一个 wordpress 容器,并将它连接到 db 容器:

$ docker run --name wp --link db:mysql -d -p 8080:80 wordpress:latest
d9ee6660b48f80328d14e7a2a57013e72fa8d88de8524d651e003940563e3090
$ docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
d9ee6660b48f        wordpress:latest    "docker-entrypoint..."   5 seconds ago       Up 4 seconds        0.0.0.0:8080->80/tcp   wp
35bd73d4d413        mysql:latest        "docker-entrypoint..."   18 minutes ago      Up 18 minutes       3306/tcp               db

此时,wp 容器和 db 容器建立了互联关系。

在浏览器中访问 http://localhost:8080/ 会进入 wordpress 安装程序,安装完成后进入容器 db,你会发现数据表确实被写在该容器中。

注:如提示数据库连接错误,先进入 db 容器新建数据库,如默认名为 wordpress。


本文为博主学习笔记,首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Docker 学习笔记 - Docker 数据管理

一、前言

生产环境使用 Docker 的过程中,往往需要对数据进行持久化或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作。

容器中管理数据主要有两种方式:

  1. 数据卷(Data Volumes):容器内数据直接映射到本地主机环境;
  2. 数据卷容器(Data Volumes Containers):使用特定容器维护数据卷;

二、数据卷

数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似 Linux 的 mount 操作。

数据卷可提供很多有用的特性,如下:

  • 数据卷可以在容器之间共享和重用,容器间传递数据将变得高效方便;
  • 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作;
  • 对数据卷的更新不会影响镜像,解耦了应用和数据;
  • 卷会一直存在,直到没有容器使用,可以安全的卸载他。

1. 在容器内创建一个数据卷

使用 docker run 命令时,使用 -v 参数可以在容器内创建一个数据卷。多次使用 -v 标记可以创建多个数据卷。

下面使用 ubuntu 镜像创建一个容器,并创建一个数据卷挂载到容器的 /myvolumes 目录:

$ docker run -it -v /myvolumes ubuntu
root@35ebd0dccc3d:/#
root@35ebd0dccc3d:/# ls 
bin  boot  dev  etc  home  lib  lib64  media  mnt  myvolumes  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

2. 挂载一个主机目录作为数据卷

使用 -v 参数也可以挂载一个本地的已有目录到容器中作为数据卷。这个特性非常适合用于开发,下面演示使用 nginx 镜像创建一个容器运行 nginx 服务并挂载数据卷。

首先通过 nginx 镜像创建一个最基本的服务:

$ docker run --name nginx-server1 -d -p 8081:80 nginx
b3faaf910a6653fc2b2d1c99672a98bdaafd89f07eacf229e355192ee0c1cc16

这时我们通过本机浏览器访问 http://localhost:8081 会出现一个经典的 nginx 欢迎页面,如果想修改页面,只能进入容器修改,显然这并不服务我们的开发习惯。

下面通过 nginx 镜像创建一个服务,并挂载一个本地目录 /html 作为数据卷,html 目录下有一个 index.html 文件,内容为 Hello, Data Volumes !,命令如下:

$ docker run --name nginx-server2 -d -p 8082:80 -v /html:/usr/share/nginx/html nginx
ee9694da5f5364029d60e22f9136991017c76c2f40e7f8742c49173d4cc1905a

这时我们通过本机浏览器访问 http://localhost:8082 就会出现 index.html 页面的内容。修改本机 index.html 中的内容后刷新页面,发现页面的内容也随之改变,显然这更符合开发的需求。

三、数据卷容器

如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门用来提供数据卷供其它容器挂载。

首先创建一个数据卷容器 dbcontainer,并在其中创建一个数据卷挂载到 /dbdata:

$ docker run --name dbcontainer -it -v /dbdata ubuntu
root@af3425b83313:/# 
root@af3425b83313:/# ls 
bin  boot  dbdata  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

然后,其它容器可以使用 --volumes-from 来挂载 dbcontainer 容器中的数据卷,例如创建 web1 和 web2 两个容器,并从 dbcontainer 容器中挂载数据卷:

$ docker run -it --name web1 --volumes-from dbcontainer ubuntu
$ docker run -it --name web2 --volumes-from dbcontainer ubuntu

这时容器 web1 和 web2 都挂载同一个数据卷到相同的 /dbdata 目录。三个容器任何一方在该目录下的写入,其它容器都能看到。


本文为博主学习笔记,首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Docker 学习笔记 - Docker 仓库

一、概念

仓库(Repository)是集中存放镜像的地方,分公共仓库和私有仓库。一个容易与之混淆的概念是注册服务器(Registry)。实际上注册服务器是存放仓库的具体服务器,一个注册服务器上可以有多个仓库,而每个仓库下面可以有多个镜像。

docker-repository.jpg

例如对于仓库地址 hub.docker.com/ubuntu,其中 hub.docker.com 是注册服务器地址,ubuntu 是仓库名。

二、仓库

1. Docker Hub 官方仓库

Dcoker Hub 是 Docker 官网维护的一个公共镜像仓库。

2. 国内镜像市场

国内的镜像市场非常多,比较知名的有下面这些:

阿里云:https://dev.aliyun.com/search.html
时速云:https://hub.tenxcloud.com
网易蜂巢:https://c.163.com
DaoCloud:https://www.daocloud.io

不会翻墙的可以优先考虑使用国内镜像。

3. 搭建本地私有仓库

如果有需要可以选择自己搭建本地私有仓库。


本文为博主学习笔记,首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Docker 学习笔记 - Docker 容器命令汇总

一、概念

容器是 Docker 的另一个核心概念。简单来说,容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层。

如果认为虚拟机是模拟运行的一整套操作系统(包括内核、应用运行态环境和其他系统环境)和跑在上面的应用,那么 Docker 容器就是独立运行的一个(或一组)应用,以及它们必须的运行环境。

下面总结了常用的容器相关命令。

二、查看容器

查看容器信息相关命令,下面会用到:

docker ps        列出所有启动状态的容器
docker ps -a     列出所有容器
docker ps -qa    列出所有容器 ID

三、创建容器

1. 新建容器

使用 docker create 命令新建一个容器,会产生容器 ID,例如:

$ docker create -it ubuntu:latest
ba8bc0e5995e56a76ae0361687316ce6062247752c6754d2b16bc135e306233f

使用 docker create 命令新建的容器处于停止状态,我们可以使用 docker ps -a 查看:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
ba8bc0e5995e        ubuntu:latest       "/bin/bash"         About a minute ago   Created                                 brave_engelbart 

2. 启动容器

使用 docker start 命令来启动一个已经创建的容器,例如启动刚创建的 ubuntu 容器(使用上面产生的容器 ID):

$ docker start ba8b
ba8b

再用 docker ps 查看,可以看到该容器处于启动状态:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ba8bc0e5995e        ubuntu:latest       "/bin/bash"         18 minutes ago      Up 10 minutes                           brave_engelbart

3. 新建并启动容器

使用 docker run 可以直接新建并启动容器:

$ docker run ubuntu:latest /bin/echo 'Hello World'
Hello World

使用 -t 参数将启动一个 bash 终端,允许用户交互:

$ docker run -it ubuntu:latest /bin/bash
root@976214c9686c:/#

有时需要让 Docker 容器在后台以守护态形式运行,可以通过添加 -d 参数来实现。

四、终止容器

使用 docker stop 命令来终止一个运行中的容器。例如终止上面的 ba8b 容器:

$ docker stop ba8b
ba8b

五、进入容器

使用 docker exec 命令可以进入一个启动状态的容器中,例如下面启动 ba8b 容器并进入:

$ docker start ba8b
ba8b
$ docker exec -it ba8b /bin/bash
root@ba8bc0e5995e:/# 

六、删除容器

使用 docker rm 命令可以删除处于终止或退出状态的容器,该命令格式为:

$ docker rm [OPTIONS] CONTAINER [CONTAINER...]

选项为:

-f, --force     强行终止并删除运行中的容器
-l, --link      删除容器的连接
-v, --volumes   删除容器挂载的数据卷

例如强制删除运行中的 ba8b 容器:

$ docker rm -f ba8b
ba8b

七、导出和导入容器

1. 导出容器

使用 docker export 可以导出容器到文件,不管此时容器处于什么状态。

下面导出一个容器 ID 为 fd15 的容器到文件:

$ docker export -o test1.tar fd15

也可以:

$ docker export fd15 > test2.tar

2. 导入容器

导出的文件又可以使用 docker import 命令导入变成镜像,下面将导出的 test1.tar 文件导入到本地镜像库中:

$ docker import test1.tar  yanlongma/ubuntu:20171030

本文为博主学习笔记,首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Docker 学习笔记 - Docker 镜像命令汇总

一、概念

镜像是 Docker 三大核心概念中最为重要的,是运行容器的前提。

Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会尝试先从默认镜像仓库下载(默认使用 Docker hub 公共注册服务器中的仓库),用户也可以通过配置,使用自定义的镜像仓库。

下面总结了常用的镜像相关命令。

二、搜索镜像

docker search 命令可以搜索远端仓库中共享的镜像,默认搜索官方仓库中镜像,命令如下:

$ docker search [OPTIONS] TERM

三、 获取镜像

docker pull 命令如下:

$ docker pull [OPTIONS] NAME[:TAG|@DIGEST]

从 Docker hub 获取一个 ubuntu 镜像

$ docker pull ubuntu:latest

也可以从指定的非官方仓库下载,下面是从网易蜂巢下载 ubuntu 镜像

$ docker pull hub.c.163.com/library/ubuntu:latest

四、查看镜像

1. 使用 images 命令列出镜像

可以看到下面列出了刚刚下载的两个镜像信息。

$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
ubuntu                         latest              ccc7a11d65b1        2 months ago        120MB
hub.c.163.com/library/ubuntu   latest              ccc7a11d65b1        2 months ago        120MB

2. 使用 tag 命令添加镜像标签

为了方便后续工作使用特定的镜像,可以使用 tag 命令来为本地镜像任意添加新的标签。例如为 ubuntu:latest 镜像添加一个 myubuntu:latest 镜像标签:

$ docker tag ubuntu:latest myubuntu:latest

3. 使用 inspect 命令查看详细信息

docker inspect 命令可以获取镜像的详细信息,包括制作者、适用架构、各层的数字摘要等:

$ docker inspect ubuntu:latest

4. 使用 history 命令查看镜像历史

镜像文件由多个层组成,使用 history 命令可以列出各层的创建信息:

$ docker history ubuntu:latest

五、删除镜像

删除镜像使用 docker rmi 命令,格式如下,其中 IMAGE 可以是标签或 Image ID:

$ docker rmi [OPTIONS] IMAGE [IMAGE...]

删除 ubuntu:latest 镜像 :

$ docker rmi ubuntu:latest

注意,当有该镜像创建的容器存在时,镜像文件默认是无法被删除的。可以使用 -f 参数来强制删除一个存在容器依赖的镜像,但并不推荐。正确的做法是,先删除依赖该镜像的所有容器,再来删除镜像。

演示删除存在容器的镜像

使用 ubuntu:latest 镜像创建一个简单的容器来输出一段话:

$ docker run ubuntu:latest echo 'hello'

使用 docker ps -a 命令可以看到本机上存在的所有容器,可以看到后台存在一个基于 ubuntu:latest 镜像创建的且处于退出状态的容器 bbb5ae0d3851:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
bbb5ae0d3851        ubuntu              "echo hello"        22 seconds ago      Exited (0) 21 seconds ago                       unruffled_swartz

如果删除该镜像,Docker 会提示有容器正在运行,无法删除:

$ docker rmi ubuntu:latest
Error response from daemon: conflict: unable to remove repository reference "ubuntu:latest" (must force) - container bbb5ae0d3851 is using its referenced image ccc7a11d65b1

正确的做法是,首先应该删除容器 bbb5ae0d3851,再删除镜像(ubuntu:latest 镜像ID 为 ccc7a11d65b1,此处用镜像ID删除)

$ docker rm bbb5ae0d3851
$ docker rmi ccc7a11d65b1

六、创建镜像

创建镜像的方法主要有三种:

1. 基于已有镜像的容器创建

该方法主要使用 commit 命令,格式如下:

$ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

2. 基于本地模板导入

用户也可以直接从一个操作系统模板文件导入一个镜像,主要使用 import 命令,格式如下:

$ docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

3. 基于 Dockerfile 创建

后面会单独总结

七、存出和载入镜像

1. 存出镜像

导出镜像到本地文件,可以使用 docker save 命令,例如导出本地的 ubuntu:latest 镜像为文件 ubuntu_latest.tar

$ docker save -o ubuntu_latest.tar  ubuntu:latest

之后,用户可以通过 ubuntu_latest.tar 文件将该镜像分享给其他人。

2. 载入镜像

可以使用 docker load 将导出的 tar 文件导入到本地镜像库,例如从文件 ubuntu_latest.tar 导入镜像到本地镜像列表:

$ docker load --input ubuntu_latest.tar 

或:

$ docker load < ubuntu_latest.tar 

八、上传镜像

可以使用 docker push 命令上传镜像到仓库,默认上传到 Docker Hub 官方仓库。

首先需要在 Docker Hub 注册账号,第一次上传需要登录,命令如下:

$ docker login

只能将镜像上传到自己的账号下面,比如我的用户名为 yanlongma,如果想上传本地的 ubuntu:latest 镜像,需要先添加新标签 yanlongma/ubuntu:latest,然后用 docker push 命令上传镜像:

$ docker tag ubuntu:latest yanlongma/ubuntu:latest
$ docker push yanlongma/ubuntu:latest

本文为博主学习笔记,首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Docker 学习笔记 - Docker 核心概念与安装

一、Docker 三大核心概念

Docker 三大核心概念如下,只有理解了这三个核心概念,才能顺利的理解 Docker 容器的整个生命周期。

1. 镜像(Image)

Docker 镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。例如,一个镜像可以包含一个基本的操作系统环境,里面仅安装了 Apache 应用程序(或用户需要的其他软件)。可以把它称为一个 Apache 镜像。

2. 容器(Container)

Docker 容器类似于一个轻量级的沙箱,Docker 利用容器来运行和隔离应用。简单来说,容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层。

3. 仓库(Repository)

Docker 仓库类似于代码仓库,它是 Docker 集中存放镜像文件的场所。

二、安装 Docker

1. 版本选择

Docker 官网 上可以看到,目前 Docker 分 CE 和 EE 两种,每种支持的平台也略有不同,大家可以根据自己的需要进行选择,学习选择 CE 版本即可。详情如下图:

docker-ce-ee.jpg

2. 安装

安装很简单,大家到 Get Docker 页面下载对应平台的安装包安装即可。需要注意的是 macOS 10.10.3 之前版本、windows7和8 需要通过虚拟机方式来支持,下载对应平台的 Docker Toolbox 安装即可。

3. 检测是否安装成功

打开终端,执行 docker version,如出现如下信息则安装成功:

$ docker version
Client:
 Version:      17.09.0-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:40:09 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.09.0-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:45:38 2017
 OS/Arch:      linux/amd64
 Experimental: true

三、相关链接

Docker 官网:https://www.docker.com
Get Docker:https://www.docker.com/get-docker
Docker Toolbox:https://www.docker.com/products/docker-toolbox


本文为博主学习笔记,首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Docker 学习笔记 - Docker 概览

1. 什么是 Docker

Docker 是基于 Go 语言实现的开源容器项目,诞生于2013年年初,最初发起者是 dotCloud 公司。Docker 自开源后受到广泛的关注和讨论,目前已有多个相关项目(包括 Docker 三剑客、Kubernetes 等),逐渐形成了围绕 Docker 容器的生态体系。

由于 Docker 在业界造成的影响力实在太大,dotCloud 公司后来改名为 DockerInc,并专注于 Docker 相关技术和产品的研发。

2. LXC

Docker 最重要的技术基石是 Linux 容器(Linux Containers, LXC)技术。

3. Docker 与传统的虚拟化方式的不同之处

docker-vs-vm.jpg

Docker 容器除了运行其中的应用外,基本不消耗额外的系统资源,保证应用性能的同时,尽量减少系统开销。

传统虚拟机方式运行 N 个不同的应用就要起 N 个不同的虚拟机(每个虚拟机都要单独分配独占的内存、磁盘等资源),而 Docker 只需要启动 N 个隔离的“很薄的”容器,并将应用放进容器内即可。应用获得的是接近原生的运行性能。

4. Docker 容器技术与传统虚拟机的特性比较

特性Docker虚拟机
启动速度秒级分钟级
性能接近原生较弱
内存代价很小较多
硬盘使用一般为MB一般为GB
运行密度单机支持上千个容器一般几十个
隔离性安全隔离完全隔离
迁移性优秀一般

5. 为什么要使用 Docker

Docker 的构想是要实现“Build, Ship and Run Any App, Anywhere”, 既通过对应用的封装、分发、部署、运行生命周期进行管理,达到应用组件“一次封装,到处运行”的目的。这里的应用组件,既可以是一个 Web 应用、一个编译环境,也可以是一套数据库平台服务,甚至是一个操作系统或集群。

至于为什么要使用 Docker ?我觉得用上面这段话回答非常完美,具体的优点不在此赘述。


本文为博主学习笔记,首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

多说评论一次导回 Typecho 本地数据库

一、追忆往昔

第一次接触社交化评论类产品大概是在2012年左右,当时国内知名度较高的有多说、友言等,国际上比较有名的有Disqus,这类产品的优点在此就不多说了。

用过几款产品后,被多说漂亮的页面和体验所吸引,最终爱上了多说。开源的内容管理和博客系统换过很多,但评论只要能用多说,就一定用它。

后来被 typecho 的精简吸引,本人的个人博客系统也从 wp 换到 typecho,评论也一直用的多说。但 typecho 没有像 wp 那样完善的插件管理系统,看不到数据,加上对第三方的不信任(随时停更),所以也没有安装第三方插件;再加上是多说的死忠粉,实不实时同步到本地数据库也没什么大问题。

2017年3月21日,多说官方发布了一条重要通知:“多说即将关闭,将于2017年6月1日正式关停服务”。当时内心感慨万千,本想来个长篇大论感慨一下,奈何文采有限,最后发了一条朋友圈:

”多说“国内社交化评论”No.1“,如今竟然也落得如此下场!不能变现的项目,即使再优秀也难得长久,愿在新的领域里再创辉煌,前程似锦!”

感慨完了,数据还是要拿回来,既然是6月1日正式停止服务,那还是有大把时间可以挥霍的,所以一直也没上心。正好这个五一小长假来临前一天,感冒+高烧找上了门,只能在家闭门养病了(平时也不知道在瞎忙什么...)。

二、主要步骤

关于多说的数据格式和 typecho 表结构在这里就不分析了,主要说说主要步骤。这里是把多说json格式的数据转换成符合 typecho 表关系的 insert 语句,并写入到insert.sql文件中,有了这个文件相信聪明的你就知道该怎么做了!

1. 将多说数据导出

进入多说开发者后台=>工具=>导出数据,选中”包含文章数据“、”包含评论数据“,务必选中两项,然后导出数据,解压后拿到export.json文件备用。

2. PHP 代码如下:

在 export.json 同级目录新建import.php文件,代码如下【下载代码】:

<?php

// 读取 json 文件并转换成 php 数组
$json = file_get_contents("./export.json");
$data = json_decode($json, true);

// 文章数据
$threads = $data['threads'];    
// 评论数据
$posts = $data['posts'];    

// 多说的文章ID(thread_id)与 typecho 的文章ID(cid) 对应关系
$threadIdRelationCid = [];
foreach ($threads as $item) {
    $threadIdRelationCid[$item['thread_id']] = $item['thread_key'];
}

// 假设评论表 coid 小于10001,此处从10001开始自增,请根据实际最大值修改
$coid = 10001;
// 多说的评论ID(post_id) 与 typecho 的评论ID(coid) 对应关系
$postIdRelationCoid = [];
foreach ($posts as $item) {
    $postIdRelationCoid[$item['post_id']] = $coid++;
}

// 拼成多条 insert sql语句
$sql = '';
foreach ($posts as $item) {
    $coid = $postIdRelationCoid[$item['post_id']];
    $cid = $threadIdRelationCid[$item['thread_id']];
    $created = strtotime($item['created_at']);
    $author = $item['author_name'] ?: '';
    $mail = $item['author_email'] ?: '';
    $url = $item['author_url'] ?: '';
    $ip = $item['ip'];
    $text = $item['message'];
    $parent = 0;
    if (is_array($item['parents'])) {
        $parent = $postIdRelationCoid[$item['parents'][0]];
    }

    $sql .= "INSERT INTO `typecho_comments` 
(`coid`, `cid`, `created`, `author`, `authorId`, `ownerId`, `mail`, `url`, `ip`, `agent`, `text`, `type`, `status`, `parent`) VALUES
({$coid}, {$cid}, {$created}, '{$author}', 0, 1, '{$mail}', '{$url}', '{$ip}', NULL, '{$text}', 'comment', 'approved', $parent);\n";
}

// 将 sql 写入文件中
file_put_contents("./insert.sql", $sql);

echo "end \n";

在命令行执行php import.php 或在浏览器中访问import.php文件(推荐使用命令行方式),就会在该文件所在的目录生成一个insert.sql文件。

3. 小问题

部分评论数据里面可能会有 emoji 表情,但是 typecho 表的字符集是 utf8,如果需要保留 emoji 的童鞋把 pre_comments 表的字符集改成 utf8mb4 即可,不需要保留 emoji 表情的将 emoji 表情删掉重导即可。

本博客已切换到 typecho 自带的评论,默认的才是最好的!!!!!如果有和我一样需求的童鞋可以把代码拿去放心使用。

三、反思

不得不说,从产品角度讲,”多说“是一个非常优秀的产品,市场占有率非常高,但从商业角度讲,”多说“又是一个非常失败的案例,其成败都值得深思。

如果您看到了这篇文章,请留下您的思考!^_^


本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma