Nginx 反向代理实现 Kibana 登录认证功能

Kibana 5.5 版后,已不支持认证功能,也就是说,直接打开页面就能管理,想想都不安全,不过官方提供了 X-Pack 认证,但有时间限制。毕竟X-Pack是商业版。

下面我将操作如何使用Nginx反向代理实现kibana的认证功能。

先决条件:

《Centos 7 源码编译安装 Nginx》

https://www.renwole.com/archives/39

1. 安装 Apache Httpd 密码生成工具

$ yum install httpd-tools -y

2. 生成Kibana认证密码

$ mkdir -p /usr/local/nginx/conf/passwd
$ htpasswd -c -b /usr/local/nginx/conf/passwd/kibana.passwd Userrenwolecom GN5SKorJ
Adding password for user Userrenwolecom

3. 配置Nginx反向代理

在Nginx配置文件中添加如下内容(或新建配置文件包含):

$ vim /usr/local/nginx/conf/nginx.conf

server {
listen 10.28.204.65:5601;
auth_basic "Restricted Access";
auth_basic_user_file /usr/local/nginx/conf/passwd/kibana.passwd;
location / {
proxy_pass http://10.28.204.65:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade; 
}
}

4. 配置Kibana

取消下面注释:

$ vim /usr/local/kibana/config/kibana.yml

server.host: "10.28.204.65"

5. 重启 Kibana 及 Nginx 服务使配置生效

$ systemctl restart kibana.service
$ systemctl restart nginx.service

接下来浏览器访问 http://103.28.204.65:5601/ 会提示验证弹窗,输入以上生成的用户密码登录即可。

nginx如何设置图片文件防盗链

关于nginx防盗链的方法网上有很多教程,都可以用,但是我发现很多教程并不完整,所做的防盗链并不是真正的彻底的防盗链!

一般,我们做好防盗链之后其他网站盗链的本站图片就会全部失效无法显示,但是您如果通过浏览器直接输入图片地址,仍然会显示图片,仍然可以右键图片另存为下载文件!

依然可以下载?这样就不是彻底的防盗了!那么,nginx应该怎么样彻底地实现真正意义上的防盗链呢?

首先,我们来看下nginx如何设置防盗链

如果您使用的是默认站点,也就是说,您的站点可以直接输入服务器IP访问的,使用root登录,修改 /usr/local/nginx/conf/nginx.conf 这个配置文件。

如果您新建了站点,那么修改/usr/local/nginx/conf/vhost/你的域名.conf 这个配置文件,找到:

location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
{
 expires      30d;
}

把这一段删掉,修改成:

location ~* .(gif|jpg|png|jpeg)$ {
    expires     30d;
        valid_referers none blocke *.hugao8.com www.hugao8.com m.hugao8.com *.baidu.com *.google.com;
    if ($invalid_referer) {
    rewrite ^/ http://ww4.sinaimg.cn/bmiddle/051bbed1gw1egjc4xl7srj20cm08aaa6.jpg;
    #return 404;
    }
    }

第一行: location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$

其中“gif|jpg|jpeg|png|bmp|swf”设置防盗链文件类型,自行修改,每个后缀用“|”符号分开!

第三行:valid_referers none blocked *.it300.com it300.com;

就是白名单,允许文件链出的域名白名单,自行修改成您的域名!*.it300.com这个指的是子域名,域名与域名之间使用空格隔开!

第五行:rewrite ^/ http://www.it300.com/static/images/404.jpg;

这个图片是盗链返回的图片,也就是替换盗链网站所有盗链的图片。这个图片要放在没有设置防盗链的网站上,因为防盗链的作用,这个图片如果也放在防盗链网站上就会被当作防盗链显示不出来了,盗链者的网站所盗链图片会显示X符号。

这样设置差不多就可以起到防盗链作用了,上面说了,这样并不是彻底地实现真正意义上的防盗链!

我们来看第三行:valid_referers none blocked *.it300.com it300.com;

valid_referers 里多了“none blocked”

我们把“none blocked”删掉,改成

valid_referers *.it300.com it300.com;

nginx彻底地实现真正意义上的防盗链完整的代码应该是这样的:

location ~* .(gif|jpg|png|jpeg)$ {
    expires     30d;
    valid_referers *.hugao8.com www.hugao8.com m.hugao8.com *.baidu.com *.google.com;
    if ($invalid_referer) {
    rewrite ^/ http://ww4.sinaimg.cn/bmiddle/051bbed1gw1egjc4xl7srj20cm08aaa6.jpg;
    #return 404;
    }
    }

