0%

docker安装lnmp

本文参考docker_practice:https://github.com/yeasy/docker_practice

为什么使用docker?

切换服务器的时候,需要把所有的环境都安装一遍,这样是很麻烦的。在早先的文章中就提到了各种备份方式,最好的方式是在主机上安装一个虚拟机,备份虚拟机就好了。但是早些虚拟主机是全虚拟化,就像vmvare一样,虚拟了一整套硬件资源,是在本地os上面又加了一层虚拟层,比较笨重。docker直接使用本地os,和传统虚拟化以及半虚拟化相比,容器不需要模拟层(emulation layer)和管理层(hypervisor layer),而是使用操作系统的系统调用接口。这降低了运行单个容器所需的开销,也使得宿主机中可以运行更多的容器。

docker安装

这里使用的是ubuntu server 16.04 64位的系统。

1.卸载旧版本
旧版本的 Docker 称为 docker 或者 docker-engine ,使用以下命令卸载旧版本:
apt-get remove docker docker-engine docker.io

2.安装Docker CE
add-apt-repository “deb https://download.docker.com/linux/ubuntu zesty edge”
更新 apt 软件包缓存,并安装 docker-ce :
apt-get update
apt-get install docker-ce -y –allow-unauthenticated
docker -v

3.开机启动
systemctl enable docker
systemctl start docker

4.配置docker镜像服务器(可以不用)
nano /etc/docker/daemon.json
{
“registry-mirrors”: [“https://docker.mirrors.ustc.edu.cn"]
}

5.docker重启

/etc/init.d/docker stop
/etc/init.d/docker start

docker常用命令

1.搜索镜像
docker search 镜像名称

2.列出本地镜像
docker images

3.拉取镜像
docker pull mysql

4.删除镜像
docker rmi $IMAGE_ID #删除指定镜像
docker rmi `docker images -q` #删除所有镜像,这不是单引号

5.保存和恢复镜像
docker save -o /docker/images/nginx.tar nginx #保存nginx镜像到/docker/images/nginx.tar
docker load -i mynginx.tar #从备份文件中恢复镜像

6.运行交互式docker容器
docker run -it –name=ubuntu ubuntu:16.04 /bin/bash
-i:表示运行容器。
-t:表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。
–name :为创建的容器命名。
/bin/bash:指的是容器运行后,启动的交互程序

7.运行守护式docker容器
docker run -id –name=ubuntu ubuntu:16.04 /bin/bash
-d:创建守护式容器在后台运行
登录守护式容器方式:
docker exec -it ubuntu /bin/bash #exit退出时,容器不会停止

8.停止与启动容器
docker stop $CONTAINER_NAME/ID
docker start $CONTAINER_NAME/ID

9.查看docker容器
docker ps -a

10.删除docker容器
docker stop xxx #xxx是容器名字,或者id
docker rm xxx
docker stop docker ps -a -q #停止所有docker容器
docker rm docker ps -a -q

11.docker容器和宿主机拷贝文件
docker cp 容器名称:容器目录 宿主机目录
docker cp 宿主机目录 容器名称:容器目录

12.挂载主机目录到容器
docker run -di -v /usr/local/myhtml:/usr/local/myhtml –name=mycentos centos:7
-v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射。如果主机没有对应文件夹,会自动建立。

docker容器和主机文件共享

1.docker容器和宿主机拷贝文件
docker cp 容器名称:容器目录 宿主机目录
docker cp 宿主机目录 容器名称:容器目录

2.挂载主机目录到容器
docker run -di -v /usr/local/myhtml:/usr/local/myhtml –name=mycentos centos:7
-v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射。

3.创建数据卷
创建一个数据卷
docker volume create my-vol
查看所有的 数据卷
docker volume ls
查看指定 数据卷 的信息
docker volume inspect my-vol
启动一个挂载数据卷的容器
docker run -id –name=web –mount source=my-vol,target=/webapp ubuntu
实验证明和-v参数的作用是一样的,只要两个容器共用同一个数据卷或者主机目录,一个对这个数据卷或主机目录的更改会影响另一个。主机对数据卷或者共享目录的更改,也会立即影响到两个容器。

docker容器之间的通信

方法一:把每个容器的服务地址端口映射到主机的端口上,通过主机端口互相访问。
方法二:通过docker的命令-link name访问。比如nginx容器中fastcgi_pass的值从127.0.0.1:9000改为了phpfpm:9000,这里的phpfpm是域名,在nginx容器的/etc/hosts文件中自动配置为phpfpm容器的访问IP。原理参考docker之间的通信。
方法三:自定义的 Docker 网络来连接多个容器,取代–link 参数。

1
2
3
4
5
6
7
8
9
10
11
先创建一个新的 Docker 网络。
$ docker network create -d bridge my-net
运行一个容器并连接到新建的 my-net 网络
$ docker run -it --rm --name busybox1 --network my-net busybox sh
打开新的终端,再运行一个容器并加入到 my-net 网络
$ docker run -it --rm --name busybox2 --network my-net busybox sh
在 busybox1 容器输入以下命令
/ # ping busybox2
PING busybox2 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.072 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.118 ms

docker部署lnmp思路

a)不能把所有的服务mysql,nginx,php都放到一个docker中,需要每个服务部署一个docker,解耦服务。
b)创建数据卷,用于主机和docker容器的文件通信,这里使用-v参数。
c)docker容器间通信,比如nginx的容器需要访问php的解析服务,php需要访问mysql。这里使用自定义的 Docker 网络来连接多个容器。
d)nginx的docker容器的/usr/share/nginx/html中保存着php文件,映射到了主机上/docker/nginx/data/html目录。同时php-fpm的docker容器的/usr/share/nginx/html也映射到主机中的/docker/nginx/data/html目录。所以nginx容器访问php文件的时候,实际访问的是php容器下的/usr/share/nginx/html,也就是主机中的/docker/nginx/data/html目录。
对应nginx配置文件:nginx.conf

