11、Docker快速部署LNMP网站平台

一、Docker概述

1、Docker是什么?

使用最广泛的开源容器引擎
一种操作系统级的虚拟化技术
依赖于Linux内核特性:Namespace(资源隔离)和Cgroups(资源限制)
一个简单的应用程序打包工具

2、Docker基本组成

Docker Client:客户端
Ddocker Daemon:守护进程
Docker Images:镜像
Docker Container:容器
Docker Registry:镜像仓库


Docker基本组成

二、Docker安装

1、Docker版本

社区版(Community Edition,CE)
企业版(Enterprise Edition,EE)

2、支持平台

Linux(CentOS,Debian,Fedora,Oracle Linux,RHEL,SUSE和Ubuntu)
Mac
Windows

3、MAC系统安装Docker

macOS 使用 Homebrew 安装 Docker Desktop CE
系统要求:系统最低为 macOS Sierra 10.12。
安装命令:

$ brew cask install docker
$ docker --version

官方文档:https://docs.docker.com

三、镜像管理

1、镜像是什么

• 一个分层存储的文件
• 一个软件的环境
• 一个镜像可以创建N个容器
• 一种标准化的交付
镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history <ID/NAME> 查看镜像中各层内容及大小,每层 对应着Dockerfile中的一条指令。Docker镜像默认存储在/var/lib/docker/<storage-driver>中。

镜像从哪里来?
Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。 地址:https://hub.docker.com/explore

配置镜像加速器:
右键点击桌面顶栏的 docker 图标,选择 Preferences ,在 Daemon 标签(Docker 17.03 之前版本为 Advanced 标签)下的 Registry mirrors 列表中将

https://yp7fjc4v.mirror.aliyuncs.com加到"registry-mirrors"的数组里,点击 Apply & Restart按钮,等待Docker重启并应用配置的镜像加速器。

2、镜像与容器联系

镜像与容器的联系

如图,容器其实是在镜像的最上面加了一层读写层,改动运行容器里的文件时, 会先从镜像里要写的文件复制到容器自己的文件系统中(读写层)。 如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作的,并不会修改镜像的源文件,这种方式提高磁盘利用率。 若想持久化这些改动,可以通过docker commit 将容器保存成一个新镜像。

3、管理镜像常用命令

查看docker 命令的用法:docker --help
查看管理镜像常用命令image 的用法:docker image --help

指令 描述
ls 列出镜像
build 构建镜像来自Dockerfile
history 查看镜像历史
inspect 显示一个或多个镜像详细信息
pull 从镜像仓库拉取镜像
push 推送一个镜像到镜像仓库
rm 移除一个或多个镜像
prune 移除未使用的镜像。没有被标记或被任何容器引用的
tag 创建一个引用源镜像标记目标镜像
export 导出容器文件系统到tar归档文件
import 导入容器文件系统tar归档文件创建镜像
save 保存一个或多个镜像到一个tar归档文件
load 加载镜像来自tar归档或标准输入

四、容器管理

1、创建容器常用选项

# docker container --help

选项 描述
-i, –interactive 交互式
-t, –tty 分配一个伪终端
-d, –detach 运行容器到后台
-e, –env 设置环境变量
-p, –publish list 发布容器端口到主机
-P, –publish-all 发布容器所有EXPOSE的端口到宿主机随机端口
–name string 指定容器名称
-h, –hostname 设置容器主机名
–ip string 指定容器IP,只能用于自定义网络
–network 连接容器到一个网络
–mount mount 将文件系统附加到容器
-v, –volume list 绑定挂载一个卷
–restart string 容器退出时重启策略,默认no,可选值:[always/on-failure]

2、容器资源限制

选项 描述
-m,–memory 容器可以使用的最大内存量
–memory-swap 允许交换到磁盘的内存量
–memory-swappiness=<0-100> 容器使用SWAP分区交换的百分比(0-100,默认为-1)
–oom-kill-disable 禁用OOM Killer
–cpus 可以使用的CPU数量
–cpuset-cpus 限制容器使用特定的CPU核心,如(0-3, 0,1)
–cpu-shares CPU共享(相对权重)

3、管理容器常用命令