这样您在浏览器直接输入图片地址就不会再显示图片出来了,也不可能会再右键另存什么的。

第五行:rewrite ^/ http://www.it300.com/static/images/404.jpg;

这个是给图片防盗链设置的防盗链返回图片,如果我们是文件需要防盗链下载,把第五行:

rewrite ^/ http://www.it300.com/static/images/404.jpg;

改成一个链接,可以是您主站的链接,比如把第五行改成:

rewrite ^/ http://www.it300.com;

这样,当别人输入文件下载地址,由于防盗链下载的作用就会跳转到您设置的这个链接!

最后,配置文件设置完成别忘记重启nginx生效!

如何快速实现一个基于Nginx的网站监控场景—-需求篇

一切从应用服务监控说起

小明所在的一家小型互联网创业公司一直将应用运行在国内某A云上。该应用采用通用的分布式Nginx+App架构为用户提供电商数据统计的webservice 服务。应用运行至今除偶发各类Bug, 性能问题以外,情况还算良好。

未分类

最近,小明的老板给小明布置了一个任务,希望把应用服务监控起来,以提高应用运行质量。老板的需求有三点:

1、先以应用服务监控为抓手,能

a) 实时统计应用各类服务的调用次数

b) 基于a,实时统计各类服务各类返回值的次数,如200,404,500,等。

c) 基于b,如果某类返回值调用超限,进行实时报警。

2、提供历史查询功能,能返回任意时段任意服务任意返回值调用次数统计。

3、以后未来公司各类定制的业务监控能快速扩展到该系统上,如各接口响应统计时间,用户特征统计,等。

“方案尽量多快好省,而且搭建的监控平台最好就在A云上,数据不要外放在第三方云上,主要是为了公网流量成本和以后大数据分析作准备”,老板最后提到。

技术选项

小明接到任务以后开始着手进行技术选型。摆在他面前貌似可行的有三个选择,传统OLAP式处理方式,搜索引擎,以及实时计算方式。

未分类

在调研现状和众多技术后,他发现,

  1. 由于公司业务规模不小,白天峰段的平均qps已经上百,而且业务还在快速增长,因此将每秒上百次调用信息每次直接存放到数据库中再实时查询肯定不合适,成本太高且不适合扩展。

  2. A云提供搜索引擎服务,错误统计功能基本能满足老板需求。但是不确定因素有两个。一方面搜索引擎价格存储成本偏高(搜索引擎需要引入索引存储),而且各类聚合查询如接口响应时间统计等查询响应时间不太好保证,另一方面考虑到实时报警还需要编写API不停进行各类调用的错误次数的轮询,性能和成本都不太确定。

  3. 基于实时计算的架构,可以将线上所有日志通过服务,返回值错误类型,和时间等维度在内存中进行实时的聚合计算,然后再持久化到存储中。一方面实时计算效率高,聚合后的结果大小会比原始数据大大减少,因此持久化成本低,实时能保证;另一方面还可以在内存中实时校验报警策略,让报警的性能开销足够小。

综上考虑,基于实时计算的架构看来最能满足当前公司的需求。决定了以后,小明开始思考进一步架构设计。

架构设计

决定了基于实时计算的技术以后,小明开始进行架构设计。通过参考各类技术网站,他发现要架构一个靠谱的网站监控方案,需要的组件以下缺一不可。

  • 数据通道:负责将数据从Nginx拉取出来,传送到搜索引擎。数据通道同时肩负数据堆积和数据重算的任务。

  • 计算引擎:基于Nginx服务,错误码,时间的维度的聚合实时计算逻辑需要基于选定的引擎进行编写。计算引擎最好能同时负责一些报警的逻辑。

  • 存储:存放最终Nginx监控结果的地方。考虑到监控结果虽然表结构简单,但是各种维度查询比较多,最好是类似于OLAP的存储类型。

  • 展示门户:针对所有Nginx监控结果作各类维度的快速分析和展示。

未分类

