持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
前言
分享一下业余自己搭建博客系统的步骤,利用 Docker 搭建 WordPress 博客系统,仅需五分钟😂
由于个人服务器配置低,就不贴地址了
前期准备
- 一台云服务器 (centos 系统,本文整体以 centos7 系统为例)
- 一个备案过的域名
搭建思路
wordpress 是非常著名的博客平台,由php语言编写,对于小白(非php开发人员)来说去从零搭建有些困难,需要了解php以及其相关组件。利用 Docker 容器化技术就可以跳过这一环节,仅仅需要熟悉 Docker 容器以及 Docker 集群相关知识即可。 本文案例利用 Docker Swarm 集群管理将 Wordpress、MySQL、Nginx 镜像写入编排文件并编写 Bash 脚本成功搭建 WordPress 博客系统,并且实现数据持久化以及自动化部署。
Docker 环境搭建
安装 Docker
# 卸载已有docker
yum remove docker docker-common docker-selinux docker-engine
# 安装需要的软件包 yum-util提供yum-config-manager功能 另外两个是devicemapper驱动依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 阿里云源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 查看仓库中docker 的版本
yum list docker-ce --showduplicates | sort -r
# 安装最新稳定版
yum install docker-ce
# 开机启动
systemctl start docker
systemctl enable docker
# 查看是否安装成功 输入下面命令后 出现版本信息即可
docker version
安装 Docker-Compose
# 安装docker-compose
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 赋予文件可执行权限
chmod +x /usr/local/bin/docker-compose
# 查看是否安装成功
docker-compose --version
镜像加速
Docker 仓库中的镜像大部分国内拉取速度非常慢 所以这里配置一下国内镜像
# 编辑配置文件
vim /etc/docker/daemon.json
# 加入以下内容 这是json格式,如果已经有其他配置则仅加入 "registry-mirrors" 字段即可
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}
代码编写
在本地新建自己的项目目录本文案例代码中的目录均以 /project 作为项目根目录。
证书相关
域名备案后将 Nginx 相关证书文件放入 /project/nginx/configs/ 目录下
/project/nginx/keys/blog.sunhy.top_bundle.crt
/project/nginx/keys/blog.sunhy.top.key
Nginx 配置文件
在 /project 目录新建 /nginx/configs/nginx.conf 文件
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
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;
client_max_body_size 10M;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
# 用于导入 目录下所有的 .conf
include /etc/nginx/conf.d/*.conf;
}
在 /project 目录新建 /nginx/configs/nginx-blog.conf文件,监听 80 端口 普通访问
server {
listen 80;
listen [::]:80;
# 域名
server_name blog.sunhy.top;
location / {
# 在 docker 集群访问容器名相当于访问IP
proxy_pass http://blog/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
在 /project 目录新建 /nginx/configs/nginx-blog-ssl.conf文件,监听 443 端口 https 访问
server {
listen 443 ssl;
server_name blog.sunhy.top;
server_tokens off;
# 证书相关文件 这些并不在 nginx 容器中
# 稍后利用编排文件做本地文件映射
ssl_certificate /etc/nginx/conf.d/blog.sunhy.top_bundle.crt;
ssl_certificate_key /etc/nginx/conf.d/blog.sunhy.top.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
charset utf-8;
location / {
proxy_pass http://blog/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
容器编排文件
在 /project 目录新建 docker-compose.yaml 文件
version: "1.0"
services:
# Nginx 容器
nginx:
image: nginx:1.21.0
# 本地映射到容器的目录
volumes:
# nginx 日志数据持久化 可以不写
- /project/nginx/log:/var/log/nginx
# nginx 配置文件
- /project/nginx/configs/nginx.conf:/etc/nginx/nginx.conf
- /project/nginx/configs/nginx-blog.conf:/etc/nginx/conf.d/default.conf
- /project/nginx/configs/nginx-blog-ssl.conf:/etc/nginx/conf.d/default-ssl.conf
# https 证书
- /project/nginx/keys/blog.sunhy.top_bundle.crt:/etc/nginx/conf.d/blog.sunhy.top_bundle.crt
- /project/nginx/keys/blog.sunhy.top.key:/etc/nginx/conf.d/blog.sunhy.top.key
# 端口映射
ports:
- 80:80
- 443:443
# 依赖
depends_on:
- blog
# 网络
networks:
- frontend
# 容器启动配置
deploy:
# 容器启动个数 默认 1
replicas: 1
# MySQL 容器
blog-db:
image: mysql:5.7
restart: always
ports:
- 3306:3306
volumes:
# MySQL 数据持久化
- /project/mysql/conf:/etc/mysql/conf.d
- /project/mysql/data:/var/lib/mysql
environment:
# root 用户密码
MYSQL_ROOT_PASSWORD: rootPwd
# 普通用户名、密码
MYSQL_USER: shy
MYSQL_PASSWORD: shyPwd
# 新增数据库 database
MYSQL_DATABASE: blog
networks:
- backend
# WordPress 容器
blog:
image: wordpress:5.9.3
environment:
# 操作数据库的用户、密码 跟上面 MySQL 容器配置要一致
WORDPRESS_DB_USER: shy
WORDPRESS_DB_PASSWORD: shyPwd
# 数据库 host docker 集群中用容器名即可访问到
WORDPRESS_DB_HOST: blog-db
# 数据库 database 跟上面 MySQL 容器配置要一致
WORDPRESS_DB_NAME: blog
# 数据表名前缀 可以不写默认好像是 wp_
WORDPRESS_TABLE_PREFIX: blog_
volumes:
# WordPress 数据持久化
- /project/wordpress:/var/www/html
depends_on:
- blog-db
networks:
- frontend
- backend
# 新建两个网络
networks:
# 名称自定义 frontend 代表前端容器使用 backend 代表后端
frontend:
backend:
自动部署脚本
建议所有代码托管至 github 仓库,以便后续在集群中加入其他容器或服务。本案例提供一个自动化部署 bash 脚本,在 /project 目录下新建 build.sh 文件
#!/bin/bash
# 进入项目目录
cd /project
# 拉取远端仓库最新代码
git pull origin master
# 删除无用镜像文件
docker image prune -a -f
# 拉取相关镜像
docker pull wordpress:5.9.3
docker pull mysql:5.7
docker pull nginx:1.21.0
# 重启集群 最后一个参数 sunhy 为名称
docker stack deploy -c /project/docker-compose.yaml sunhy
项目启动
初始化 Docker 集群
# 初始化
docker swarm init
部署
# 运行编写的部署脚本
bash /project/build.sh
# 脚本运行结束后 查看服务状态
docker service ls
访问配置的域名即可进入 WordPress 安装页面,根据提示完成操作登陆后台即可管理博客网站。
问题排查
本人搭建过程中走了一些弯路,当 docker 容器启动不了或者搭建失败报错时,要根据自己的判断找出出错的容器,用 docker 命令查看容器日志输出,如果容器可以运行则可以利用命令进入容器,在容器中排查错误或尝试修改找到问题解决办法。
Docker 容器相关命令
进入容器
# attach 命令进入容器后 如果终端退出 则容器随之停止
docker attach <容器 ID>
# exec 命令进入容器后 终端退出 容器继续后台运行
docker exec -it <容器 ID> /bin/bash
退出容器
# 直接输入 exit
exit
查看所有容器
# 输出所有容器 包括已停止
docker ps -a
停止容器
# 根据 docker ps -a 输出的信息 通过 容器id 停止容器
docker stop <容器 ID>
重新启动容器
# 通过 容器id 重启容器
docker restart <容器 ID>
删除容器
docker rm -f <容器 ID>
查看容器日志
# -f 容器内部的标准输出
docker logs -f <容器 ID>
检查容器底层信息
# 以json形式输出 容器信息
docker inspect <容器 ID>