选项 描述
ls 列出容器
inspect 查看一个或多个容器详细信息
exec 在运行容器中执行命令
commit 创建一个新镜像来自一个容器
cp 拷贝文件/文件夹到一个容器
logs 获取一个容器日志
port 列出或指定容器端口映射
top 显示一个容器运行的进程
stats 显示容器资源使用统计
stop/start 停止/启动一个或多个容器
rm 删除一个或多个容器
update 表更资源的更新

五、管理容器里应用程序数据

Docker提供三种方式将数据从宿主机挂载到容器中:


数据从宿主机挂载到容器

• volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
• bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。
• tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用 tmpfs,同时避免写入容器可写层提高性能。

1、Volume

管理卷:

# docker volume create nginx-vol 
# docker volume ls
# docker volume inspect nginx-vol 

用卷创建一个容器:
# docker run -d --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx 

清理:

# docker stop nginx-test
# docker rm nginx-test
# docker volume rm nginx-vol

注意:

  1. 如果没有指定卷,自动创建。

2、Bind Mounts

用卷创建一个容器:

$ mkdir -p $(pwd)/apps/wwwroot
$ docker run -d -it --name=nginx-test --mount type=bind,src=$(pwd)/apps/wwwroot,dst=/usr/share/nginx/html nginx 

验证绑定:

$ docker inspect nginx-test

清理:

$ docker stop nginx-test 
$ docker rm nginx-test

注意:

  1. 如果源文件/目录没有存在,不会自动创建,会抛出一个错误。
  2. 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。

六、容器网络

网络模式

• bridge
–net=bridge 默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
• 自定义网络 与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名或者主机名容器之间网络通信。
• host –net=host
容器不会获得一个独立的network namespace,而是与宿主机共用一个。这就意味着容器不会有自己的网卡信息,而是使用宿主
机的。容器除了网络,其他都是隔离的。
• none
–net=none
获取独立的network namespace,但不为容器进行任何网络配置,需要我们手动配置。
• container
–net=container:Name/ID
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。

七、Dockerfile

1. Dockerfile格式

从上往下执行:

FROM centos:latest
MAINTAINER liuzhousheng
RUN yum install gcc -y
COPY run.sh /usr/bin
EXPOSE 80
CMD [“run.sh”]

2. Dockerfile指令

指令 描述
FROM 构建新镜像是基于哪个镜像
MAINTAINER 镜像维护者姓名或邮箱地址
RUN 构建镜像时运行的Shell命令
COPY 拷贝文件或目录到镜像中
ENV 设置环境变量
USER 为RUN、CMD和ENTRYPOINT执行命令指定运行用户
EXPOSE 声明容器运行的服务端口
HEALTHCHECK 容器中服务健康检查
WORKDIR 为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录
ENTRYPOINT 运行容器时执行,如果有多个ENTRYPOINT指令,最后一个生效
CMD 运行容器时执行,如果有多个CMD指令,最后一个生效

3. Build镜像

Usage: docker build [OPTIONS] PATH | URL | - [flags] Options:
-t, --tag list # 镜像名称
-f, --file string # 指定Dockerfile文件位置
# docker build .
# docker build -t shykes/myapp .
# docker build -t shykes/myapp -f /path/Dockerfile /path
# docker build -t shykes/myapp http://www.example.com/Dockerfile

4. 构建Nginx,PHP基础镜像