1
2
3
4
5
6
7
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

创建公共网桥

docker network create -d bridge docker-bridge-net

docker部署php-fpm

1.创建相关文件夹
mkdir -p /docker/php/docker-file
mkdir -p /docker/php/conf mkdir -p /docker/php/data mkdir -p /docker/php/logs

2.下载nginx容器
docker pull bitnami/php-fpm

3.配置文件
docker run -id –restart=always –name=php -v /docker/nginx/data/html:/usr/share/nginx/html –network docker-bridge-net bitnami/php-fpm

4.保存镜像
mkdir -p /docker/images
docker save -o /docker/images/bitnami-php-fpm.tar bitnami/php-fpm

docker部署nginx

1.创建相关文件夹
mkdir -p /docker/nginx/docker-file
mkdir -p /docker/nginx/data/html /docker/nginx/logs /docker/nginx/conf /docker/nginx/conf/httpscert
//必须先建立配置文件,docker只会自动建立文件夹
touch /docker/nginx/conf/nginx.conf

#和https相关的文件
touch /docker/nginx/conf/httpscert/www.xxx.com/fullchain.pem
touch /docker/nginx/conf/httpscert/www.xxx.com/privkey.pem
touch /docker/nginx/conf/httpscert/www.xxx.com/dhparam.pem

2.下载nginx容器
docker pull nginx

3.配置文件
nano /docker/nginx/conf/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
user  root;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;


events {
worker_connections 1024;
}


http {
include /etc/nginx/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 /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;

server {
listen 80;
server_name www.xxx.com xxx.com ;
location / {
root /usr/share/nginx/html;
index index.html index.php;
}
}
}

4.运行nginx容器
docker run -id –restart=always –name=nginx
-v /docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro
-v /docker/nginx/conf/httpscert:/etc/nginx/httpscert:ro
-v /docker/nginx/conf/conf.d:/etc/nginx/conf.d
-v /docker/nginx/logs:/var/log/nginx
-v /docker/nginx/data/html:/usr/share/nginx/html
-p 80:80 -p 443:443 –network docker-bridge-net nginx

5.打开防火墙端口
ufw allow 80
ufw allow 443
ufw reload

