今天收到一份面试题,内容看似很简单:
CentOS7,nginx 最新版,php 7.x,mysql 不做要求 + wordpress
以文件的方式创建并挂载2G的swap分区
请把学习记录以 URL,截图等方式保留。最终。我在手机上可以看到wordpress站点就好。时间1小时以内,方法方式不限
虽然看起来和简单,比如用 docker-compose
一键就能完成部署完成,不过为了把部署过程中遇到的一些问题详细地记录下来,以及参考的一些文档等,通过一篇正式的博客展现出来,这样效果会好一些。同时咱作为完美主义者,希望给再做一些额外的优化,比如 HTTPS ,以及不久前和咱给博客加的 Webp Server 😂。让图片飞起来 oh-my-webp.sh ! 咱来推销 Webp Server Go 啦 (小声。
另外提一点的是,如果你深入理解 LNMP 技术栈的话,还是推荐使用传统的方式比如 yum 安装或源码编译安装,那样会能理解这些服务之间的工作流程,会对整个系统有深入的了解。而 docker-compose
简单粗暴的方式为我们屏蔽了这些细节,会让我们放弃去思考这些底层的细节,对于我们学习这门技术栈来讲,还是弊大于利。不过今天为了快速部署起来,还是选用 docker-compose 吧😂
WordPress
Get WordPress Use the software that powers over 35% of the web.
WordPress 想必大家都很熟悉啦,毕竟收是全球内容管理系统里的老大哥,常年占据在第一的位置(占有率 35%)。官网 wordpress.org
任务2 以文件的方式创建并挂载2G的swap分区 这个任务与 WordPress 不太相关,所以就先完成这个。拿到机器后 ssh 登录到系统,先使用常用的命令看一下服务器的信息,另外在自己的域名上添加了 A 记录wordpress.k8s.li
到这台服务器 IP ,并开启 HTTPS ,防止被 DDOS 攻击,毕竟有 CloudFlare 的 Anycast CDN 给我们在前头扛一把😂还是不错滴。
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 [root@interview ~]# uname -a Linux interview 3.10.0-1062.12.1.el7.x86_64 #1 SMP Tue Feb 4 23:02:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux [root@interview ~]# cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 45 model name : Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz stepping : 7 microcode : 0x710 cpu MHz : 2594.123 cache size : 20480 KB physical id : 0 siblings : 1 core id : 0 cpu cores : 1 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush mmx fxsr sse sse2 syscall nx rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes hypervisor lahf_lm bogomips : 5187.68 clflush size : 64 cache_alignment : 64 address sizes : 46 bits physical, 48 bits virtual power management: [root@interview ~]# free -h total used free shared buff/cache available Mem: 985M 150M 451M 12M 382M 680M Swap: 0B 0B 0B
unanme -a
查看一下系统的内核版本 ,3.10.0-1062
的内核看样子是 CentOS7.7
cat /proc/cpuinfo
查看一下 CPU 的信息,E5-2670 的 CPU ,属于 Intel 第六代 CPU 系列。
free
查看一下内存的情况,1GB 的小内存😂
Q2 以文件的方式创建并挂载2G的swap分区
这个问题比较简单,之前自己的 GCE 小鸡 512M 内存上也是使用文件的方式创建 2GB 的交换分区😂。所以对这个步骤早就熟记于心,并不需要搜索就能搞定😋。使用 dd 命令即可生成一个 2GB 大小的文件。
1 2 3 4 [root@interview ~]# dd if=/dev/zero of=/swapfile bs=4M count=500 500+0 records in 500+0 records out 2097152000 bytes (2.1 GB) copied, 11.0648 s, 190 MB/s
2097152000 bytes (2.1 GB) copied, 11.0648 s, 190 MB/s
怎么会是 2.1 GB 呢?,多出来 0.1GB ,强迫症受不了。想起来了,可能是 bs=4M
参数的问题。于是我在我的 debian 机器上测试了一下
顺带 man 一下 dd 看看 bs 参数是怎么定义的
bs=BYTES read and write up to BYTES bytes at a time (default: 512); overrides ibs and obs
1 2 3 4 5 ╭─debian@debian ~ ╰─$ dd if=/dev/zero of=./test bs=4MB count=4 4+0 records in 4+0 records out 16000000 bytes (16 MB, 15 MiB) copied, 0.0147078 s, 1.1 GB/s
原因是文件大小单位不同,一个是 MB
另一个是 MiB
,在 Google 上搜索了一下 。看到上的一个回答 What is the difference between 1 MiB and 1 MB and why should we care? 。也想起了前两天看到 面向信仰编程 大佬的一个推文:
接下来使用 mkswap
命令将刚刚创建好的 /swapfile
文件格式化为交换分区所需要的格式,并修改一下文件权限为 600 ,即只能由 root 用户读,不然默认的 755 会被其他用户看到,而里面的内容是内存里的信息,所以安全起见还是修改一下权限。
1 2 3 4 5 6 7 8 9 10 11 [root@interview ~]# mkswap /swapfile Setting up swapspace version 1, size = 2047996 KiB no label, UUID=a4eab465-75d1-4830-b870-c222c7e2e87b [root@interview ~]# [root@interview ~]# chmod 600 /swapfile [root@interview ~]# swapon !$ swapon /swapfile [root@interview ~]# free -h total used free shared buff/cache available Mem: 985M 212M 140M 12M 633M 612M Swap: 2.0G 0B 2.0G
至此任务二完成了,接下来就是题目的核心安装 WordPress 啦
install 刚开始打算使用常规的方法来部署 WordPress 的,使用 Google 搜索关键字 CentOS install WordPress
,排名第二的是 DigitalOcean
官方博客里的 How To Install WordPress on CentOS 7 。官方博客里提到:
Additionally, you’ll need to have a LAMP (Linux, Apache, MySQL, and PHP) stack installed on your CentOS 7 server. If you don’t have these components already installed or configured, you can use this guide to learn how to install LAMP on CentOS 7.
虽然 WordPress 官方没有给出详细的搭建步骤,但可以参考 DigitalOcean 官方的内容,毕竟公有云服务提供商的技术专家写的博客更可靠一些。由于要求的是 nginx 最新版本,yum 安装的 nginx 版本可能会旧一些。
1 2 3 4 5 6 7 8 9 [root@interview wordpress]# yum list nginx Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: centos-distro.1gservers.com * epel: d2lzkl7pfhq30w.cloudfront.net * extras: mirror.dal.nexril.net * updates: mirror.dal10.us.leaseweb.net Available Packages nginx.x86_64 1:1.16.1-1.el7 epel
yum list nginx
里的信息显示 nginx 版本为 1.16.1 并不是 官网 上的最新版 1.17.10
,源码编译的时间可能会有点长,因为前天看到一个推文说他使用 GCP 的小鸡编译 nginx 大概花了 3 个小时😂。而我面试规定的时间是要求 1 个小时内解决。我去,想要最新版 nginx ,而且最省时间的办法看来只用 docker 的方式安装 nginx 了 ,使用 nginx 官方的镜像 nginx:latest 即为 nginx 最新的版本。Google 搜索 docker hub nginx
来到 docker 官方的 nginx 镜像仓库 nginx 。我哭了,虽然是 1.17 版本,但是 1.17.9 版本而不是 1.17.10 ,就差了一点点啊!掀桌儿(。将就着用吧,虽然差了那么一点点。
事实证明我推断错了,第二天我在我的另一台机器上编译 nginx 花了不到 1 分钟,被大佬坑惨了啊😂。在 GCE 小鸡上编译 nginx 根本不可能需要 3 小时吧,3 分钟才对的吧。当初看到后就感觉编译 nginx 需要 3个小时就有点问题,但并没有亲自去验证。唉,还是自己不够细致啊,一知半解真是很危险的事儿!
install docker 安装 docker 的方式再熟悉不过了,使用一个 curl 命令就能搞定 curl -fsSL https://get.docker.com | bash -s docker
如果在国内环境的话,后面加上 --mirror Aliyun
参数就能使用阿里云的镜像站,这样会更快一些。即 curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
。
不过我还是从第一次接触的角度来安装 docker ,Google 搜索 centos install docker
点进入第一个搜索结果即为官网 Install Docker Engine on CentOS ,为了节省时间就没有按照官网的步骤来,而是使用官方的一键脚本来安装。
1 2 3 4 5 [root@interview ~]# curl -fsSL https://get.docker.com -o get-docker.sh [root@interview ~]# ls get-docker.sh [root@interview ~]# chmod +x get-docker.sh [root@interview ~]# ./get-docker.sh
安装完成之后使用 docker info
来查看一下 docker 信息。需要注意的是:目前最新版本的 docker 默认优先采用 overlay2 的存储驱动,对于已支持该驱动的 Linux 发行版,不需要任何进行任何额外的配置。另外需要注意的是devicemapper
存储驱动已经在 docker 18.09 版本中被废弃,docker 官方推荐使用 overlay2
替代devicemapper
,在我司生产环境曾经因为 devicemapper
遇到过存储挂不起的坑😑。
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 [root@interview ~]# docker info Client: Debug Mode: false Server: Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 19.03 .8 Storage Driver: overlay2 Backing Filesystem: <unknown> Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd init version: fec3683 Security Options: seccomp Profile: default Kernel Version: 3.10 .0 -1062.12 .1 .el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 1 Total Memory: 985. 3MiB Name: interview ID: YSZO:TT5U:GDLH:3FYT:LFGP:NLOS:L4YI:5LFU:3EAV:KHP2:F746:I5P3 Docker Root Dir: /var/lib/docker Debug Mode: false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0 .0 .0 /8 Live Restore Enabled: false
install docker-compose 安装完 docker 之后,接下来安装 docker-compose ,使用 Google 搜索 centos install docker-compose
点进入第一个搜索结果即为官网的 Install Docker Compose
1 2 3 4 5 6 7 8 9 [root@interview ~] sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose [root@interview ~]# docker-compose version bash: /usr/local/bin/docker-compose: Permission denied [root@interview ~]# chmod +x /usr/local/bin/docker-compose [root@interview ~]# docker-compose version docker-compose version 1.25.4, build 8d51620a docker-py version: 4.1.0 CPython version: 3.7.5 OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
遇到了 Permission denied
问题,原来是忘记加权限了 chmod +x /usr/local/bin/docker-compose
一下即可。
WordPress 官方 Quickstart: Compose and WordPress 的 docker-compose.yaml
中的 web 服务器是使用的 apache 而不是 nginx ,因此要使用第三方的 docker-compose.yaml,前段时间在折腾 Webp Server Go 的时候遇到过这种需求。于是在 GitHub 上搜索 wordpress nginx docker-compose
找到了合适的 repo 即 wordpress-nginx-docker 。看一下 docker-compose.yaml 文件
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 version: '3.6' services: wordpress: image: wordpress:${WORDPRESS_VERSION:-php7.3-fpm} container_name: wordpress volumes: - ./config/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini - ./wordpress:/var/www/html environment: - WORDPRESS_DB_NAME=${WORDPRESS_DB_NAME:-wordpress} - WORDPRESS_TABLE_PREFIX=${WORDPRESS_TABLE_PREFIX:-wp_} - WORDPRESS_DB_HOST=${WORDPRESS_DB_HOST:-mysql} - WORDPRESS_DB_USER=${WORDPRESS_DB_USER:-root} - WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD:-password} depends_on: - mysql restart: always mysql: image: mariadb:${MARIADB_VERSION:-latest} container_name: mysql volumes: - ./mysql:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-password} - MYSQL_USER=${MYSQL_USER:-root} - MYSQL_PASSWORD=${MYSQL_PASSWORD:-password} - MYSQL_DATABASE=${MYSQL_DATABASE:-wordpress} restart: always nginx: image: nginx:${NGINX_VERSION:-latest} container_name: nginx ports: - '80:80' - '443:443' volumes: - ${NGINX_CONF_DIR:-./nginx}:/etc/nginx/conf.d - ${NGINX_LOG_DIR:-./logs/nginx}:/var/log/nginx - ${WORDPRESS_DATA_DIR:-./wordpress}:/var/www/html - ${SSL_CERTS_DIR:-./certs}:/etc/letsencrypt - ${SSL_CERTS_DATA_DIR:-./certs-data}:/data/letsencrypt depends_on: - wordpress restart: always adminer: image: adminer restart: always links: - mysql ports: - 8080 :8080
共有 4 个容器: wordpress、mysql、nginx、adminer,默认不需要修改既可以部署起来。adminer 是个 web 端管理 MySQL 数据库的,可以删掉不需要。
由于默认的系统不带 git ,所以需要安装一下 git yum install git
,然后把 repo clone 下来。
1 2 3 git clone https://github.com/mjstealey/wordpress-nginx-docker cd wordpress-nginx-docker docker-compose up
这样使用 docker-compose up
命令就能启动一个 WordPress 站点了。通过访问域名 wordpress.k8s.li 即可访问刚刚创建好的网站了。
Webp Server 为了优化一下博客图片静态资源的加载速度,可以为 WordPress 加上一个 Webp Server 服务,将原图片压缩为 webp 格式。需要修改一下 nginx 的配置文件,添加内容如下:
1 2 3 location ^~ /wp-content/uploads/ { proxy_pass http://webp-server:3333; }
在 docker-compose.yaml 文件中加入 webp server 的容器
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 version: '3.6' services: wordpress: image: wordpress:${WORDPRESS_VERSION:-php7.3-fpm} container_name: wordpress volumes: - ./config/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini - ./wordpress:/var/www/html environment: - WORDPRESS_DB_NAME=${WORDPRESS_DB_NAME:-wordpress} - WORDPRESS_TABLE_PREFIX=${WORDPRESS_TABLE_PREFIX:-wp_} - WORDPRESS_DB_HOST=${WORDPRESS_DB_HOST:-mysql} - WORDPRESS_DB_USER=${WORDPRESS_DB_USER:-root} - WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD:-password} depends_on: - mysql restart: always mysql: image: mariadb:${MARIADB_VERSION:-latest} container_name: mysql volumes: - ./mysql:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-password} - MYSQL_USER=${MYSQL_USER:-root} - MYSQL_PASSWORD=${MYSQL_PASSWORD:-password} - MYSQL_DATABASE=${MYSQL_DATABASE:-wordpress} restart: always nginx: image: nginx:${NGINX_VERSION:-latest} container_name: nginx ports: - '80:80' - '443:443' volumes: - ${NGINX_CONF_DIR:-./nginx}:/etc/nginx/conf.d - ${NGINX_LOG_DIR:-./logs/nginx}:/var/log/nginx - ${WORDPRESS_DATA_DIR:-./wordpress}:/var/www/html - ${SSL_CERTS_DIR:-./certs}:/etc/letsencrypt - ${SSL_CERTS_DATA_DIR:-./certs-data}:/data/letsencrypt depends_on: - wordpress restart: always webp-server: image: webpsh/webps:latest restart: always container_name: webp-server volumes: - ./webp-server/config.json:/etc/config.json - ./wordpress:/var/www/html ports: - 3333 :3333
修改好 docker-compose.yaml 文件之后,我们还需要为 webp-server 准备一个 config.json 文件,存放在 ./webp-server/config.json
下,内容如下:
1 2 3 4 5 6 7 8 { "HOST" : "0.0.0.0" , "PORT" : "3333" , "QUALITY" : "80" , "IMG_PATH" : "/var/www/html" , "EXHAUST_PATH" : "" , "ALLOWED_TYPES" : ["jpg" ,"png" ,"jpeg" ,"bmp" ,"gif" ] }
接下来我们使用 docker-compose restart
命令重启一下容器,之后再 WordPress 端上传一张图片测试一下。上传完成之后,拿到图片的 url ,然后使用 wget 命令测试一下,显示 Length: 102288 (100K) [image/webp]
就说明我们的 webp server 已经成功运行啦😂。完整的 repo 在我的 GitHub 上 Wwordpress ,欢迎来食用呀😋
1 2 3 4 5 6 7 8 9 10 11 12 ╭─root@sg-02 /opt/wordpress-nginx-docker ‹master› ╰─# wget http://dl.amd64.xyz/wp-content/uploads/2020/04/74898710_p21.jpg --2020-04-17 01:06:29-- http://dl.amd64.xyz/wp-content/uploads/2020/04/74898710_p21.jpg Resolving dl.amd64.xyz (dl.amd64.xyz)... 3.1.38.108 Connecting to dl.amd64.xyz (dl.amd64.xyz)|3.1.38.108|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 102288 (100K) [image/webp] Saving to: ‘74898710_p21.jpg’ 74898710_p21.jpg 100%[=======>] 99.89K --.-KB/s in 0.001s 2020-04-17 01:06:29 (130 MB/s) - ‘74898710_p21.jpg’ saved [102288/102288]
参考
end 至此部署一个 WordPress 的流程就结束啦,为了追求速度就放弃了对一些细节的深究,得不偿失啊。
有些内容看似简单,但想把这个过程中遇到的问题以及想法落笔成字,形成一篇博客,还是需要语言组织能力,看来自己这方面还是有些欠缺。