• 构建Nginx基础镜像
FROM centos:7
MAINTAINER liuzhousheng
RUN yum install -y gcc gcc-c++ make \
    openssl-devel pcre-devel gd-devel \
    iproute net-tools telnet wget curl && \
    yum clean all && \
    rm -rf /var/cache/yum/*
RUN wget http://nginx.org/download/nginx-1.15.5.tar.gz && \
    tar zxf nginx-1.15.5.tar.gz && \
    cd nginx-1.15.5 &&\
    ./configure --prefix=/usr/local/nginx \
    --with-http_ssl_module \
    --with-http_stub_status_module && \
    make -j 4 && make install && \
    rm -rf /usr/local/nginx/html/* && \
    echo "ok" >> /usr/local/nginx/html/status.html && \
    cd / && rm -rf nginx-1.12.2* && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ENV PATH $PATH:/usr/local/nginx/sbin
#COPY nginx.conf /usr/local/nginx/conf/nginx.conf  ## 先注释这行,不然构建需要依赖本地配置文件,启动启动容器会依赖php
WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

运行命令:

# docker build -t nginx:v1 -f dockerfile-nginx .
# docker image ls
# docker run -d --name nginx01 -p 88:80 nginx:v1
# docker ps -l
# curl 10.40.6.165:88/status.html

用刚刚创建的nginx:v1 镜像在创建一个v2镜像

# cat index.html   ## 将这文件作为nginx root目录
hello docker!!!

# cat  dockerfile-nginxv2   ##  新的dockerfile
FROM nginx:v1
COPY index.html /usr/local/nginx/html/

# docker build -t nginx:v2 -f dockerfile-nginxv2 .   ## 创建nginx:v2镜像
Sending build context to Docker daemon  410.1kB
Step 1/2 : FROM nginx:v1
 ---> db3cfa07d4a5
Step 2/2 : COPY index.html /usr/local/nginx/html
 ---> 64f743ec5b18
Successfully built 64f743ec5b18
Successfully tagged nginx:v2

# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v2                  64f743ec5b18        27 seconds ago      395MB
nginx               v1                  db3cfa07d4a5        11 minutes ago      395MB

# docker run -d --name nginx02 -p 89:80 nginx:v2
c446b345b73ac6417d7090b5d46c7be574b87be152ad7c9f42886e86e43f4d06
# curl 10.40.6.165:89
hello docker!!!

• 构建PHP基础镜像

FROM centos:7
MAINTAINER liuzhousheng
RUN yum install epel-release -y && \
    yum install -y gcc gcc-c++ make gd-devel libxml2-devel \
    libcurl-devel libjpeg-devel libpng-devel openssl-devel \
    libmcrypt-devel libxslt-devel libtidy-devel autoconf \
    iproute net-tools telnet wget curl && \
    yum clean all && \
    rm -rf /var/cache/yum/*

RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \
    tar zxf php-5.6.36.tar.gz && \
    cd php-5.6.36 && \
    ./configure --prefix=/usr/local/php \
    --with-config-file-path=/usr/local/php/etc \
    --enable-fpm --enable-opcache \
    --with-mysql --with-mysqli --with-pdo-mysql \
    --with-openssl --with-zlib --with-curl --with-gd \
    --with-jpeg-dir --with-png-dir --with-freetype-dir \
    --enable-mbstring --with-mcrypt --enable-hash && \
    make -j 4 && make install && \
    cp php.ini-production /usr/local/php/etc/php.ini && \
    cp sapi/fpm/php-fpm.conf /usr/local/php/etc/php-fpm.conf && \
    sed -i "90a \daemonize = no" /usr/local/php/etc/php-fpm.conf && \
    mkdir /usr/local/php/log && \
    cd / && rm -rf php* && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ENV PATH $PATH:/usr/local/php/sbin:/usr/local/php/bin
COPY php.ini /usr/local/php/etc/
COPY php-fpm.conf /usr/local/php/etc/
WORKDIR /usr/local/php
EXPOSE 9000
CMD ["php-fpm"]

运行命令构建:

# docker build -t php:v1 -f dockerfile-php .
# docker image ls
# docker run -d --name php01 php:v1
# docker ps -l

八、快速搭建LNMP网站平台

LNMP

lnmp 架构要用到三个容器,所以要准备相应的三个镜像:
php: php:v1(上边我们自己制作的镜像)
nginx: nginx:v1(上边我们自己制作的镜像)
mysql: mysql:5.7(使用官方镜像)

# docker pull mysql:5.7

(1)、自定义网络

# docker network create net-lnmp

(2)、创建Mysql容器

$ mkdir -p /Users/liuzhousheng/docker/data/mysql
$ docker run -d --name lnmp_mysql --net net-lnmp --mount type=bind,src=/Users/liuzhousheng/docker/data/mysql,dst=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress mysql:5.7 --character-set-server=utf8

(3)、创建PHP容器

$ mkdir -p ~/apps/wwwroot
$ docker run -d --name lnmp_php --net net-lnmp --mount type=bind,src=/Users/liuzhousheng/apps/wwwroot,dst=/wwwroot php:v1

(4)、创建Nginx容器
nginx.conf配置文件:

user                 nobody;
worker_processes     4;
worker_rlimit_nofile 65535;

error_log  logs/error.log  notice;

pid        /var/run/nginx.pid;

events {
    use epoll;
    worker_connections  4096;
}

http {

    include       mime.types;
    default_type  application/octet-stream;

    log_format  main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log off;
    keepalive_timeout  65;

    client_max_body_size         64m;
    server {
        listen 80;
        server_name www.lnmp_test.com;
        index index.php index.html;

        access_log logs/www.lnmp_test.com_access.log;
        error_log logs/www.lnmp_test.com_error.log;

        # location ~ .*\.(js|css|html|png|gif|jpg|jpeg)$ {
        location / {
            root /wwwroot;
        }

        location ~* \.php$ {
            root /wwwroot;
            fastcgi_pass lnmp_php:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
}

启动容器:

$ mkdir -p /Users/liuzhousheng/apps/logs/wordpress/nginx
$ docker run -d --name lnmp_nginx --net net-lnmp -p 88:80 --mount type=bind,src=$(pwd)/nginx.conf,dst=/usr/local/nginx/conf/nginx.conf --mount type=bind,src=/Users/liuzhousheng/apps/wwwroot,dst=/wwwroot --mount type=bind,src=/Users/liuzhousheng/apps/logs/wordpress/nginx,dst=/usr/local/nginx/logs nginx:v1

查看三个容器:

# docker ps 

创建php测试页:

$cat ~/apps/wwwroot/test.php
<?php
    phpinfo()
?>

## 浏览器请求URL:http://10.40.6.165:88/test.php

(5)、以wordpress博客为例
https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz

# cd ~/apps/wwwroot
# wget https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz
# tar xvf wordpress-4.9.4-zh_CN.tar.gz

使用浏览器访问 http://10.40.6.165:88/wordpress

进入容器 lnmp_nginx查看nginx访问日志:

# docker exec -it lnmp_nginx bash
[root@f8c38e7b7a95 nginx]# tail -f logs/www.lnmp_test.com_access.log
10.19.1.28 - - [15/May/2019:17:13:42 +0800] "POST /wordpress/wp-admin/admin-ajax.php HTTP/1.1" 200 58 "http://10.40.6.165:88/wordpress/wp-admin/edit.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36"
10.19.1.28 - - [15/May/2019:17:13:43 +0800] "GET /wordpress/wp-includes/js/wp-emoji-release.min.js?ver=4.9.10 HTTP/1.1" 304 0 "http://10.40.6.165:88/wordpress/wp-admin/edit.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36"
10.19.1.28 - - [15/May/2019:17:13:43 +0800] "GET /wordpress/wp-admin/edit.php HTTP/1.1" 200 48058 "http://10.40.6.165:88/wordpress/wp-admin/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36"
10.19.1.28 - - [15/May/2019:17:13:43 +0800] "POST /wordpress/wp-admin/admin-ajax.php HTTP/1.1" 200 58 "http://10.40.6.165:88/wordpress/wp-admin/edit.php" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,646评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,979评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,391评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,356评论 0 215
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,740评论 3 293
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,836评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,022评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,764评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,487评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,728评论 2 252
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,200评论 1 263
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,548评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,217评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,134评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,921评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,919评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,766评论 2 274

推荐阅读更多精彩内容

  • 一、Docker 简介 Docker 两个主要部件:Docker: 开源的容器虚拟化平台Docker Hub: 用...
    R_X阅读 4,346评论 0 27
  • Docker容器技术已经发展了好些年,在很多项目都有应用,线上运行也很稳定。整理了部分Docker的学习笔记以及新...
    __七把刀__阅读 11,340评论 0 59
  • Docker 的体系结构 docker 使用 C/S 架构,docker daemon 作为 server 端接受...
    凤落溪凰落地阅读 1,425评论 0 2
  • 从买会员到目前过去了五分钟,毫不掩饰的说,作为一个写文章小白,我后悔了。 可刚刚为什么买会员呢?因为一种很...
    琰么乎阅读 164评论 2 1
  • 撒切尔夫人说:请注意你的习惯,因为他能塑造你的性格,请注意你的性格,因为他能决定你的命运。 还记得以前有个故事,一...
    夏日凉风_5752阅读 131评论 0 0