6.保存镜像
mkdir -p /docker/images
docker save -o /docker/images/nginx.tar nginx

docker部署let’s encrypt

1.安装certbot
pip3 install certbot #不知道为什么这家vps的提供商这样安装会报错,网上的解决方法也不管用。采用下面的方式安装。

#certbot-auto脚本可以创建一个虚拟的python环境,没有这种问题
wget https://dl.eff.org/certbot-auto -O /usr/sbin/certbot-auto
chmod a+x /usr/sbin/certbot-auto
certbot-auto

2.生成证书
certbot-auto certonly –webroot -w /docker/nginx/data/html -d www.xxx.com -m xxx@gmail.com –agree-tos
/docker/nginx/data/html 这个目录是nginx容器映射到宿主机上的目录,验证程序需要在网站目录读写一个文件,来验证这台服务器拥有这个域名。
生成 dhparam.pem 文件
mkdir /etc/ssl/private/ -p
cd /etc/ssl/private/
openssl dhparam 2048 -out dhparam.pem

#复制证书文件到nginx
mkdir -p /docker/nginx/conf/httpscert/www.xxx.com
cp -f /etc/letsencrypt/live/www.xxx.com/fullchain.pem /docker/nginx/conf/httpscert/www.xxx.com/fullchain.pem
cp -f /etc/letsencrypt/live/www.xxx.com/privkey.pem /docker/nginx/conf/httpscert/www.xxx.com/privkey.pem
cp -f /etc/ssl/private/dhparam.pem /docker/nginx/conf/httpscert/www.xxx.com/dhparam.pem
chmod 400 /etc/letsencrypt/live/www.xxx.com/fullchain.pem
chmod 400 /etc/letsencrypt/live/www.xxx.com/privkey.pem
chmod 400 /etc/ssl/private/dhparam.pem
chmod 400 /docker/nginx/conf/httpscert/www.xxx.com/fullchain.pem
chmod 400 /docker/nginx/conf/httpscert/www.xxx.com/privkey.pem
chmod 400 /docker/nginx/conf/httpscert/www.xxx.com/dhparam.pem

3.nginx配置ssl访问
nano /docker/nginx/conf/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#定义Nginx运行的用户和用户组,window下不指定
#user nobody; #默认不写就行
#user nginx nginx;
#docker中的默认配置
user root;

#是否以守护进程的方式运行nginx,守护进程是指脱离终端并且在后头运行的进程,关闭守护进程执行的方式可以让我们方便调试nginx
#docker容器中已经开启了
#daemon on;

#nginx进程数,建议设置为等于CPU总核心数。
#lscpu或者cat /proc/cpuinfo | grep 'processor' | wc -l得到cpu核心数量
worker_processes 1;
#worker_processes auto;

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log warn;

#进程文件,windows 底下可以注释掉
pid /var/run/nginx.pid;

#一个nginx进程打开的最多文件描述符数目,
#理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,
#但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
#现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。
#这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。
worker_rlimit_nofile 65535;

#工作模式与连接数上限
events {
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];
#使用epoll的I/O 模型。linux建议epoll,FreeBSD建议采用kqueue,window下不指定。
#补充说明:
#与apache相类,nginx针对不同的操作系统,有不同的事件模型
#A)标准事件模型
#Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll
#B)高效事件模型
#Kqueue:使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
#Epoll:使用于Linux内核2.6版本及以后的系统。
#/dev/poll:使用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。
#Eventport:使用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。
use epoll;

#单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 65535;

#keepalive超时时间。
#keepalive_timeout 60;

#客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
#分页大小可以用命令getconf PAGESIZE 取得。但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。
#client_header_buffer_size 4k;

#这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
#open_file_cache max=65535 inactive=60s;

#这个是指多长时间检查一次缓存的有效信息。
#open_file_cache_valid 80s;

#open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。
#open_file_cache_min_uses 1;
}