好在针对前三个组件,A云提供了一些现成的产品组件,小明不需要自己手动一个个去搭建,因此入门门槛还不算高。

  • 数据通道这块,小明在阿里云上选取了一款类似于Kafka的数据通道,在支持性能和消息堆积等特性的同时,在数据接入上提供了一定的简便性。

  • 计算引擎上,小明为了简易入手,选择了一款基于spark-stream计算引擎组件,可以上面直接写SQL语句进行实时计算编排而不需要自己写流式计算程序。

  • 存储方面,由于没有太强事物需求,而且在容量上要求较高,小明选择了一款类似Hbase的云上存储产品。

  • 展示门户方面,没有直接对应产品。小明挠了挠头,决定还是只能自己突击一下前段编程技术,基于开源展示框架来编写一个简单的查询门户。

跟老板申请了预算以后,小明开始陆续开通各类产品进行开发测试。预计一个月完成任务,

漫漫开发路程

开通流程很简单。花了半天不到,kafka, storm, hbase的租户集群到手。可惜常言道,开发项目80%的时间花费在最终20%的坑上。项目过了一个月,但是功能尚未完成70%。小明在自己的技术博客上默默的记录下以下踩过的坑。

  • 集成故障排查成本

由于需要集成的组件包括数据通道,实时计算层,后台存储,并在代码中集成推送数据逻辑以及报警查询逻辑。每个环节稍有出错将造成整个链路阻塞,调试成本显得非常高。

  • 日志清洗

开发期间为了获取到相关应用为了调整对于日志的推送逻辑,需要在每台Nginx日志内容变更以后再在每个服务端变更API的推送逻辑,变更过程冗长且容易出错。

  • 持久化表设计

除了要针对监控项做出适合的表库设计,并尽量避免索引热点以外,还需要考虑当数据结果由于实时计算层不稳定重复计算时如何保证数据库写入幂等性,这对表结构设计是一个不小的挑战

  • 延迟数据合并

如果由于应用原因导致Nginx日志数据被延迟发送,如何保证比如晚到1个小时的数据能被实时计算引擎准确计算并将结果合并到之前的结果。

  • 报警

针对所有结果需要设置定时任务每分钟对数据进行遍历查询。比如针对任何返回500调用错误超过5%占比的服务,需要所有服务进行多次的调用结果进行遍历查询。如何不遗漏所有的服务错误检查的同时保证高效率查询也是个不小的挑战。

  • 报警准确性

有的时候由于日志延迟,上一分钟部分服务器正常日志还没采集全,导致局部500调用错误的服务暂时超过5%,类似错误是否需要报警?如果报警,有可能误报,不报警的话,可能漏报,怎么处理呢?

  • 如何统计UV, TopN

以UV为例。如果要跨任意时间度查询UV,则常规手段还需要在数据库中存入每单位时间(如分钟级别)的全量IP访问信息。这对于存储利用率来讲显然是无法接受的。有没有更优化的方案?

  • 针对错误场景的诊断方法

针对各类返回值500的调用错误,业务方提出希望出现500错误时能根据时间和调用服务维度查询到详细的调用入参和其他详情,其场景和日志搜索类似。对于类似新加入需求,貌似通过实时聚合计算和存储不能直接办到。需要对日志另辟蹊径另行处理。

  • 以上问题还不包括前段展示的各类问题。

掐指一算,两个月晃眼过了。项目还没弄完一半,小明有点急了。

另外一种新的思路

小明晚上约了自己的同门师兄老丹搓串。就着小酒,小明把自己最近的烦心事从头到尾跟老丹说了一遍。

老丹听了一拍大腿:“小明,你这就奥特了。其实在阿里云上有一款云产品, 叫做业务实时监控,简称ARMS,基本上你遇到的这些问题,在ARMS上已经提供了一站式的解决方案,你只需要快速接入即可。”。

“噢,是么?我们业务的监控逻辑很多都是基于Nginx日志定制,ARMS具备接入Nginx日志的能力,并允许让我定制业务监控能力么?“小明问道。

“当然。ARMS上不仅提供监控Nginx的任务模板,本身自带报警和监控报表,同时还全程开放定制能力。如果你要增加自己的业务监控逻辑,或者删除或修改自己不要的通用监控逻辑,直接在其平台上定制即可。”老丹答道。

未分类

“听起来不错。最终结果除了报表和报警外,公司的下游业务平台也能用么?”

“可以的,ARMS提供API, 下游系统直接对接数据API即可,跟你在云上直接读数据库没什么本质区别。”

“听起来不错,看来我的项目有救了,我赶紧去看看。”

