SegmentFault i折腾最新的文章
2016-12-23T15:06:20+08:00
https://segmentfault.com/feeds/blogs
https://creativecommons.org/licenses/by-nc-nd/4.0/
使用 https, 并将 WWW 跳转到 NON-WWW
https://segmentfault.com/a/1190000007900112
2016-12-23T15:06:20+08:00
2016-12-23T15:06:20+08:00
WensonSmith
https://segmentfault.com/u/wensonsmith
0
<h2>0x01: 背景</h2>
<p>博客经常不更新,服务器还时不时挂掉一次,导致 PageRank 基本是负的了,不过技术上要跟的上更新啊! 微信小程序接口必须是 https, 这次就当是练手了。</p>
<h2>0x02: 整体思路流程</h2>
<ol>
<li><p>确保自己的域名解析全部是 <code>A 记录</code></p></li>
<li><p>使用 <a href="https://link.segmentfault.com/?enc=Mdv6TLktRevB9HklZ0T9kg%3D%3D.PixBgtvnMjK%2Br1YdqfadUV%2Bow%2FzVXVIzJqa%2BeZvhlTM%3D" rel="nofollow">Let's Encrypt</a> 证书, <a href="https://link.segmentfault.com/?enc=nwGZxSzLWjMviNiE%2FofvLg%3D%3D.9AQQlLVlXHZswskWZj35zpUSD0Dr%2BWlWYqRh2Cg%2BuwY%3D" rel="nofollow">Certbot</a> 安装证书</p></li>
<li><p>使用 <code>Crontab</code> 自动 <code>Renew</code> 证书</p></li>
<li><p>配置 Nginx ,<code>SSL Server</code></p></li>
<li><p>将 HTTP 跳转到 HTTPS , 将 <code>WWW</code> 跳转到 <code>NON-WWW</code></p></li>
<li><p>用检测工具检测一下自己 HTTPS 的评级</p></li>
</ol>
<h2>0x03: 检查自己的域名解析是否是A记录</h2>
<p>刚开始使用 <code>Certbot</code> 安装证书的时候,老是报错,经过搜索发现,原来自己的域名有 <code>CNAME</code> 解析的。 所以在安装证书钱,请确保自己的域名都是A记录解析</p>
<h2>0x04: 使用免费的 Let's Encrypt 证书</h2>
<p>关于免费的证书,这里有其他选项可供选择:</p>
<ul>
<li><p>阿里云免费的 : <a href="https://link.segmentfault.com/?enc=9SGqLyakC4Ugnd88mmSnAw%3D%3D.BV4k1xSe8M2s9IwRLKzhkFr%2BaKDaNiNcUkod3zdHo20c9BeNgY82yOWGOflzQ9o8zloOEYa2SxNTOe9aZPeZyA%3D%3D" rel="nofollow">Symantec 证书</a></p></li>
<li><p>Let's Encrypt :<a href="https://link.segmentfault.com/?enc=XO9nIQn6VyHOpoAju8o0tQ%3D%3D.xWRPVnCUvug5bFy65rGJKd6mvEKWj%2FEjt61Bswm3mEI%3D" rel="nofollow">免费证书</a></p></li>
<li><p>一站式解决方案: <a href="https://link.segmentfault.com/?enc=YrakZsxTwADp%2BGPYq5wkcg%3D%3D.Z%2F6aySwskYN0ppXcHf8AzljtIZdT07txXFOhBok73PM%3D" rel="nofollow">cloudflare</a></p></li>
</ul>
<p>根据 Lets' Encrypt 官网说明,我们使用推荐的 <code>Certbot</code> 安装我们的证书。 当然你也可以选择 <a href="https://link.segmentfault.com/?enc=LPIBP8dSp%2B%2FQ%2ByZizcuIgg%3D%3D.GCDBlhTABhgrUtThgkc%2BYfxQtouYRjCClPD59CeyxPFLwWOy%2FnHvMjrmE%2BRARVAh" rel="nofollow">acme-tiny</a> 来安装证书。<br>我的服务器环境是 <code>CentOS 7</code> 和 <code>Nginx/1.10.1</code>, 这里强烈推荐大家将Nginx 升级到最新的版本,新版本在SSL配置上比较省事。</p>
<pre><code class="sh">//安装Certbot
sudo yum install certbot
//安装命令很简单, -w 后面跟网站根目录, -d 就是你要添加证书的域名,如果有多个域名,多个-d就可以了
certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com</code></pre>
<p>如果顺利,他会提示出安装成功,证书会保存在 <code>/etc/letsencrypt/live/example.com/</code> 里面。</p>
<h2>0x05: 使用 Crontab 定时Renew 证书</h2>
<p>因为是免费证书, 所以有一个有效期是90天,到期之后需要 <code>Renew</code> 一下。 官方推荐是每天检查用任务 <code>Renew</code> 两次,因为如果证书没过期,他就只是检测一下,并不会做其他操作。这里我们设置的定时任务是每天检查一次。</p>
<pre><code class="bash">$ crontab -e
10 6 * * * certbot renew --quiet
//列出任务看看是否添加成功
$ crontab -l</code></pre>
<h2>0x06: 配置NGINX, SSL Server</h2>
<p>节约生命,请使用神器: Mozilla出品的 <a href="https://link.segmentfault.com/?enc=sL2rsUCh9HY%2BLlymozwMOg%3D%3D.eZIvwMFjQLfUFVQSiQHhsNf8XT3mXEDU21601Gve56xEhKxXAxFVK%2Fa%2FIE5Fgm7Rs2nRnymz48aZshBT7tdPrw%3D%3D" rel="nofollow">SSL配置生成器</a><br>使用生成器需要填写 <code>nginx</code> 和 <code>openssl</code> 版本, 用下面命令进行查看</p>
<pre><code class="sh">//查看nginx版本
nginx -v
//查看openssl 版本
yum info openssl
//如果需要更新openssl
yum update openssl</code></pre>
<p>下面就是我生成的配置(nginx: 1.10.1, openssl: 1.0.1e)</p>
<pre><code class="sh">server {
server_name example.com wwww.example.com;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /etc/letsencrypt/live/example.com/dhparam.pem;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
## verify chain of trust of OCSP response using Root CA and Intermediate certs
#ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;
#resolver <IP DNS resolver>;
server_name example.com;
index index.html;
root /home/wwwroot/example.com;
location ~ .*\.(ico|gif|jpg|jpeg|png|bmp|swf)$
{
access_log off;
expires 1d;
}
location ~ .*\.(js|css|txt|xml)?$
{
access_log off;
expires 12h;
}
location / {
try_files $uri $uri/ =404;
}
access_log /home/wwwlogs/example.com.log access;
}</code></pre>
<p>上面配置的第一个 <code>Server</code> 将所有的 http 请求跳转到 https 请求上。 其中 <code>ssl_dhparam</code> 这个参数的 <code>.pem</code> 用下面命令生成:</p>
<pre><code class="sh">openssl dhparam -out /etc/letsencrypt/live/example.com/dhparam.pem 2048</code></pre>
<p>现在加上https看一下效果吧!</p>
<h2>0x07: 将WWW跳转到NON-WWW</h2>
<p>为了SEO,网站使用 WWW 前缀,或者全部不使用 WWW,要实现的效果就是将下面三种情况,<br>统统跳转到 <code>https://example.com</code></p>
<pre><code>http://example.com
http://www.example.com
https://www.example.com</code></pre>
<p>0x06中的配置,第一个 <code>server</code> 已经将处理好钱两种情况, 现在来处理第三种情况。<br>这个配置主要需要<code>注意</code>的是,这里也要加上所有的 <code>ssl</code> 配置参数。</p>
<pre><code class="sh">server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /etc/letsencrypt/live/example.com/dhparam.pem;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
## verify chain of trust of OCSP response using Root CA and Intermediate certs
#ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;
server_name www.example.com;
return 301 https://example.com$request_uri;
}</code></pre>
<h2>0x08: 工具</h2>
<ul>
<li><p><a href="https://link.segmentfault.com/?enc=JAMoAupO52YSWsnkIvFWDg%3D%3D.zRUxu%2FM0a5gFfyrxL8hMrkEHMnCRVj4JABP0G2N6rI6G0rMSbPiDeCAqXFy4IU%2FZ" rel="nofollow">ssllabs 测试评级</a></p></li>
<li><p><a href="https://link.segmentfault.com/?enc=KGj81gm92ZGpWJTQ7uuuIA%3D%3D.odA0CjSh6malZLheCSa4taJOA%2FYQhvOXj09F8t5J9rM%3D" rel="nofollow">securityheaders 测试评级</a></p></li>
<li><p><a href="https://link.segmentfault.com/?enc=i6o9A3snBM9C6P%2F%2FjjX0KA%3D%3D.MYSHdNAbqCoLCck7Sb%2BOMVco2ngeZ4JDDzW1utoMhD2U8W3Uvxb%2BKXL2mtv7H3nk4cxeZ7CvkEkI35a553cgmA%3D%3D" rel="nofollow">Mozilla出品的 SSL配置生成器</a></p></li>
</ul>
NodeJS和NW通过ffi调用dll/so动态库
https://segmentfault.com/a/1190000006826851
2016-09-06T10:00:00+08:00
2016-09-06T10:00:00+08:00
WensonSmith
https://segmentfault.com/u/wensonsmith
5
<h2>0x01. 使用的 npm 包</h2>
<p>首先要安装 <code>node-gyp</code>, 用来重新编译依赖包。</p>
<pre><code class="sh">npm instal -g node-gyp</code></pre>
<p>然后主要用到下面三个包:</p>
<ul>
<li><p><a href="https://link.segmentfault.com/?enc=FF1OjFK5lmcPKmKxA986kQ%3D%3D.HFfiAicUk9OeBnT3FtxJSNVo6o0g26EpcLqCRhThmpP3tEpWhPFpTr9Ri2qa%2F2UD" rel="nofollow">node-ffi</a> -- 使用<code>Javascript</code>调用动态库</p></li>
<li><p><a href="https://link.segmentfault.com/?enc=qPv1sh4cGssGbv3b%2BRJDjg%3D%3D.3IF%2BBD8197BxSkZpnPwKLkp0Pq8dGLehCnIiaTPGQqftE34tKLnNxgm%2FQGwfkiKV" rel="nofollow">ref</a> -- 用来定义数据类型,提供指针功能</p></li>
<li><p><a href="https://link.segmentfault.com/?enc=GNH0tlNGgI18KYGMHlDQiA%3D%3D.XWV4Bu5SXFT43zbKPBMMSdkXSMh8GnS11nyT7vxOg%2Fkoz7OMXp1CpwflPoMNiwFS" rel="nofollow">ref-array</a> -- 用<code>Buffer</code>来实现C语言中的 <code>array</code> 数据类型</p></li>
</ul>
<pre><code class="sh">npm install ffi //这个命令会同时安装上 ref、ref-struct
npm instal ref-array</code></pre>
<h2>0x02. 测试NODEJS调用</h2>
<p>要使用动态库中的函数,首先要对动态库里的函数进行声明。<br>比如在 <code>Test.dll</code> 库中,有两个函数如下:</p>
<pre><code class="c">void init(string name, int port);
string hello(int times);</code></pre>
<p>在 <code>js</code>中进行声明的方法如下:</p>
<pre><code class="js">var ffi = require('ffi');
var Test = ffi.Library('Test.dll',{
'init': ['void',['string','int']],
'hello': ['string', ['int']]
});
#规则就是
'函数名':['返回值数据类型':['参数数据类型',...,'参数数据类型']]
</code></pre>
<p>声明完成后,就可以进行调用了</p>
<pre><code class="js">Test.init('COM1', 9300);
Test.hello(5);</code></pre>
<p>这里用简单的数据类型,来讲解调用动态库的大致流程。剩下比较复杂的地方在于如何模拟像 <code>指针</code>、<code>结构体</code>、<code>数组</code> 等比较复杂的数据类型。</p>
<h2>0x03. 结构体、指针、数组的转化</h2>
<h3>1. 结构体</h3>
<p>结构体需要用到'ref-struct'这个包。假设有以下结构体:</p>
<pre><code class="c">typedef struct {
byte UID[16]; /*餐盘标签 UID,16 进制*/
byte UType[6]; /*餐盘类型,10 进制*/
int ProdNo; /*菜品编码,10 进制*/
int ProdPrice; /*菜品价格,价格以分为单位,10 进制*/
} DishInfo;</code></pre>
<p><code>int</code>类型的好办,可以直接使用 <code>ref</code>包里含有的类型 <code>ref.types.int</code>。 <br><code>UID</code>和<code>UType</code>是两个<code>bype</code>类型的数组,需要使用<code>ref-array</code>进行模拟。</p>
<pre><code class="js">var refStruct = require('ref-struct');
var refArray = require('ref-array');
var DishInfo = refStruct({
'UID': refArray('byte', 16),
'UType': refArray('byte', 6),
'ProdNo': ref.types.int,
'ProdPrice': ref.types.int
});</code></pre>
<h3>2. 指针和引用</h3>
<p>假设动态库中有函数如下, 第二个参数为结构体指针, 第三个参数是一个<code>int</code> 引用。</p>
<pre><code class="c">int Read(int port, DishInfo * pInfo, int &Count);</code></pre>
<p>在声明函数的时候,就需要指明指针和引用的数据类型。示例如下:</p>
<pre><code class="js">var ffi = require('ffi');
var ref = require('ref');
var refStruct = require('ref-struct');
var refArray = require('ref-array');
var DishInfo = refStruct({
'UID': refArray('byte', 16),
'UType': refArray('byte', 6),
'ProdNo': ref.types.int,
'ProdPrice': ref.types.int
});
//数据类型
var intPointer = ref.refType('int');
var DishInfoArrType = refArray(DishInfo); //定义了DishInfo数组类型
var Test = ffi.Library('Test.dll',{
'init': ['void',['string','int']],
'hello': ['string', ['int']],
'Read': ['int', ['int', DishInfoArrType, intPointer]]
});
//实例化
var count = ref.alloc('int');
var DishInfoArr = DishInfoArrType(3);
Test.Read(11, DishInfoArray, count);
//使用deref()获取引用的实际值
var actualCount = count.deref();</code></pre>
<h2>0x04. NW 适配</h2>
<p>使用NodeJS直接调用没问题后,就可以使用 node-gyp 编译适配 NW 的包了, 这里只说明window环境下的使用方法。</p>
<h3>1. 搭建编译环境</h3>
<ol>
<li>
<p>安装 <a href="https://link.segmentfault.com/?enc=sLHFaLs6acgUuy1zvaWwZQ%3D%3D.VjcYi39j%2FBWy73FeyC4beJGvc8By4mF6vClQm0uaJm4T9209lvYCvZwAs1nA55ut38q8QTjQSi%2B8YfiUHoevene0cDF7WkCDXIsQegVI5E4%3D" rel="nofollow">Visual Studio 2015</a></p>
<pre><code>> ? [Windows Vista / 7 only] 需要安装 [.NET Framework 4.5.1](http://www.microsoft.com/en-us/download/details.aspx?id=40773)
</code></pre>
</li>
<li>
<p>安装 <a href="https://link.segmentfault.com/?enc=6GFUhHipXfRpwBc7qAvMpg%3D%3D.5Jclhgpq0iehl0Z6synSOQVTUk46GxZ9%2BonCA0b8Pu%2BO3%2Fiq9O%2B3atOL25YXZK3T" rel="nofollow">python 2.7</a> (不要装3.x.x,不支持),装完后运行</p>
<pre><code>npm config set python python2.7</code></pre>
</li>
<li>
<p>设置visualstudio版本</p>
<pre><code>npm config set msvs_version 2015</code></pre>
</li>
</ol>
<h3>2. 修改 win_delay_load.cc</h3>
<p>打开 Github - nw.js repository, 然后切换自己使用的nw 版本分支。<br><img src="/img/remote/1460000006826854" alt="nwjs选择分支" title="nwjs选择分支"></p>
<p>我这里选择的是 nw14, 然后找到 <code>tools/win_delay_load_hook.cc</code>, 下载替换掉 <code>%APPDATA%\npm\node_modules\node-gyp\src\win_delay_load_hook.cc</code></p>
<h3>3. node-gyp 重编译 ffi 和 ref</h3>
<pre><code class="sh"># --target 输入nw 版本号,这里实用的是 v0.14.3, arch为 ia32 或者 x64
cd node_modules/ffi
node-gyp configure --target=0.14.3 --arch=ia32
node-gyp build
cd node_modules/ref
node-gyp configure --target=0.14.3 --arch=ia32
node-gyp build
</code></pre>
<h2>0x05. 参考资料</h2>
<ol>
<li><p><a href="https://link.segmentfault.com/?enc=kShc4QQ1MAj0oC4g2IMzEg%3D%3D.rbUAzPMduET1HLBA8ACdf0ncixJVuv80pcVG8u2QBd%2BxZuYiF0qlWKZbU5xRlDAt" rel="nofollow">通过ffi在node.js中调用动态链接库(.so/.dll文件)</a></p></li>
<li><p><a href="https://link.segmentfault.com/?enc=mcmcWtmcDDPLS9JezwEa8Q%3D%3D.h5NyUrCQssMyovwAh3Mgzevd4voOn0J3AJlzcuFkWsPde5VMYV6LYJJbo6eYl6trb2Zz48n4zCuKLhLUPIU%2FSTyF58sOqYotds3M1fcf5XwOC71LIYNyiaPXkJI8T6%2Bf" rel="nofollow">Use Native Node Modules</a></p></li>
<li><p><a href="https://link.segmentfault.com/?enc=c3Y4T2mfU%2BO9%2FSy3OBayPg%3D%3D.6Z%2B2IveVXHsYsvMdLE%2B8N0BVd0O1Yi7nVd0Dv4drkgA%3D" rel="nofollow">厚颜无耻加上自己的博客 XD </a></p></li>
</ol>
阿里云VPS搭建自己的的Hexo博客
https://segmentfault.com/a/1190000005723321
2016-06-15T11:42:23+08:00
2016-06-15T11:42:23+08:00
WensonSmith
https://segmentfault.com/u/wensonsmith
18
<h2>1. 博客的架构</h2>
<p>先搞明白Hexo博客从搭建到自动发布的架构,才能更好的理解我们每一步进行的操作。<br>不然只跟着步骤过了一遍,却不知道为什么这么做。</p>
<p>首先看这张架构图:<br><img src="/img/remote/1460000005723405" alt="Hexo-Structure" title="Hexo-Structure"></p>
<p>整个流程就是本地将 <code>*.md</code> 渲染成静态文件,然后Git推送到服务器的<code>repository</code>,服务器再通过 <code>git-hooks</code> 同步网站根目录。</p>
<h2>2. 整个搭建流程</h2>
<p><strong>第一部分</strong>: 服务器环境搭建,包括安装 <code>Git</code> 、<code>Nginx</code>配置 、创建 <code>git</code> 用户 。</p>
<p><strong>第二部分</strong>: 本地<code>Hexo</code>初始化, 包括安装 <code>NodeJS</code> 、<code>hexo-cli</code>, 生成本地静态网站</p>
<p><strong>第三部分</strong>: 使用Git自动化部署发布博客</p>
<h2>3. 服务器环境搭建</h2>
<h4>3-1.安装Git和NodeJS (CentOS 环境)</h4>
<pre><code class="sh">yum install git
#安装NodeJS
curl --silent --location https://rpm.nodesource.com/setup_5.x | bash -</code></pre>
<p>NodeJS 安装可以参考: <a href="https://link.segmentfault.com/?enc=XQ99CwZDQv%2FjAd4ye3koqw%3D%3D.myqp4gORdPx7uJnRvJS37GoY6bQo6S87cZdQlYPJEMk9ZrgqjaRzuU4IvxQtb%2FKD" rel="nofollow">Linux安装NodeJS</a></p>
<h4>3-2. 创建git用户</h4>
<pre><code class="sh">adduser git
chmod 740 /etc/sudoers
vim /etc/sudoers</code></pre>
<p>找到以下内容</p>
<pre><code class="sh">## Allow root to run any commands anywhere
root ALL=(ALL) ALL</code></pre>
<p>在下面添加一行</p>
<pre><code class="sh">git ALL=(ALL) ALL</code></pre>
<p>保存退出后改回权限</p>
<pre><code class="sh">chmod 400 /etc/sudoers</code></pre>
<p>随后设置Git用户的密码,</p>
<pre><code class="sh">#需要root权限
sudo passwd git</code></pre>
<p>切换至git用户,创建 <code>~/.ssh</code> 文件夹和 <code>~/.ssh/authorized_keys </code>文件,并赋予相应的权限</p>
<pre><code class="sh">su git
mkdir ~/.ssh
vim ~/.ssh/authorized_keys
#然后将电脑中执行 cat ~/.ssh/id_rsa.pub | pbcopy ,将公钥复制粘贴到authorized_keys
chmod 600 ~/.ssh/authorzied_keys
chmod 700 ~/.ssh</code></pre>
<p>然后就可以执行ssh 命令测试是否可以免密登录</p>
<pre><code class="sh">ssh -v git@SERVER</code></pre>
<p>至此,Git用户添加完成</p>
<h4>3-3. Nginx安装和配置</h4>
<p>我是用的是lnmp 一键安装包,nginx安装教程一大堆,就不再叙述。主要看nginx配置。<br>找到nginx的配置文件,修改配置如下:</p>
<pre><code class="sh">server
{
listen 80;
#listen [::]:80;
server_name www.seekbetter.me seekbetter.me;
index index.html index.htm index.php default.html default.htm default.php;
#这里要改成网站的根目录
root /path/to/www;
include other.conf;
#error_page 404 /404.html;
location ~ .*\.(ico|gif|jpg|jpeg|png|bmp|swf)$
{
access_log off;
expires 1d;
}
location ~ .*\.(js|css|txt|xml)?$
{
access_log off;
expires 12h;
}
location / {
try_files $uri $uri/ =404;
}
access_log /home/wwwlogs/blog.log access;
}</code></pre>
<h2>4. 本地Hexo程序</h2>
<h4>4-1:初始化Hexo博客</h4>
<p>首先要安装 <code>hexo-cli</code>,安装<code>hexo-cli</code> 需要 root 权限,使用 <code>sudo</code> 运行</p>
<pre><code class="sh">sudo npm install -g hexo-cli</code></pre>
<p>然后初始化Hexo程序</p>
<pre><code class="sh">cd ~/Documents/code
hexo init blog</code></pre>
<p>等执行成功以后安装两个插件, <code>hexo-deployer-git</code> 和 <code>hexo-server</code> ,这俩插件的作用分别是使用Git自动部署,和本地简单的服务器。</p>
<p><a href="https://link.segmentfault.com/?enc=eamQtFeOiSMeRtuJC%2BzL%2Bg%3D%3D.meCNaUzIW7ht1SwXZxxp4qUPlRtrE8E65SsUSLZQdQnGw0FyPKie5E33P2I4N65d" rel="nofollow">hexo-deployer-git帮助文档</a><br><a href="https://link.segmentfault.com/?enc=53ASm6DCkmAfXCKfUnLN%2Fw%3D%3D.V0%2Bedgfu%2FNL9LR0Ir9%2BPikjkK3lr4ebv%2BN%2BNa7vxcwjwmJZxiniJP0WvRZ%2FnpA%2BT" rel="nofollow">hexo-server帮助文档</a></p>
<pre><code class="sh">cd blog
npm install hexo-deployer-git --save
npm install hero-server</code></pre>
<h4>4-2. 生成自己的第一篇文章 hello world !</h4>
<p>使用 <code>hexo new <文章名称></code> 来新建文章,该命令会成成一个 <code>.md</code>文件放置在 <code>sources/_posts</code>文件夹。</p>
<pre><code class="sh">hexo new "hello Hexo"
vim sources/_posts/hello-hexo.md</code></pre>
<p>编辑完毕以后, 使用<code>hexo g</code>将 <code>.md</code>文件渲染成静态文件,然后启动<code>hexo-server</code>:</p>
<pre><code class="sh">hexo g
hexo server</code></pre>
<p>现在便可以打开浏览器访问 <code>http://localhost:4000</code> 来查看我们的博客了!</p>
<h2>5. 自动化部署</h2>
<h4>5-1:服务器上建立git裸库</h4>
<p>创建一个裸仓库,裸仓库就是只保存<code>git</code>信息的<code>Repository</code>, 首先切换到<code>git</code>用户确保<code>git</code>用户拥有仓库所有权<br>一定要加 <code>--bare</code>,这样才是一个裸库。</p>
<pre><code class="sh">su git
cd ~
git init --bare blog.git</code></pre>
<h4>5-2. 使用 git-hooks 同步网站根目录</h4>
<p>在这里我们使用的是 <code>post-receive</code>这个钩子,当git有收发的时候就会调用这个钩子。 在 <code>~/blog.git</code> 裸库的 <code>hooks</code>文件夹中,<br>新建<code>post-receive</code>文件。</p>
<pre><code class="sh">vim ~/blog.git/hooks/post-receive
#!/bin/sh
git --work-tree=/path/to/www --git-dir=~/blog.git checkout -f</code></pre>
<p>保存后,要赋予这个文件可执行权限</p>
<pre><code class="sh">chmod +x post-receive</code></pre>
<h4>5-3. 配置<code>_config.yml</code>,完成自动化部署</h4>
<p>然后打开 <code>_config.yml</code>, 找到 <code>deploy</code></p>
<pre><code class="javascript">deploy:
type: git
repo: git@SERVER:/home/git/blog.git //<repository url>
branch: master //这里填写分支 [branch]
message: 提交的信息 //自定义提交信息 (默认为 Site updated: {{ now('YYYY-MM-DD HH:mm:ss') }})</code></pre>
<p>保存后,尝试将我们刚才写的"hello hexo"部署到服务器</p>
<pre><code class="sh">hexo clean
hexo generate --deploy</code></pre>
<p>访问服务器地址,就可以看到我们写的文章"Hello hexo",以后写文章只需要:</p>
<pre><code class="sh">hexo new "Blog article name"
···写文章
hexo clean && hexo generate --deploy</code></pre>
<p>博客就更新咯!~</p>
<h4>参考资料:</h4>
<p><a href="https://link.segmentfault.com/?enc=fqPJwDrzejYbsb9vbczctg%3D%3D.3u65fCIk76f2XZVNVOiN5Gf8xH%2FvC8JmXYH6mLhcV%2FeShfo%2BZkGXILSDBdPXnR9C5xMtBem83qctBOPP5CImZA%3D%3D" rel="nofollow">使用 Git Hook 自动部署 Hexo 到个人 VPS</a><br><a href="https://link.segmentfault.com/?enc=7OraonI3NsOMpwmiIs%2F1vQ%3D%3D.rkF%2BTbQdKgrC%2BqPICf4St%2FE3CmP6HhVZ5JGzAvhBvLU%3D" rel="nofollow">Hexo 文档</a></p>
Ubuntu 15.10 使用 Xorg.conf 修改分辨率
https://segmentfault.com/a/1190000004510095
2016-02-29T14:54:46+08:00
2016-02-29T14:54:46+08:00
WensonSmith
https://segmentfault.com/u/wensonsmith
2
<p>Ubuntu 15.10装在中控机上,发现屏幕右边有黑边。 打开设置一看,分辨率不对。 1024x768的屏幕, 这里设置成了1280x1024, 而且只有一个选项。</p>
<p>这时候就需要使用 xorg.conf 来配置啦!</p>
<h3>文件位置</h3>
<p>早期的Ubuntu ,这个文件都是放置 <code>··/etc/X11/xorg.conf</code> ,但是早已废弃多年。现在需要自己创建,并放置于 <code>/usr/share/X11/xorg.conf.d/</code> 文件夹下面。</p>
<h3>xorg.conf 文件简介</h3>
<h4>一、xorg.conf的一般编写规则:</h4>
<p><code>xorg.conf</code> 文件保存有X Window的各种信息,它由数个 <code>Section/EndSecion</code></p>
<pre><code>的区块组成,格式如下:
</code></pre>
<pre><code class="sh">Section "Section名称"
选项名称 "选项值"
选项名称 "选项值"
……
EndSection</code></pre>
<pre><code>也就是说,一个区块以 `Section "Section` 名称"开头,以 `EndSection` 结尾,中间是选项。
</code></pre>
<h4>二、显示方面的设置主要包括三个区块:</h4>
<p><strong>monitor</strong> 设置显示器<br><strong>device</strong> 设置显卡<br><strong>screen</strong> 设置显示器与显卡的结合,也就是最终的显示</p>
<p>在显示设置方面,这三个区块似乎缺一不可。<br>下面提供一个范例:</p>
<pre><code class="sh">Section "Device"
Identifier "Whatever a Device name"
EndSection
Section "Monitor"
Identifier "Whatever a Monitor name"
EndSection
Section "Screen"
Identifier "Default Screen"
Monitor "Whatever a Monitor name"
Device "Whatever a Device name"
EndSection</code></pre>
<p>在这个范例当中 , <code>Identifier</code> 是自己取的名字,可以随便取。 然后在 <code>Screen</code> 的 <code>section</code>里面,Monitor 和 Device 分别对应自己取的名字。</p>
<h3>创建配置文件</h3>
<p>新建一个 10-monitor.conf 文件,先看具体配置,然后再细细说明</p>
<pre><code>Section "Device"
Identifier "Whatever a Device name"
EndSection
Section "Monitor"
Identifier "Whatever a Monitor name"
Modeline "1024x768_60.00" 63.50 1024 1072 1176 1326 768 771 775 798 -hsync +vsync
Option "PreferredMode" "1024x768_60.00"
EndSection
Section "Screen"
Identifier "Default Screen"
Monitor "Whatever a Monitor name"
Device "Whatever a Device name"
SubSection "Display"
Modes "1024x768"
EndSubSection
EndSection</code></pre>
<p>这里多出的就是<code>Modeline</code> 和下面 <code>Subsection "Display"</code> , 这个modeline 是很好获取的, 打开终端,运行:</p>
<pre><code class="sh">cvt 1024 768
//这里会输出
Modeline "1024x768_60.00" 63.50 1024 1072 1176 1326 768 771 775 798 -hsync +vsync</code></pre>
<p>后面的两位参数,很容易懂,就是分辨率。 然后把输出结果复制粘贴进去, Modeline 下面的Option 就很好理解了, 第一个参数不变, 第二个参数就是输出的Modeline里用引号包起来的这部分。</p>
<p>下面的 <code>SubSection "Display"</code> 直接复制粘贴,将 Modes后改为刚才设置的分辨率。 </p>
<p>然后重启看效果吧!</p>
<p>部分参考文章:</p>
<p><a href="https://link.segmentfault.com/?enc=qdJw%2BLhKjxQbYNXTcKoZ7w%3D%3D.kMxxHMhHU8tBVhBG0cRpFDl8N3gl6E1cf%2Fhnpf1ftYmFcK%2BgRY7yfIzfwT7yO%2B8YOKHhgQjqskHTaPyNTj3yHQ%3D%3D" rel="nofollow">人在井天 - 编写xorg.conf,简单三行解决ubuntu分辩率不可调的问题</a></p>
AngularJs 2 快速入门
https://segmentfault.com/a/1190000004506135
2016-02-28T20:44:30+08:00
2016-02-28T20:44:30+08:00
WensonSmith
https://segmentfault.com/u/wensonsmith
4
<blockquote><p>阅读文档时顺便翻译, 不好还请见谅! <a href="https://link.segmentfault.com/?enc=OAPYAGedFjoWMWR9IcwCXQ%3D%3D.BeAHm0Ix3aUiE%2FfzxHXYO8%2BDi2H47PZ4%2BcfhTDPHcqoPRZ%2FV8%2BaNoItlxnMhAHFKGWXV9Zay98UpB4Dv%2F5eQ4Q%3D%3D" rel="nofollow">原文需翻墙 Quickstart</a></p></blockquote>
<p>让我们从零开始,使用<code>Typescript</code>构建一个超级简单的 <code>AngularJs 2</code>应用。</p>
<h2>先跑一个DEMO</h2>
<p>运行这个 <a href="https://link.segmentfault.com/?enc=UoQMa3ghjxKrMieTXKOZ7g%3D%3D.odUHe2%2FheiMN7ePcIj3Urt9dcP53MiCt6vSlUBoUZg3N7mYHJGYQ1DPmO65nKUOpSgJiFdiTQqwaKle6zXxk%2FjNB3q99XfzKsaq7vCwKCmA%3D" rel="nofollow">DEMO</a>先来感受一下 AngularJS2 的应用。</p>
<p>下面是这个应用的文件结构</p>
<blockquote><p>angular2-app<br> |_ app<br> | |_ app.component.ts<br> | |_ main.ts<br> |_ index.html<br> |_ license.md</p></blockquote>
<p>总结来说就是一个 index.html 文件和两个在 app 文件下的 Typescript 文件, 我们可以hold住!</p>
<p>下面我们将一步一步的构建这样的一个程序:</p>
<ol>
<li><p>配置我们的开发环境</p></li>
<li><p>编写 Angular 初始化组件</p></li>
<li><p>引导它控制我们主要的 index.html 页面</p></li>
<li><p>编写index.html 页面</p></li>
</ol>
<h2>开发环境搭建</h2>
<h3>建立文件夹</h3>
<pre><code class="sh">mkdir angular2-app
cd angular2-app</code></pre>
<h3>配置Typescript</h3>
<p>需要通过一些特殊的设置来指导Typesript进行编译。<br>新建一个 <code>tsconfig.json</code> 文件,放于项目根目录下,并输入一下配置</p>
<pre><code class="json">{
"compilerOptions": {
"target": "es5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules",
"typings/main",
"typings/main.d.ts"
]
}</code></pre>
<blockquote><p>我们稍后在附录中会详细讲解这个 tsconfig.json</p></blockquote>
<h3>Typescript Typings</h3>
<p>有很多Javascript的库,继承了一些 Javascript的环境变量以及语法, Typescript编译器并不能原生的支持这些。 所以我们使用 Typescript 类型定义文件 - <code>d.ts</code> 文件 (即 typings.json) 来解决这些兼容性问题。</p>
<p>创建 <code>typings.json</code> 文件,放于项目根目录下</p>
<pre><code class="json">{
"ambientDependencies": {
"es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#6697d6f7dadbf5773cb40ecda35a76027e0783b2"
}
}</code></pre>
<blockquote><p>同样的,在附录中会有更详细点的解释</p></blockquote>
<h3>添加我们需要的库</h3>
<p>我们推荐使用npm来管理我们的依赖库。<br>在项目根目录下创建package.json文件</p>
<pre><code class="json">{
"name": "angular2-quickstart",
"version": "1.0.0",
"scripts": {
"start": "concurrent \"npm run tsc:w\" \"npm run lite\" ",
"tsc": "tsc",
"tsc:w": "tsc -w",
"lite": "lite-server",
"typings": "typings",
"postinstall": "typings install"
},
"license": "ISC",
"dependencies": {
"angular2": "2.0.0-beta.7",
"systemjs": "0.19.22",
"es6-promise": "^3.0.2",
"es6-shim": "^0.33.3",
"reflect-metadata": "0.1.2",
"rxjs": "5.0.0-beta.2",
"zone.js": "0.5.15"
},
"devDependencies": {
"concurrently": "^2.0.0",
"lite-server": "^2.1.0",
"typescript": "^1.7.5",
"typings":"^0.6.8"
}
}</code></pre>
<blockquote><p>在附录中,会有更详细的解释</p></blockquote>
<p>安装这些依赖包只需要运行</p>
<pre><code class="sh">npm install</code></pre>
<p>这样我们就完成了我们的开发环境的搭建。</p>
<h2>第一个Angular 组件</h2>
<p>组件是Angular中最基本的一个概念。 一个组件包含一个视图 - 我们用来展示信息或者完成用户交互的页面。 技术上来讲, 一个组件就是一个控制模板试图的类, 在开发应用中会写很多组件。 这是我们第一次尝试写一个组件,所以我们保证他尽可能的简单。</p>
<h3>创建一个应用源码的子目录</h3>
<p>我们习惯上将我们的程序放在项目根目录下的 app 子目录下,所以首先创建一个 app 文件夹</p>
<pre><code class="sh">mkdir app
cd app</code></pre>
<h3>创建组件文件</h3>
<p>在 app 文件夹下创建一个 app.component.ts 文件,然后输入以下内容</p>
<pre><code class="typescript">import {Component} from 'angular2/core';
@Component({
selector: 'my-app',
template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }
</code></pre>
<p>让我们来详细的看一下这个文件, 在文件的最后一行,我们定义了一个 类。</p>
<h3>组件类</h3>
<p>在这个文件地步,我们创建了一个啥都不做的空组件类 AppComponent。 当我们真正开发应用的时候, 我们可以扩展这个类,比如添加一些属性和方法逻辑。 这个 AppComponent 类之所以为空是因为我们在入门程序中他不用做任何事情。</p>
<h3>模块</h3>
<p>Angular应用是模块化的。 他们包含很多完成某项功能的模块文件。 <br>大多数程序文件会 export出一个东西比如一个组件。 我们的 app.component.ts 文件 exports出了 AppComponent</p>
<pre><code class="typescript">export class AppComponent { }</code></pre>
<p>exports使一个文件转变成一个模块。 文件名(不包含扩展名)通常就是这个模块的名称。 所以, app.component 就是我们的第一个模块的名称。</p>
<p>一些更复杂的应用会有继承于 AppComponent 的子组件, 而且会有很多文件和模块。但是我们的快速入门程序不需要这么多, 一个组件就够了。</p>
<p>如果一个组件依赖其他的组件, 在Typescript应用中, 当我们需要引入其他模块的时候,直接import进来就可以使用。 例如:</p>
<pre><code class="typescript">import {AppComponent} from './app.component'
</code></pre>
<p>Angular 同样是一个模块, 他是一系列模块的集合。 所以当我们需要angular的一些功能时,同样的把Angular引入进来。</p>
<h3>组件注解</h3>
<p>当我们给一个类加上注解的时候, 一个类就变成了 Angular的组件。 Angular 需要通过注解来搞明白怎么去构建视图, 还有组件是怎么与应用的其他部分进行整合的。</p>
<p>我们用 Componet 方法来定义一个组件的注解, 这个方法需要引入 angular2/core 才可以使用。</p>
<pre><code class="typescript">import {Component} from 'angular2/core';
</code></pre>
<p>在Typescript中,我们在类上面添加注解, 注解的方式很简单,使用 @ 作为前缀进行注解。</p>
<pre><code class="typescript">@Component({
selector: 'my-app',
template: '<h1>My First Angular 2 App</h1>'
})
</code></pre>
<p>@Component 告诉Angular这个类是一个组件。 里面的参数有两个, selector 和 template.</p>
<p>selector参数是一个 css 选择器, 这里表示选择 html 标签为 my-app的元素。 Angular 将会在这个元素里面展示AppComponent 组件。</p>
<blockquote><p>记住这个 my-app 元素,我们会在 index.html 中用到</p></blockquote>
<p>template控制这个组件的视图, 告诉Angular怎么去渲染这个视图。 现在我们需要让 Angular去加载这个组件</p>
<h3>初始化引导</h3>
<p>在 app 文件夹下创建 main.ts</p>
<pre><code class="typescript">import {bootstrap} from 'angular2/platform/browser'
import {AppComponent} from './app.component'
bootstrap(AppComponent);
</code></pre>
<p>我们需要做两个东西来启动这个应用</p>
<ol>
<li><p>Angular自带的 bootstrap 方法</p></li>
<li><p>我们刚刚写好的启动组件</p></li>
</ol>
<p>把这个两个统统 import进来,然后将组件传递给 bootstrap 方法。</p>
<blockquote><p>附录中会详细讲解 为什么我们从 angular2/platform/browser中引入bootstrap 方法,还有为什么会创建一个main.ts文件</p></blockquote>
<p>现在万事俱备,只差东风啦!</p>
<h3>添加 index.html 文件</h3>
<p>首先回到项目的根目录,在根目录中创建index.html</p>
<pre><code class="html"><html>
<head>
<title>Angular 2 QuickStart</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 1. Load libraries -->
<!-- IE required polyfills, in this exact order -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<!-- 2. Configure SystemJS -->
<script>
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app/main')
.then(null, console.error.bind(console));
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
</code></pre>
<p>HMTL中三个部分需要说明一下:</p>
<ol>
<li><p>加载我们需要的 javascript库, 附录中会有详细的介绍</p></li>
<li><p>配置了 System 并让他import 引入 main 文件</p></li>
<li><p>添加 my-app 这个HTML元素,这里才是加载我们Angular实例的地方!</p></li>
</ol>
<p>我们需要一些东西来加载应用的模块,这里我们使用 SystemJs。 这里有很多选择,SystemJS不一定是最好的选择,但是这个挺好用。</p>
<p>SystemJs的具体使用不在我们的快速入门教程里,在附录中会有一个剪短的说明。</p>
<p>当Angular调用main.ts文件中的 bootstrap方法, 它读取 AppComponent 的注解,找到 my-app 这个HTML元素, 并将template 渲染进去。</p>
<h3>编译然后运行</h3>
<p>只需要在终端中输入</p>
<pre><code class="sh">npm start</code></pre>
<p>程序将会将Typescript编译成 Javascript ,同事启动一个 lite-server, 加载我们编写的index.html。 显示 My First Angular 2 App.</p>
<h3>最终的结构</h3>
<blockquote><p>|_ angular2-quickstart<br>|_ app<br>| |_ app.component.ts<br>| |_ main.ts<br>|_ node_modules ...<br>|_ typings ...<br>|_ index.html<br>|_ package.json<br>|_ tsconfig.json<br>|_ typings.json</p></blockquote>