#设定http服务器
http {
include mime.types; #文件扩展名与文件类型映射表

default_type application/octet-stream; #默认文件类型

charset utf-8; #默认编码

#server_names_hash_bucket_size 128; #服务器名字的hash表大小

#client_header_buffer_size 32k; #上传文件大小限制

#large_client_header_buffers 4 64k; #设定请求缓

client_max_body_size 50m; #上传文件最大值

sendfile off; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。

autoindex off; #开启目录列表访问,合适下载服务器,默认关闭。

tcp_nopush on; #防止网络阻塞

tcp_nodelay on; #防止网络阻塞

#keepalive_timeout 120; #长连接超时时间,单位是秒

#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

#gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
gzip_vary on;#跟Squid等缓存服务有关,on的话会在Header里增加"Vary: Accept-Encoding",我不需要这玩意,自己对照情况看着办吧
#limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用

#日志格式设定
#log_format name (自定义日志名称) format(输出选项)
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
#日志格式设置。
#$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
#$remote_user:用来记录客户端用户名称;
#$time_local: 用来记录访问时间与时区;
#$request: 用来记录请求的url与http协议;
#$status: 用来记录请求状态;成功是200,
#$body_bytes_sent :记录发送给客户端文件主体内容大小;
#$http_referer:用来记录从那个页面链接访问过来的;
#$http_user_agent:记录客户浏览器的相关信息;
#通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。

#定义本虚拟主机的访问日志
#access_log path(存放路径) name (自定义日志名称)
access_log /var/log/nginx/access.log access;

server {
listen 80;
server_name www.xxx.com xxx.com;
#所有请求转到https的443端口处理
#301 代表永久性转移
return 301 https://$server_name$request_uri;
}

#配置一个虚拟主机
server {
listen 443 ssl;
server_name www.xxx.com xxx.com;

#(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)
#没有有location modifier [=|~|~*|^~|@],后面跟普通字符串,不能是正则表达式
#因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
#匹配符合以后,还要继续往下搜索,只有后面的正则表达式没有匹配到时,这一条才会采用这一条
location / {
#php项目的路径
root /usr/share/nginx/html;
index index.html index.php;
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}
}

#fastcgi代理以.php结尾的请求
#~对大小写敏感,后面须是正则表达式
#\.是转义字符,否则单纯的.代表“匹配除换行符以外的任意字符”
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

#所有静态文件由nginx直接读取不经过tomcat或resin
#location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
# expires 10d;
#}
#location ~ \.(js|css)?$ {
# expires 1h;
#}

#letsencrypt生成的文件
ssl_certificate /etc/nginx/httpscert/www.xxx.com/fullchain.pem;
ssl_certificate_key /etc/nginx/httpscert/www.xxx.com/privkey.pem;

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;

ssl_dhparam /etc/nginx/httpscert/www.xxx.com/dhparam.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 一般推荐使用的ssl_ciphers值: https://wiki.mozilla.org/Security/Server_Side_TLS
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK';
ssl_prefer_server_ciphers on;


}#server end

}

docker部署mysql

1.创建相关文件夹
mkdir -p /docker/mysql/docker-file
mkdir -p /docker/mysql/data /docker/mysql/logs /docker/mysql/conf

2.下载镜像
docker pull mysql:5.7

3.配置文件
nano /docker/mysql/conf/mysql-custom.cnf

4.运行mysql docker容器
docker run -id –restart=always –name=mysql -v /docker/mysql/data:/var/lib/mysql -v /docker/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=xxx –network docker-bridge-net -p 3306:3306 mysql:5.7
虽然映射了端口到主机,但是不要打开防火墙,是为了本机的备份服务。

5.保存镜像
mkdir -p /docker/images
docker save -o /docker/images/mysql.tar mysql

wordpres部署

把wordpress解压到/docker/nginx/data/html,修改wp-config.php

1
2
3
4
5
/** MySQL数据库密码 */
define('DB_PASSWORD', 'xxx');

/** MySQL主机 */
define('DB_HOST', 'mysql:3306');

docker备份恢复