未分类

赶紧来看看吧,看如何使用ARMS快速搭建Nginx监控任务。

nginx认证模块ngx_http_auth_basic_module

ngx_http_auth_basic_module模块基于“HTTP Basic Authentication“协议完成用户认证。

模块指令:

auth_basic 

auth_basic_user_file

这两个指令的应用范围:http,server,location,limit_except

示例:

location / {

    auth_basic           "closedsite";

    auth_basic_user_fileconf/htpasswd;

}

auth_basic指令:

语法:auth_basic string | off;

默认:auth_basic off;

开启/关闭基于“HTTP Basic Authentication”协议的用户/密码认证。

auth_basic_user_file指令:

语法:auth_basic_user_file file;

默认:–

用于指定保存用户名和密码的文件,注意文件权限。

文件格式为:

name1:password1

name2:password2:comment

name3:password3

支持的密码类型:

用crypt()函数加密,工具有htpasswd、openssl passwd

使用基于md5的密码算法的Apache变体(apr1)

使用htpasswd实现nginx的认证

1、安装htpasswd,htpasswd是apache提供的密码生成工具

yuminstall httpd-tools -y

2、htpasswd用法

$ htpasswd -h

htpasswd:illegal option -- h

Usage:

    htpasswd[-cimBdpsDv] [-C cost] passwordfile username

    htpasswd-b[cmBdpsDv] [-C cost] passwordfile username password

    htpasswd-n[imBdps] [-C cost] username

    htpasswd-nb[mBdps] [-C cost] username password

-c  Createa new file.

-n  Don'tupdate file; display results on stdout.

-b  Usethe password from the command line rather than prompting for it.

-i  Readpassword from stdin without verification (for script usage).

-m  ForceMD5 encryption of the password (default).

-B  Forcebcrypt encryption of the password (very secure).

-C  Setthe computing time used for the bcrypt algorithm

     (higheris more secure but slower, default: 5, valid: 4 to 31).

-d  ForceCRYPT encryption of the password (8 chars max, insecure).

-s  ForceSHA encryption of the password (insecure).

-p  Donot encrypt the password (plaintext, insecure).

-D  Deletethe specified user.

-v  Verifypassword for the specified user.

3、创建用户密码文件

[roger@test ~]$ htpasswd -c/etc/nginx/passwd.db xiaoming ###新创建密码文件

New password:

Re-type new password:

Adding password for user xiaoming

[roger@test ~]$ htpasswd/etc/nginx/passwd.db xiaoli ###添加新的用户

New password:

Re-type new password:

Adding password for user xiaoli

[roger@test ~]$ cat/etc/nginx/passwd.db        ###查看文件内容格式

xiaoming:$apr1$OlmGwtmd$kG6fmWrQzCWEJGT/uWXsJ.

xiaoli:$apr1$UNkIjCHM$5h6Gigl1q.IZbq6yODzAv1

4、配置nginx

location / {

    auth_basic           "welcome";

    auth_basic_user_file /etc/nginx/passwd.db;

}

访问相关内容的时候将会认证

650) this.width=650;" src="https://s5.51cto.com/wyfs02/M02/08/B3/wKiom1nl1oSDZw2SAAAZ63BET1Y888.png" title="TIM图片20171017180650.png" alt="wKiom1nl1oSDZw2SAAAZ63BET1Y888.png" />

使用对应的用户名密码可以登录访问。

端口映射+nginx对外请求控制

前几天接到个任务,要和另一家公司对接,具体就是我这开一个接口给对面调用.因为一开始在内网测试,那问题来了,怎么才能让对面访问到呢?

​ 当然是找运维大兄弟…..操作也很简单,就是用路由做一个端口映射,用公网ip做一个端口映射到我本机地址.这样外网就能访问到我的tomcat了.

比如说公网ip是192.168.1.0,我的ip是192.168.1.1,tomcat端口是8080.

那就在路由上配一个端口9876直接映射到本地tomcat 192.168.1.1:8080.那现在外网就可以通过http://192.168.1.0:9876/访问到本地http://192.168.1.1:8080/了.

就这样,做好了接口,问题又来了,因为这个接口是在核心系统里,那这样就会把所有的接口都暴露了,肯定不行..

怎么做呢,怎么才能拦截这些请求呢? 当然又去问了运维大兄弟,再查了些资料,得知用Nginx可以只允许访问指定的url,其他的都直接对外禁止访问.

