博客搬家日记--搭建基于Docker的LNMP环境
背景
由于云主機馬上就要到期了,所以最近對比了幾家云服務器提供商。最終決定嘗試一下 UCloud。于是不得不把原博客(typecho)遷移過來。下面是流水賬式地記錄一下過程。
過程記錄
本想嘗試按照以前的筆記重新搭建一套環境,然后再把數據導過來,但是一想到這一長串的步驟,以及可能碰到的問題就頭疼,于是決定構建一個基于容器的 LNMP 環境,一勞永逸,也方便日后繼續做博客遷移。當然如果有同學也想搭建基于 LNMP 的博客如 Typecho,則可以參考我的模板:-)(文末有 Github 鏈接)。
注:以下命令及配置都是基于 CentOS7。
容器環境
由于此次環境的搭建是用的 docker,所以先保證機器上安裝了 docker 和 docker-compose:
# 安裝 docker sudo yum install -y yum-utils sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sudo yum install docker-ce docker-ce-cli containerd.io sudo systemctl enable docker sudo systemctl start docker# 安裝 docker-compose sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-composeLNMP 環境配置
構建基于 docker-compose,目錄結構如下:
. ├── docker-compose.yml # docker-compose 配置文件 ├── mysql │ ├── conf # mysql 配置文件目錄 │ │ ├── my.cnf │ └── data # mysql 數據文件目錄 ├── nginx │ ├── cert # nginx ssl 證書目錄 │ │ ├── nightfield.com.cn.key │ │ ├── nightfield.com.cn.pem │ ├── conf # nginx 配置目錄 │ │ ├── nightfield.com.cn.conf │ ├── html # nginx Web 根目錄 │ │ ├── info.php │ └── log # nginx 日志目錄 ├── php │ ├── conf # php 配置目錄 │ │ └── php.ini │ └── Dockerfile # php 的 Dockerfile 配置可以看到主要是對應軟件的一些配置文件。docker-compose.yml 文件內容如下:
version: "3" services:nginx:image: nginx:latestcontainer_name: nginxnetworks:- lnmpdepends_on:- phpports:- "80:80"- "443:443"expose:- "80"- "443"volumes:- /opt/docker/nginx/html:/usr/share/nginx/html # nginx web 根目錄- /opt/docker/nginx/conf/:/etc/nginx/conf.d # 配置目錄- /opt/docker/nginx/log:/var/log/nginx # 日志目錄- /opt/docker/nginx/cert:/etc/nginx/cert # ssl 證書目錄links:- phpphp:build: # 由于 PHP 的構建相對較為復雜,所以用了 Dockerfile 的方式context: ./phpdockerfile: Dockerfilecontainer_name: phpvolumes:- /opt/docker/nginx/html:/usr/share/nginx/html # nginx web 根目錄- /opt/docker/php/conf/:/usr/local/etc/php/conf.d # 配置目錄networks:- lnmpdepends_on:- mysqlexpose:- "9000"mysql:image: mysql:5.7container_name: mysqlvolumes:- /opt/docker/mysql/conf/:/etc/mysql/conf.d # 配置目錄- /opt/docker/mysql/data:/var/lib/mysql # 數據目錄environment:MYSQL_ROOT_PASSWORD: password # 改為自定義密碼networks:- lnmpexpose:- "3306"ports:- "3306:3306"networks:lnmp:Mysql
Mysql 的配置較為簡單不再贅述,注意將對應的配置目錄以及數據目錄從容器中映射出來便于管理。
Nginx
將 Nginx 的配置從容器中映射出來,模版如下:
# https ssl, 對應 443 端口 server {listen 443 ssl;server_name nightfield.com.cn; # 域名或者服務器 iperror_log /var/log/nginx/error.log;access_log /var/log/nginx/access.log;index index.php;root /usr/share/nginx/html;# ssl 配置ssl_certificate_key cert/nightfield.com.cn.key; # 證書 keyssl_certificate cert/nightfield.com.cn.pem; # 證書 pemssl_session_cache shared:SSL:1m;ssl_session_timeout 5m;ssl_prefer_server_ciphers on;location ~ .*\.php(\/.*)*$ { # 注意這里的正則fastcgi_split_path_info ^(.+\.php)(/.+)$;fastcgi_pass php:9000;fastcgi_index index.php;include fastcgi_params;fastcgi_split_path_info ^(.+.php)(/.+)$;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;fastcgi_param PATH_INFO $fastcgi_path_info;} }# https,對應 80 端口 server {listen 80;server_name nightfield.com.cn; # 域名或者服務器 iprewrite ^(.*)$ https://${server_name}$1 permanent; # 重定向到 https }PHP
PHP 的構建相對復雜,除了從官網拉 PHP 鏡像外,還需要安裝額外的模塊如 mysqli pdo_mysql,所以做了一個 Dockerfile,內容如下:
FROM php:7.0-fpm # 基礎鏡像 RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \&& echo "Asia/Shanghai" > /etc/timezone RUN apt-get update && apt-get install -y \ # 一些 lib 庫libfreetype6-dev \libjpeg62-turbo-dev \libmcrypt-dev \libpng-dev \libmemcached-dev \zlib1g-dev \libcurl4-openssl-dev \libxml2-dev \--no-install-recommends && rm -rf /var/lib/apt/lists/* \&& docker-php-ext-install -j$(nproc) \ # 插件安裝iconv mcrypt gettext curl mysqli pdo pdo_mysql zip \mbstring bcmath opcache xml simplexml sockets hash soap \&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \&& docker-php-ext-install -j$(nproc) gdCMD ["php-fpm", "-F"]LNMP 環境構建及驗證
配置都完成之后,啟動容器環境:
docker-componse up -d在云服務器的安全組規則配置中,開放對應端口:80,443,3306(完成數據遷移之后可以關閉),然后打開瀏覽器訪問 ${hostname}/info.php,可以看到如下頁面:
說明環境已安裝成功!
數據遷移
接下來要做的就是把博客數據從老的庫遷移到新的庫。
Typecho 數據
將整個 Typecho 目錄打包,用 scp 傳到新機器的 ./nginx/html/ 目錄下。
Mysql
我這里用了比較老套的方法:從老庫導出數據再導入新庫,用工具是 DBeaver。這里記錄一下 Typecho 相關的一些表結構。
use typecho; CREATE TABLE `typecho_comments` (`coid` int(10) unsigned NOT NULL AUTO_INCREMENT,`cid` int(10) unsigned DEFAULT '0',`created` int(10) unsigned DEFAULT '0',`author` varchar(200) DEFAULT NULL,`authorId` int(10) unsigned DEFAULT '0',`ownerId` int(10) unsigned DEFAULT '0',`mail` varchar(200) DEFAULT NULL,`url` varchar(200) DEFAULT NULL,`ip` varchar(64) DEFAULT NULL,`agent` varchar(200) DEFAULT NULL,`text` text,`type` varchar(16) DEFAULT 'comment',`status` varchar(16) DEFAULT 'approved',`parent` int(10) unsigned DEFAULT '0',PRIMARY KEY (`coid`),KEY `cid` (`cid`),KEY `created` (`created`) ) ENGINE=MyISAM AUTO_INCREMENT=51476 DEFAULT CHARSET=utf8;CREATE TABLE `typecho_contents` (`cid` int(10) unsigned NOT NULL AUTO_INCREMENT,`title` varchar(200) DEFAULT NULL,`slug` varchar(200) DEFAULT NULL,`created` int(10) unsigned DEFAULT '0',`modified` int(10) unsigned DEFAULT '0',`text` longtext,`order` int(10) unsigned DEFAULT '0',`authorId` int(10) unsigned DEFAULT '0',`template` varchar(32) DEFAULT NULL,`type` varchar(16) DEFAULT 'post',`status` varchar(16) DEFAULT 'publish',`password` varchar(32) DEFAULT NULL,`commentsNum` int(10) unsigned DEFAULT '0',`allowComment` char(1) DEFAULT '0',`allowPing` char(1) DEFAULT '0',`allowFeed` char(1) DEFAULT '0',`parent` int(10) unsigned DEFAULT '0',`views` int(10) DEFAULT '0',PRIMARY KEY (`cid`),UNIQUE KEY `slug` (`slug`),KEY `created` (`created`) ) ENGINE=MyISAM AUTO_INCREMENT=199 DEFAULT CHARSET=utf8;CREATE TABLE `typecho_fields` (`cid` int(10) unsigned NOT NULL,`name` varchar(200) NOT NULL,`type` varchar(8) DEFAULT 'str',`str_value` text,`int_value` int(10) DEFAULT '0',`float_value` float DEFAULT '0',PRIMARY KEY (`cid`,`name`),KEY `int_value` (`int_value`),KEY `float_value` (`float_value`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;CREATE TABLE `typecho_metas` (`mid` int(10) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(200) DEFAULT NULL,`slug` varchar(200) DEFAULT NULL,`type` varchar(32) NOT NULL,`description` varchar(200) DEFAULT NULL,`count` int(10) unsigned DEFAULT '0',`order` int(10) unsigned DEFAULT '0',`parent` int(10) unsigned DEFAULT '0',PRIMARY KEY (`mid`),KEY `slug` (`slug`) ) ENGINE=MyISAM AUTO_INCREMENT=52 DEFAULT CHARSET=utf8;CREATE TABLE `typecho_options` (`name` varchar(32) NOT NULL,`user` int(10) unsigned NOT NULL DEFAULT '0',`value` text,PRIMARY KEY (`name`,`user`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;CREATE TABLE `typecho_relationships` (`cid` int(10) unsigned NOT NULL,`mid` int(10) unsigned NOT NULL,PRIMARY KEY (`cid`,`mid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;CREATE TABLE `typecho_users` (`uid` int(10) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(32) DEFAULT NULL,`password` varchar(64) DEFAULT NULL,`mail` varchar(200) DEFAULT NULL,`url` varchar(200) DEFAULT NULL,`screenName` varchar(32) DEFAULT NULL,`created` int(10) unsigned DEFAULT '0',`activated` int(10) unsigned DEFAULT '0',`logged` int(10) unsigned DEFAULT '0',`group` varchar(16) DEFAULT 'visitor',`authCode` varchar(64) DEFAULT NULL,PRIMARY KEY (`uid`),UNIQUE KEY `name` (`name`),UNIQUE KEY `mail` (`mail`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;域名重解析
去域名的配置頁面,將 A 記錄 重新解析到新的 ip 上,等待生效后(ping 以下域名看結果),訪問 https://nightfield.com.cn 已經可以正確打開博客,還是原來的味道,只是換了配方:-)。
問題記錄
1. 博客的配置丟失
還不知道具體原因,用最笨的方法解決了:主題和插件重新配置了一下。
2. PHP 無法連接數據庫
報的錯誤是:
Uncaught Error: Class 'mysqli' not found原因一般是沒有安裝 mysqli 導致的,但是我們在 Dockerfile 里面確實有安裝此模塊。在配置文件 ./php/conf/php.ini 中加上以下配置,問題解決:
extension=mysqli.so extension=pdo_mysql.so3. 打開很多 Typecho 頁面報 Cannot modify header information
報的錯誤是:
Warning: Cannot modify header information - headers already sent by (output started at /data/dy-pages/store-1/262/1634262/www/install.php:202) in /data/dy-pages/store-1/262/1634262/www/var/Typecho/Cookie.php on line 102在配置文件 ./php/conf/php.ini 中加上以下配置,問題解決:
output_buffering=on4. 無法登陸 Typecho 管理頁面,報 404
這個問題是無法正確解析 URL 導致的。Typecho 登陸之后的 url 類似 https://www.nightfield.com.cn/index.php/action/login?_=7,而我在 Nginx 配置的 PHP location 為 location ~ .*\.php$,無法處理上述 url。將 location 改為 location ~ .*\.php(\/.*)*$ 問題解決。
附錄
本次基于 docker 的 LNMP 環境的代碼 Github 地址:Docker-LNMP。
總結
以上是生活随笔為你收集整理的博客搬家日记--搭建基于Docker的LNMP环境的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(1981)vue之电商管理系统
- 下一篇: 前端学习(1683):前端系列实战课程之