为什么不用docker commit xxx_nginx mynginx保存容器?
xxx_nginx是容器名称
mynginx是新的镜像名称
比如mysql,直接commit mysql 的docker容器,发现mysql中的数据库data并没有保存下来,原因是mysql的docker镜像中是通过挂在数据卷的方式来写入数据库中的数据,可以在/var/lib/volumes/xxxxxxxxxxxxxxxxxxxxx/_data中找到。而数据卷中的数据是不会被保存下来的。在mysql:5.7的镜像docker file中可以看到相关信息。
所以最好的实践,就是创建docker容器的时候自己指定主机到docker中路径的映射,恢复的时候直接恢复就好了。

1.备份docker中的数据
mkdir /backup
tar cvpzf /backup/backup-$(date +%Y%m%d-%H%M).tgz /docker
-p :使用原文件的原来属性(属性不会依据使用者而变)

2.恢复docker中的数据
tar xvpzf /backup/backup-20181001-1630.tgz -C /

3.从文件中恢复镜像,-i 输入的文件
docker load -i /docker/images/nginx.tar
docker load -i /docker/images/mysql.tar
docker load -i /docker/images/bitnami-php-fpm.tar
docker images 查看镜像

4.恢复php-fpm服务
docker run -id –restart=always –name=php -v /docker/nginx/data/html:/usr/share/nginx/html –network docker-bridge-net bitnami/php-fpm

5.恢复nginx服务
docker run -id –restart=always –name=nginx
-v /docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro
-v /docker/nginx/conf/httpscert:/etc/nginx/httpscert:ro
-v /docker/nginx/conf/conf.d:/etc/nginx/conf.d
-v /docker/nginx/logs:/var/log/nginx
-v /docker/nginx/data/html:/usr/share/nginx/html
-p 80:80 -p 443:443 –network docker-bridge-net nginx
ufw allow 80
ufw allow 443
ufw reload

6.生成https需要的证书
mkdir /etc/ssl/private/ -p
cd /etc/ssl/private/
openssl dhparam 2048 -out dhparam.pem

#let’s encrypt
certbot-auto certonly –webroot -w /docker/nginx/data/html -d www.xxx.com -m xxx@gmail.com –agree-tos

#复制证书文件到nginx
mkdir -p /docker/nginx/conf/httpscert/www.xxx.com
cp -f /etc/letsencrypt/live/www.xxx.com/fullchain.pem /docker/nginx/conf/httpscert/www.xxx.com/fullchain.pem
cp -f /etc/letsencrypt/live/www.xxx.com/privkey.pem /docker/nginx/conf/httpscert/www.xxx.com/privkey.pem
cp -f /etc/ssl/private/dhparam.pem /docker/nginx/conf/httpscert/www.xxx.com/dhparam.pem
chmod 400 /etc/letsencrypt/live/www.xxx.com/fullchain.pem
chmod 400 /etc/letsencrypt/live/www.xxx.com/privkey.pem
chmod 400 /etc/ssl/private/dhparam.pem
chmod 400 /docker/nginx/conf/httpscert/www.xxx.com/fullchain.pem
chmod 400 /docker/nginx/conf/httpscert/www.xxx.com/privkey.pem
chmod 400 /docker/nginx/conf/httpscert/www.xxx.com/dhparam.pem

7.恢复mysql服务
docker run -id –restart=always –name=mysql -v /docker/mysql/data:/var/lib/mysql -v /docker/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=xxx –network docker-bridge-net -p 3306:3306 mysql:5.7
这里不打开防火墙端口,映射到主机3306端口,是为了备份脚本连接到数据库而已。
密码也不用改,如果通过MYSQL_ROOT_PASSWORD改了密码是不起作用的,原因是因为主机中的数据/docker/mysql/data映射到了新建的mysql容器中,数据库密码还是原来的,需要进入容器修改。

备份到dropbox

把tar cvpzf /backup/backup-$(date +%Y%m%d-%H%M).tgz /docker打包后上传dropbox出错,原因是因为太大了,所以把备份文件分卷压缩后上传,比较简单。

1
2
#-v100m   分卷压缩,每个100m
executeCommand = r'7za a "%s" "%s" -t7z -mhe -r -mx9 -v100m -p"%s"' % (fileName, self.backupConfig['tempDir'], self.backupConfig['zipPassword'])