那怎么做呢?

重新修改下映射规则,不直接映射到tomcat,先经过nginx,通过nginx再把请求发送到tomcat.

这里就重新映射一个端口8000,在nginx中监听这个端口,然后再配置访问规则,再代理到tomcat

在nginx.config中添加一段server

server {
#监听8080端口,这个8080是路由映射到本机的端口
listen 8000;
server_name 0.0.0.0;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#阻止所有请求,这里将永远输出403错误
deny all;
}
#允许访问 /test/processe接口
location ~ /test/processe {
# 代理本地项目url
proxy_pass http://192.168.4.48:8080;
}
#如果还有其他接口,就再添加一个location
#location ~ /test/processe1 {
#proxy_pass http://192.168.4.48:8080;
#}
#location ~ /test/processe2 {
#proxy_pass http://192.168.4.48:8080;
#}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

这里的流程就是,外网通过访问公网ip+给定的端口,在路由根据映射规则,再访问到我这台电脑,这个时候请求不是直接去访问本机的接口,而是进入了Nginx,在这里,会去检查请求的url是否与配置允许的地址相同,不同的话就会403 Forbidden错误啦,当uri是/test/processe时,就能访问实际代理的http://192.168.4.48:8080/test/processe接口了

那这样就可以让对面只能访问指定的接口

配置laravel的nginx站点

server{}配置

server{
        #端口配置
        listen 80;
        #域名配置
        server_name laravel.cc;

        index index.php index.html index.htm;
        #站点配置到public
        root /data/wwwroot/laravel.cc/public;
      #日志记录
        access_log /data/logs/nginx.laravel.cc.log access;
        error_log /data/logs/nginx.laravel.cc.error debug;
     #静态文件配置
        location ~ .*.(jpg|jpeg|gif|png|bmp|css|js|swf|txt|ttf|woff|ico)$ {
                expires 7d;
                break;
        }

        location / {
         #重点区
                try_files $uri $uri/ /index.php?$query_string;
                index index.php index.html index.htm;
        }
        #静态文件配置
        location /logs {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
                break;
        }
        #处理php配置
        location ~ ".php$" {
                include fastcgi_params;
                fastcgi_index index.php;
                #在nginx.conf配置server_mango
                fastcgi_pass server_mango;
        }
}

http下的server_mango配置
  

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"';

    log_format access '$remote_addr [$time_local] "$http_host" "$request" "$status $body_bytes_sent" "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;

    sendfile        on;
    tcp_nopush     on;
    server_tokens       off;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip on;
    gzip_min_length  5k;
    gzip_buffers     4 16k;
    #gzip_http_version 1.0;
    gzip_comp_level 3;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary on;
    #重点区与server{}中的处理php应用到的
    upstream server_mango {
        server 127.0.0.1:9000;
    }
    #加载vhost下的.conf后缀所有文件
    include /usr/local/nginx/conf/vhost/*.conf;
}

Nginx版本无缝升级

/usr/local/nginx/sbin/nginx -V     #查看版本
nginx version: nginx/1.4.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-ld-opt='-ljemalloc' #注意这里的编译项
cd lnmp/src
wget http://nginx.org/download/nginx-1.4.4.tar.gz
tar xzf nginx-1.4.4.tar.gz
cd nginx-1.4.4
./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-ld-opt='-ljemalloc'
make    //注意只make  不要make install
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx$(date +%m%d)    #备份nginx原文件
cp objs/nginx /usr/local/nginx/sbin/nginx     #复制编译make后的文件覆盖nginx原文件
/usr/local/nginx/sbin/nginx -t     #检测nginx文件配置
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`    #把nginx.pid改成nginx.pid.oldbin跟着启动新的nginx
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`   #退出旧的nignx

Nginx下wordpress 固定链接更改后404问题解决

安装好wordpress后默认文章固定链接后缀是 ?p=xx之类的,这样的链接虽然挺简洁,但对SEO不利。

在后台自定义固定链接后,打开网站除首页外,其他页面都是404。这是由于没有设置好Nginx对wordpress的rewrite规则,google了一些解决办法,说的都是要在Nginx的配置文件写入

server{

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

}

但是写上以上代码仍然不起作用。于是google到Nginx官网上对于wordpress的rewrite规则说明,照着例子改了自己的Nginx配置,参考如下

upstream php {
        server unix:/tmp/php-cgi.socket;
        server 127.0.0.1:9000;
}

server {
    listen 80;
    server_name www.zhenglinbo.com zhenglinbo.com;

    root /var/www/blog;
    index index.html index.htm index.php;

    location / {

      try_files $uri $uri/ /index.php?$args;

    }

    location ~ .php$ {
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include fastcgi.conf;
                fastcgi_intercept_errors on;
                fastcgi_pass php;
        }

    location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }

    error_page 404 /error/index.html;
        location = /40x.html {
    }   

}

成功!使用自定义的文章固定链接为 /post-%post_id%.html 。

附Nginx官网对wordpress的rewrite规则说明:https://www.nginx.com/resources/wiki/start/topics/recipes/wordpress/

NGINX,APACHE开启文件目录浏览功能

我们都知道在apache下可以配置访问web服务器的某个路径时,自动显示其目录下面的文件列表的,其实Nginx一点也不比apache弱,它当然也可以实现这个功能,而且还非常容易和简单;主要用到autoindex 这个参数来开启,其配置如下:

复制代码代码如下:

location / {
root /data/www/file                     //指定实际目录绝对路径;
autoindex on;                            //开启目录浏览功能;
autoindex_exact_size off;            //关闭详细文件大小统计,让文件大小显示MB,GB单位,默认为b;
autoindex_localtime on;              //开启以服务器本地时区显示文件修改日期!
}

如上配置后,用IE访问该服务器的根目录,就会显示出 /data/www/file目录下的所有文件列表,Nginx目录浏览效果图:

未分类

为了备忘,最后将apache下的配置方法也记录一下!实现效果和上面一样!

复制代码代码如下:

Alias / ”/data/www/file”
< Directory  ”/data/www/file” >
Options Indexes                                               //开启目录列表索引模式
Order allow,deny
IndexOptions  NameWidth = 25   Charset = UTF -8     //设定文件名显示长度,文字字符编码
Allow from all
</ Directory >

Docker配置Hexo+Git+Nginx

未分类

功能需求

像我这种Tototototo Young的码字儿的总喜欢追求逼格,原来用博客园onenote可以直接导入,后来就想迁移到自己云主机上

为了保证服务器环境的干净(强迫症晚期),将整套环境封装进docker中

如果想要8003直接绑定到域名上,见另一篇Docker配置Nginx反向代理

解决方案

  • Hexo+Github的构建博客资料网上有很多,不赘述,不使用这种方法

  • Hexo+Git+Nginx+云主机上构建服务器资料也不少,如果想要配置过程的邮件私聊我

  • Hexo+Git+Nginx+云主机+Docker,今天使用这种方法构建,镜像还没有push到Docker源,有需要的私聊~

实现思路

Hexo是基于Nodejs的一个框架,将markdown文件解析生成html静态文件

通过Git将本地的html文件拉取到云主机上,存入nginx站点目录供解析

Docker容器需要开放两个端口,80用于nginx解析,22端口给git推送博客页面,宿主机监听8003和8004端口

镜像以Centos为基础镜像,拉取NodeJS,使用yum安装Nginx,Git,OpenSSH
但由于需要配置ssh的公钥私钥,则在实例化镜像后再进入容器配置ssh

主机环境

  • 宿主机环境
    centos Linux release 7.3.1611 (Core)
    docker version 17.06.1-ce, build 874a737
    node v8.4.0
    npm 5.3.0

  • 容器环境
    centos Linux release 7.4.1708 (Core)
    nginx version: nginx/1.12.1
    git version 1.8.3.1

  • 容器目录
    git库: /root/blogs.git
    nginx: /etc/nginx/conf.d/default.conf
    blog文件: /usr/share/nginx/html
    ssh私钥: /root/.ssh/authorized_keys

前期准备

  • 宿主机已有nodejs环境并可运行,根目录在/usr/local/node

  • 宿主机安装docker

  • 电脑端安装git

构建Dockerfile

拉取Centos镜像

$ sudo docker pull centos

编辑Dockerfile文件

FROM centos:latest # 基于centos
COPY . /usr/local/node # 将node环境复制
RUN 
        yum install -y wget &&  # 安装wget
        mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup &&  # 备份yum源
        wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo &&  # 更换yum源为阿里源
        yum clean all &&  # yum缓存
        yum makecache && 
        rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm &&  # 获取nginx的yum源
        yum install -y nginx &&  # 安装nginx
        yum install -y git &&  # 安装git
        yum install -y vim &&  # 安装vim
        git init --bare ~/blogs.git &&  # 创建git库
        echo "git --work-tree=/usr/share/nginx/html --git-dir=/root/blogs.git checkout -f" >~/blogs.git/hooks/post-receive &&  # 创建git勾子用于拉取hexo推送的信息
        chmod a+x ~/blogs.git/hooks/post-receive &&  # 给勾子执行权限
        yum install -y openssh openssh-server openssh-clients &&  # 安装ssh服务
        ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key &&  # 生成服务端钥匙
        ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && 
        ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
EXPOSE 22 # 暴露22端口用于ssh连接,git拉取页面
EXPOSE 80 # 暴露80端口用于nginx服务
CMD ["nginx","-g","daemon off;"] # nginx服务命令,必须使用daemon守护进程

Docker容器后台运行,就必须有一个前台进程,如果CMD仅执行nginx,那么nginx执行完后台启动后,会立即自杀,docker容器状态会变为exited

docker容器必须有一个常驻的前台进程,所以使用daemon,使pid=1的进程不是/bin/bash而退出

构建镜像与容器

构建镜像

$ docker build -t hexoblogs . // 构建新镜像,注意不要少了最后的点
Successfully built 70eaeb40d97b
Successfully tagged hughdong/hexoblogs:latest

实例化容器并映射到宿主机端口,后台运行容器

$ sudo docker run --name dhblogs -p 8003:80 -p 8004:22 -d hexoblogs:latest

查看容器情况,当看到Status是UP且能看到Ports端口情况时为正常

$ sudo docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                        NAMES
c58e2a73f117        hexoblogs:latest         "nginx -g 'daemon ..."   12 minutes ago      Up 12 minutes       0.0.0.0:8004->22/tcp, 0.0.0.0:8003->80/tcp   dhblogs

测试镜像

浏览器输入http://...:8003/是否显示nginx测试页

未分类

配置ssh

获取本地ssh公钥,电脑端打开git bash

$ ssh-keygen

一路回车下去,然后打开C:UsersUsername.sshid_rsa.pub,复制内容,username是自己的电脑账户名

从宿主机进入Docker容器

$ sudo docker exec -it dhblogs /bin/bash

进入容器后执行以下步骤

# echo "*******************************" > ~/.ssh/authorized_keys // 复制的公钥,替换掉命令的******
# chmod 600 ~/.ssh/authorized_keys // 赋予权限
# chmod 700 ~/.ssh
# /usr/sbin/sshd // 启动ssh服务

本地测试ssh并互换秘钥

本地git bash执行

$ ssh root@***.***.***.*** -p 8004 // 前面是宿主机ip后面是端口

首次执行ssh时需要输入yes连接,之后hexo才能正常推送

未分类

如果报错ERROR

ERROR // 如果多次更换docker,同配置ssh连接时需要删除客户机的known_hosts
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE HOST IDENTIFICATION HASCHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

C:Usershughd.sshknown_hosts 删除该主机对应的旧信息即可

本地配置ssh配置文件

打开C:Usershughd.ssh,如果没有config文件则创建新的

Host是云主机ip地址,Port是容器映射到宿主机的端口8004

Host ***.***.***.***
Port ***

本地配置hexo

nodejs和npm安装过程略

$ npm install -g hexo-cli
$ npm install hexo-deployer-git --save 
$ npm install hexo-server
$ hexo init f:/6.Code/GitBlogs // 初始化hexo
$ npm install

配置本地hexo的_config.yml

# Site
title: Hugh
subtitle: Mad web developers
description:
author: HughDong
language: zh-CN
timezone: Asia/Shanghai
# Deployment
deploy:
  type: git
  repo: root@***.***.***.***:/root/blogs.git
  branch: master

生成并推送博客,看到回显服务器端files文件更新则成功

$ hexo clean && hexo g -d
[master 29390bd] Site updated: 2017-10-13 11:03:15 9 files changed, 23 insertions(+), 23 deletions(-)
Branch master set up to track remote branch master from root@***.***.***.***:/root/blogs.git.
To ***.***.***.***:/root/blogs.git   aa45a3e..29390bd  HEAD -> master
INFO  Deploy done: git