<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Lanvige's Zen Garden]]></title>
  <link href="http://blog.lanvige.com/atom.xml" rel="self"/>
  <link href="http://blog.lanvige.com/"/>
  <updated>2016-01-27T12:57:49+08:00</updated>
  <id>http://blog.lanvige.com/</id>
  <author>
    <name><![CDATA[Lanvige Jiang]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Docker Toolbox in Action]]></title>
    <link href="http://blog.lanvige.com/2016/01/27/docker-toolbox-in-action/"/>
    <updated>2016-01-27T10:10:17+08:00</updated>
    <id>http://blog.lanvige.com/2016/01/27/docker-toolbox-in-action</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/ops/docker-toolbox.jpg"></p>

<ul>
<li><a href="https://www.docker.com/products/docker-toolbox">https://www.docker.com/products/docker-toolbox</a></li>
<li><a href="https://github.com/docker/toolbox/">https://github.com/docker/toolbox/</a></li>
</ul>


<p>Docker Toolbox 可以很方便的在 Windows / Mac 上安装使用 Docker，原理就是通过 Virtualbox 安装一台新的 Linux 虚拟机，然后在虚拟机上运行 Docker Engine，同时，在 Win / Mac 上可以直接操作 Docker。</p>

<p><img src="http://blog.lanvige.com/uploads/ops/vbox-docker-vm.jpg"></p>

<h2>Docker Toolbox 中包含了：</h2>

<p>建议用 Toolbox 自带的，不要再各自独立安装。</p>

<ul>
<li>Docker Engine</li>
<li>Compose</li>
<li>Machine</li>
<li>Kitematic</li>
</ul>


<p>Docker Toolbox 还带了 <code>Docker Quickstart Terminal</code> 用于启动带 Docker 脚本的 Terminal。</p>

<h2>Mac Install</h2>

<p>Mac 上通过 brew-cask 可以很方便的进行 Docker Toolbox 的安装。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">brew</span> <span class="n">install</span> <span class="n">brew</span><span class="o">-</span><span class="n">cask</span>
</span><span class='line'><span class="err">$</span> <span class="n">brew</span> <span class="n">cask</span> <span class="n">install</span> <span class="n">dockertoolbox</span>
</span></code></pre></td></tr></table></div></figure>


<h2>操作</h2>

<p>通过 Kitematic / Docker Quickstart Terminal 可以启动 Docker VM，进入 Docker CLI 后即可正常操作。</p>

<h3>1. 创建主机</h3>

<p>第一次进入时，会创建一个台新主机，其中包括以下步骤：</p>

<ul>
<li>创建新的证书</li>
<li>下载 boot2docker.iso（<a href="https://github.com/boot2docker/boot2docker">Lightweight Linux for Docker</a>）然后 Virtualbox 用该 iso 作为引导盘，创建 Docker VM。</li>
<li>启动 Docker VM</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">bash</span> <span class="o">--</span><span class="n">login</span> <span class="s1">&#39;/Applications/Docker/Docker Quickstart Terminal.app/Contents/Resources/Scripts/start.sh&#39;</span>
</span><span class='line'><span class="no">Creating</span> <span class="ss">CA</span><span class="p">:</span> <span class="sr">/Users/</span><span class="n">lanvige</span><span class="o">/.</span><span class="n">docker</span><span class="o">/</span><span class="n">machine</span><span class="o">/</span><span class="n">certs</span><span class="o">/</span><span class="n">ca</span><span class="o">.</span><span class="n">pem</span>
</span><span class='line'><span class="no">Creating</span> <span class="n">client</span> <span class="ss">certificate</span><span class="p">:</span> <span class="sr">/Users/</span><span class="n">lanvige</span><span class="o">/.</span><span class="n">docker</span><span class="o">/</span><span class="n">machine</span><span class="o">/</span><span class="n">certs</span><span class="o">/</span><span class="n">cert</span><span class="o">.</span><span class="n">pem</span>
</span><span class='line'><span class="no">Running</span> <span class="n">pre</span><span class="o">-</span><span class="n">create</span> <span class="n">checks</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Image</span> <span class="n">cache</span> <span class="n">directory</span> <span class="n">does</span> <span class="ow">not</span> <span class="n">exist</span><span class="p">,</span> <span class="n">creating</span> <span class="n">it</span> <span class="n">at</span> <span class="sr">/Users/</span><span class="n">lanvige</span><span class="o">/.</span><span class="n">docker</span><span class="o">/</span><span class="n">machine</span><span class="o">/</span><span class="n">cache</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">No</span> <span class="n">default</span> <span class="no">Boot2Docker</span> <span class="no">ISO</span> <span class="n">found</span> <span class="n">locally</span><span class="p">,</span> <span class="n">downloading</span> <span class="n">the</span> <span class="n">latest</span> <span class="n">release</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Latest</span> <span class="n">release</span> <span class="k">for</span> <span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">boot2docker</span><span class="o">/</span><span class="n">boot2docker</span> <span class="n">is</span> <span class="n">v1</span><span class="o">.</span><span class="mi">9</span><span class="o">.</span><span class="mi">1</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Boot2Docker</span> <span class="n">v1</span><span class="o">.</span><span class="mi">9</span><span class="o">.</span><span class="mi">1</span> <span class="n">has</span> <span class="n">a</span> <span class="n">known</span> <span class="n">issue</span> <span class="n">with</span> <span class="no">AUFS</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">See</span> <span class="n">here</span> <span class="k">for</span> <span class="n">more</span> <span class="ss">details</span><span class="p">:</span> <span class="ss">https</span><span class="p">:</span><span class="sr">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">docker</span><span class="o">/</span><span class="n">docker</span><span class="o">/</span><span class="n">issues</span><span class="o">/</span><span class="mi">18180</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Consider</span> <span class="n">specifying</span> <span class="n">another</span> <span class="n">storage</span> <span class="n">driver</span> <span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">g</span><span class="o">.</span> <span class="s1">&#39;overlay&#39;</span><span class="p">)</span> <span class="n">using</span> <span class="s1">&#39;--engine-storage-driver&#39;</span> <span class="n">instead</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Downloading</span> <span class="sr">/Users/</span><span class="n">lanvige</span><span class="o">/.</span><span class="n">docker</span><span class="o">/</span><span class="n">machine</span><span class="o">/</span><span class="n">cache</span><span class="o">/</span><span class="n">boot2docker</span><span class="o">.</span><span class="n">iso</span> <span class="n">from</span> <span class="ss">https</span><span class="p">:</span><span class="sr">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">boot2docker</span><span class="o">/</span><span class="n">boot2docker</span><span class="o">/</span><span class="n">releases</span><span class="o">/</span><span class="n">download</span><span class="o">/</span><span class="n">v1</span><span class="o">.</span><span class="mi">9</span><span class="o">.</span><span class="mi">1</span><span class="o">/</span><span class="n">boot2docker</span><span class="o">.</span><span class="n">iso</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Creating</span> <span class="no">VirtualBox</span> <span class="no">VM</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Creating</span> <span class="no">SSH</span> <span class="n">key</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Starting</span> <span class="n">the</span> <span class="no">VM</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="p">(</span><span class="n">default</span><span class="p">)</span> <span class="no">Waiting</span> <span class="k">for</span> <span class="n">an</span> <span class="no">IP</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Waiting</span> <span class="k">for</span> <span class="n">machine</span> <span class="n">to</span> <span class="n">be</span> <span class="n">running</span><span class="p">,</span> <span class="n">this</span> <span class="n">may</span> <span class="n">take</span> <span class="n">a</span> <span class="n">few</span> <span class="n">minutes</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Machine</span> <span class="n">is</span> <span class="n">running</span><span class="p">,</span> <span class="n">waiting</span> <span class="k">for</span> <span class="no">SSH</span> <span class="n">to</span> <span class="n">be</span> <span class="n">available</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Detecting</span> <span class="n">operating</span> <span class="nb">system</span> <span class="n">of</span> <span class="n">created</span> <span class="n">instance</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Detecting</span> <span class="n">the</span> <span class="n">provisioner</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Provisioning</span> <span class="n">with</span> <span class="n">boot2docker</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Copying</span> <span class="n">certs</span> <span class="n">to</span> <span class="n">the</span> <span class="n">local</span> <span class="n">machine</span> <span class="n">directory</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Copying</span> <span class="n">certs</span> <span class="n">to</span> <span class="n">the</span> <span class="n">remote</span> <span class="n">machine</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Setting</span> <span class="no">Docker</span> <span class="n">configuration</span> <span class="n">on</span> <span class="n">the</span> <span class="n">remote</span> <span class="n">daemon</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Checking</span> <span class="n">connection</span> <span class="n">to</span> <span class="no">Docker</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="no">Docker</span> <span class="n">is</span> <span class="n">up</span> <span class="ow">and</span> <span class="n">running!</span>
</span><span class='line'><span class="no">To</span> <span class="n">see</span> <span class="n">how</span> <span class="n">to</span> <span class="n">connect</span> <span class="no">Docker</span> <span class="n">to</span> <span class="n">this</span> <span class="n">machine</span><span class="p">,</span> <span class="ss">run</span><span class="p">:</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">docker</span><span class="o">-</span><span class="n">machine</span> <span class="n">env</span> <span class="n">default</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>                        <span class="c1">##         .</span>
</span><span class='line'>                  <span class="c1">## ## ##        ==</span>
</span><span class='line'>               <span class="c1">## ## ## ## ##    ===</span>
</span><span class='line'>           <span class="sr">/&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;\___/</span> <span class="o">===</span>
</span><span class='line'>      <span class="o">~~~</span> <span class="p">{</span><span class="o">~~</span> <span class="o">~~~~</span> <span class="o">~~~</span> <span class="o">~~~~</span> <span class="o">~~~</span> <span class="o">~</span> <span class="sr">/  ===- ~~~</span>
</span><span class='line'><span class="sr">           \______ o           __/</span>
</span><span class='line'>             <span class="p">\</span>    <span class="p">\</span>         <span class="n">__</span><span class="o">/</span>
</span><span class='line'>              <span class="p">\</span><span class="n">____</span><span class="p">\</span><span class="n">_______</span><span class="o">/</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="n">docker</span> <span class="n">is</span> <span class="n">configured</span> <span class="n">to</span> <span class="n">use</span> <span class="n">the</span> <span class="n">default</span> <span class="n">machine</span> <span class="n">with</span> <span class="no">IP</span> <span class="mi">192</span><span class="o">.</span><span class="mi">168</span><span class="o">.</span><span class="mi">99</span><span class="o">.</span><span class="mi">100</span>
</span><span class='line'><span class="no">For</span> <span class="n">help</span> <span class="n">getting</span> <span class="n">started</span><span class="p">,</span> <span class="n">check</span> <span class="n">out</span> <span class="n">the</span> <span class="n">docs</span> <span class="n">at</span> <span class="ss">https</span><span class="p">:</span><span class="sr">//</span><span class="n">docs</span><span class="o">.</span><span class="n">docker</span><span class="o">.</span><span class="n">com</span>
</span></code></pre></td></tr></table></div></figure>


<h3>2. 进入主机</h3>

<p>可以通过 docker-machine env 查看 Docker 主机的配置信息：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">docker</span><span class="o">-</span><span class="n">machine</span> <span class="n">env</span> <span class="n">default</span>
</span><span class='line'>
</span><span class='line'><span class="n">export</span> <span class="no">DOCKER_TLS_VERIFY</span><span class="o">=</span><span class="s2">&quot;1&quot;</span>
</span><span class='line'><span class="n">export</span> <span class="no">DOCKER_HOST</span><span class="o">=</span><span class="s2">&quot;tcp://192.168.99.100:2376&quot;</span>
</span><span class='line'><span class="n">export</span> <span class="no">DOCKER_CERT_PATH</span><span class="o">=</span><span class="s2">&quot;/Users/lanvige/.docker/machine/machines/default&quot;</span>
</span><span class='line'><span class="n">export</span> <span class="no">DOCKER_MACHINE_NAME</span><span class="o">=</span><span class="s2">&quot;default&quot;</span>
</span><span class='line'><span class="c1"># Run this command to configure your shell:</span>
</span><span class='line'><span class="c1"># eval $(docker-machine env default)</span>
</span></code></pre></td></tr></table></div></figure>


<p>通过 docker-machine ssh 进入 Docker 主机：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">docker</span><span class="o">-</span><span class="n">machine</span> <span class="n">ssh</span> <span class="n">default</span>
</span></code></pre></td></tr></table></div></figure>


<h3>3. 操作</h3>

<p>这时，无论是在 Win / Mac 还是在 Docker VM 中，通过 <code>Docker Quickstart Terminal</code> 进入 Terminal 就可以正常的使用 Docker 命令了。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">docker</span> <span class="o">-</span><span class="n">v</span>
</span><span class='line'><span class="no">Docker</span> <span class="n">version</span> <span class="mi">1</span><span class="o">.</span><span class="mi">9</span><span class="o">.</span><span class="mi">1</span><span class="p">,</span> <span class="n">build</span> <span class="n">a34a1d5</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Issues:</h2>

<h3>1. Volume</h3>

<p>Docker Toolbox 中的 Volume 映射的目录不是 Win / Mac 机上的目录，而是 Docker VM 上的目录，这一点一定要注意。</p>

<h2>REF::</h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Postgres 9.5 Upgrade]]></title>
    <link href="http://blog.lanvige.com/2016/01/14/postgres-upgrade/"/>
    <updated>2016-01-14T11:42:45+08:00</updated>
    <id>http://blog.lanvige.com/2016/01/14/postgres-upgrade</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/develop/postgres-logo.jpg"></p>

<ul>
<li><a href="http://blog.lanvige.com/2015/09/30/postgres-in-action/">Postgres in Action</a></li>
</ul>


<h2>Postgres 9.5 Release</h2>

<p>9.5 正式发布，推出如下几个新功能：<a href="http://www.postgresql.org/about/news/1636/">Announcement</a></p>

<ul>
<li>UPSERT（最期待）</li>
<li>Row Level Security</li>
<li>Big Data</li>
</ul>


<h3>升级兼容问题</h3>

<p>将数据库升级到了 9.5.0 后，发现无法正常启动：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">postgres</span> <span class="o">-</span><span class="n">D</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># FATAL:  database files are incompatible with server</span>
</span><span class='line'><span class="c1"># DETAIL:  The data directory was initialized by PostgreSQL version 9.4, which is not compatible with this version 9.5.0.</span>
</span></code></pre></td></tr></table></div></figure>


<p>Postgres 并不遵循 <a href="http://semver.org/">Semantic Versioning</a> 规范，9.4 -> 9.5 是大版本变动，会有数据结构的变化。<a href="http://www.postgresql.org/docs/9.5/static/upgrading.html">Postgres: Upgrading a PostgreSQL Cluster</a></p>

<h2>Data Upgrade</h2>

<p>因为数据结构变化，导致无法直接升级使用，就是看如何升级，考虑到使用场景，会有如下三种方案，数据目录删除重建，数据库备份还原，数据目录升级。</p>

<h3>1. 重建数据目录</h3>

<p>如果是开发机器，上面的数据不是很重要，可以选择删除数据目录，用新版重建。（OSX and Brew installed）</p>

<h5>关停 pg</h5>

<p>记得要先关停 pg，不然会自动创建目录，自动新建的目录有权限问题。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">launchctl</span> <span class="n">unload</span> <span class="o">~</span><span class="sr">/Library/</span><span class="no">LaunchAgents</span><span class="o">/</span><span class="n">homebrew</span><span class="o">.</span><span class="n">mxcl</span><span class="o">.</span><span class="n">postgresql</span><span class="o">.</span><span class="n">plist</span>
</span></code></pre></td></tr></table></div></figure>


<h5>重建数据库目录并进行初始化</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">rm</span> <span class="o">-</span><span class="n">rf</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres</span>
</span><span class='line'><span class="err">$</span> <span class="n">initdb</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres</span>
</span></code></pre></td></tr></table></div></figure>


<h5>启用 pg</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">launchctl</span> <span class="nb">load</span> <span class="o">~</span><span class="sr">/Library/</span><span class="no">LaunchAgents</span><span class="o">/</span><span class="n">homebrew</span><span class="o">.</span><span class="n">mxcl</span><span class="o">.</span><span class="n">postgresql</span><span class="o">.</span><span class="n">plist</span>
</span></code></pre></td></tr></table></div></figure>


<h3>2. 数据库备份还原</h3>

<p>当然也可以通过备份（pg_dump），再还原（pg_）的方式，将 DB 数据进行升级。（这也是官方最推荐的做法。）</p>

<p><a href="http://www.postgresql.org/docs/9.5/static/backup-dump.html">http://www.postgresql.org/docs/9.5/static/backup-dump.html</a></p>

<h5>单数据库 SQL Dump</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="o">&gt;</span> <span class="n">pg_dump</span> <span class="n">dbname</span> <span class="o">&gt;</span> <span class="n">outfile</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="o">&gt;</span> <span class="n">psql</span> <span class="n">dbname</span> <span class="o">&lt;</span> <span class="n">infile</span>
</span></code></pre></td></tr></table></div></figure>


<h5>多数据库 Dump</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="o">&gt;</span> <span class="n">pg_dumpall</span> <span class="o">&gt;</span> <span class="n">outfile</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="o">&gt;</span> <span class="n">psql</span> <span class="o">-</span><span class="n">f</span> <span class="n">infile</span> <span class="n">postgres</span>
</span></code></pre></td></tr></table></div></figure>


<h3>3. 数据目录升级</h3>

<p>通过 <code>pg_upgrade</code> 来对旧的数据库目录进行升级，但这个需要新旧版本同时存在。</p>

<p>那新版数据库目录呢？我们得自己去建立一个新目录，使用上文提到的 initdb 命令，并跟旧目录使用同一个名字。所以我们要先把旧版目录换个名字，再建立新目录。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="err">$</span> <span class="n">mv</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="k">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="k">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres_94</span>
</span><span class='line'><span class="err">$</span> <span class="n">initdb</span> <span class="o">-</span><span class="n">D</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="k">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres</span>
</span></code></pre></td></tr></table></div></figure>


<p>当新目录创建好以后，准备工作就做完了。这时就可以使用 pg_upgrade 了。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">pg_upgrade</span> <span class="o">-</span><span class="n">b</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="no">Cellar</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">9</span><span class="o">.</span><span class="mi">4</span><span class="o">.</span><span class="mi">4</span><span class="o">/</span><span class="n">bin</span> <span class="o">-</span><span class="n">B</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="no">Cellar</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">9</span><span class="o">.</span><span class="mi">5</span><span class="o">.</span><span class="mi">0</span><span class="o">/</span><span class="n">bin</span> <span class="o">-</span><span class="n">d</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres_94</span> <span class="o">-</span><span class="n">D</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres</span> <span class="o">-</span><span class="n">v</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># -v 显示执行详细信息</span>
</span></code></pre></td></tr></table></div></figure>


<h2>REF::</h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[mti in practice]]></title>
    <link href="http://blog.lanvige.com/2016/01/02/mti-in-practice/"/>
    <updated>2016-01-02T21:58:51+08:00</updated>
    <id>http://blog.lanvige.com/2016/01/02/mti-in-practice</id>
    <content type="html"><![CDATA[
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Bad & the Luck with Macky]]></title>
    <link href="http://blog.lanvige.com/2016/01/02/the-bad-the-luck-with-macky/"/>
    <updated>2016-01-02T19:31:01+08:00</updated>
    <id>http://blog.lanvige.com/2016/01/02/the-bad-the-luck-with-macky</id>
    <content type="html"><![CDATA[<p>介绍一下 Macky，是 Jocky 购于 2012 年，当时的最高配（15&#8217; 高分屏），13 年的时候跟了我，不过一直到 14 年时，发现电池鼓的把后壳挣了起来，才意思到她的存在，于是换了新的电池，Devbox 作了正式交接，起名 Macky（Mac &amp; Jocky），后来陆续上了 SSD，换掉光驱装上硬盘支架，内存升到 16G，欢快的又跑了2年。</p>

<h2>[Sob]</h2>

<p><img src="http://blog.lanvige.com/uploads/iampc/macky-videoissue.jpg"></p>

<p>2016 新年第一天，一如即往的带着本本出去嗮太阳，到家时，却发现屏幕点不亮，强制关机后正常，晚上出门后发现外接显示屏是黑屏但带亮光，又尝试重启，无效。回想这两次黑屏前都做了一件事，连公司 VPN，但感觉又没有任何关系。</p>

<p>折腾到半夜，长按关机键半小时，终得关机，看着跑男，就没放心上。</p>

<p>直到第二天一早，发现问题大了，始终无法开机。查了下网上这个 Case 还挺多，说是 2011 年款的通病，按贴子说明，重置 SCM，无效；重置 NVRAM，无效；</p>

<p>傻眼了，虽然一直想换新本，但也只是想想，毕竟 Retina 用不着（到哪都外接屏用），多花 1W 块没换来任何不一样的东西。不值，iMac 27 5K 也才 1.4W（5K Retina 啊，口水）。况且，Skylake，USBC, DDR4 在现一代上都还缺席。。。这个上下不接的时间，这足可以逼疯处女座（还好不是）！！！</p>

<h2>花屏门（召回条例）</h2>

<p>网上关于花屏门的问题，很多人都在吐槽，投诉，各种维修办法，自换 <code>N卡主板</code> 等，苦恼中，看到一条振奋人心的消息，<a href="http://nb.zol.com.cn/508/5083061.html">苹果终于召回有显卡故障的 Macbook Pro</a>。</p>

<blockquote><p>苹果目前已启动一个召回项目，为用户修理于 2011 年 2 月 - 2013 年 2 月售出的 Macbook Pro，解决视频扭曲、视频不显示，以及系统意外重启等问题。</p></blockquote>

<p>于是去 Apple 官网，在所有更换维修计划 <code>exchange_repair</code> 中找到这么一条：<a href="http://www.apple.com/cn/support/macbookpro-videoissues/">适用于视频问题的 MacBook Pro 维修扩展计划</a> <code>2015 年 2 月 19 日</code></p>

<h4>- 受影响的 MacBook Pro 可能显示一个或多个下述症状：</h4>

<ul>
<li>电脑屏幕上视频失真或紊乱</li>
<li>即使已打开电脑，电脑屏幕（或外部显示器）上也不显示任何视频</li>
<li>电脑意外重启</li>
</ul>


<h4>- 受影响的产品</h4>

<ul>
<li>2011 年生产的 15 英寸和 17 英寸 MacBook Pro 机型</li>
</ul>


<h4>- 最最最重要的一条</h4>

<ul>
<li>此计划为您受影响的 MacBook Pro 机型提供的保修期限直到 <code>2016 年 2 月 27</code> 日。</li>
</ul>


<p><a href="https://checkcoverage.apple.com/cn/zh">保修服务和支持期限（序列号）查询工具</a> 这里查询保修机器信息。</p>

<h2>预约 GENIUS BAR</h2>

<p><img src="http://blog.lanvige.com/uploads/iampc/macky-vst.jpg"></p>

<p>完全符合，立即开始预约，多种尝试，后还还是 <code>Apple 技术支持</code> 帮忙预约了下午 1：15 南京东路店（奇怪的是，我自己手机上预约时，每家店都是满的。）</p>

<p>PS1：出门时忽然觉得预约南京东路是对的，不用地铁换乘 ：）</p>

<p>PS2：元旦的南京路太恐怖了，哪哪都是人，走都走不开，路口都是武警肉墙。</p>

<p>等到 15 分，准时有人叫名字，真担心这般吵闹会不会听不到。描述了下情况，做了个登记，查有没有主板库存，所幸有货，机器做了几次自检，终于看到网上传说中的 vst 自检程序了，有点像在微软时的内部装机工具，哈哈。</p>

<p>通过 vst，系统看的清清楚楚，光驱、主板，电池信息都还原在屏幕上了。一一做了登记。</p>

<blockquote><p>吐槽下，登记结束时，登记 App Crash 了，工作人员给我说，看，Crash了。。于是又重新填一次，其实我的信息都已经填过好多次了，每次还是会让重新输入，真是浪费时间。</p></blockquote>

<p>大致 3 天取货，工作人员说。</p>

<blockquote><p>显然，对于这种自己换电池，加内存，换 SSD，拆光驱的行为，对保修没有影响。</p></blockquote>

<h2>[Joyful] Welcome back： <code>Macky</code></h2>

<p>从 Apple Store 走出来，天热的不行，完全不像元旦该有的温度，绕过南京东路，走在福州路上，清静了不少，边走边看，倒发现不少好玩的东西。随意走进一家 Cafe Bar，坐在吊椅上，叫了杯含酒精的咖啡，恩，以后应该再也不会再喝了。</p>

<p>大致 4 点钟，接到电话，说是 Apple，Macky 已经被修好了，但有个事情要给我说明下：修好的电脑有个 Bug，每次开机、关机时，会有花屏闪现。问我能不能接受。我说不能接受。于是他改口说，这不是个问题，是个正常现象，只会在开关机时花一下，其它时间正常，而且有 90 天保修。这。。。又顺带问了下，新主板显卡是换了 <code>N卡</code>，还是老的 <code>A卡</code>，回复是 <code>A卡</code>，不过技术升级了，不会再出问题。又是。。。（一串无语）</p>

<p>折回 Apple Store，等了许久，终于等回了我的本本，开机时看到那条花线，笑了下，工作人员表示他不知道。好吧，只能这样了。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/macky-newboard.jpg"></p>

<p>Anyway，其实心中窃喜，有种赚了 1W 块的赶脚。又可以再用上两年了。 iMac 27 5K 依然等你。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Docker in Practice]]></title>
    <link href="http://blog.lanvige.com/2015/11/17/docker-in-practice/"/>
    <updated>2015-11-17T11:47:59+08:00</updated>
    <id>http://blog.lanvige.com/2015/11/17/docker-in-practice</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/ops/docker-archi.png"></p>

<p>在公司推广 Docker，终于发布了第一个业务线。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DevOps Practice - Multistage Deployment]]></title>
    <link href="http://blog.lanvige.com/2015/11/02/devops-practice-multistage-deployment/"/>
    <updated>2015-11-02T15:48:02+08:00</updated>
    <id>http://blog.lanvige.com/2015/11/02/devops-practice-multistage-deployment</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/ops/devops-stages.png"></p>

<p>一套完整的开发流程，必不可少的有几个不同的环境，用于开发的不同阶段。每个环境有自己专属的使用人群、数据源：</p>

<h5>- Development</h5>

<p>Dev 环境是有开发人员自己的数据库，为了开发，会准备一些专用数据，不被清零。数据源可以是 <code>Prod</code> 过滤掉敏感数据后的（同步周期不一样）。</p>

<h5>- Test</h5>

<p>Test 环境用的是测试人员专有数据库，每次跑自动化脚本，会清空数据库，使用 clean_db, fake 等来进行清空，构建测试数据等。</p>

<h5>- Stage</h5>

<p>Staging 环境，用的是线上数据库副本，每 <code>天/周</code> 同步。用于做上线前的测试准备工作。</p>

<p>理论上，无论开发珠江实业 是测试使用，都不应该直连线上数据库。</p>

<h5>- Production</h5>

<p>Production 环境，直接线上数据库。</p>

<h2>Environments &amp; Domains</h2>

<p>每个环境都会有自己的入口，清晰的入口可以减少沟通成本。建议通过域名层级来进行定义区分。</p>

<h3>- 产品（一级）域名</h3>

<p>一般来说，每个产品都应该有自己的域名，所有的业务都绑定在该域名下。这样域名的形式为： <code>app1.com</code>。</p>

<p>但也有情况是多个产品用同一个域名。这时，就要加上一个产品名了： <code>app1.lanvige.com</code>，以下所有的域名都以此为 base。</p>

<h3>- 业务（二级）域名</h3>

<p>业务上通过二级域来区分，像 api，admin 等。</p>

<ul>
<li>api.lanvige.com</li>
<li>admin.lanvige.com</li>
<li>editor.lanvige.com</li>
</ul>


<h3>- 环境（三级）域名</h3>

<p>不同的环境通过三级域名来区分，<code>Production 环境</code> 不适用。</p>

<ul>
<li>dev.api.lanvige.com</li>
<li>test.api.lanvige.com</li>
<li>stage.api.lanvige.com</li>
<li>api.lanvige.com</li>
</ul>


<p>开发、测试环境由于只是公司内部使用，完全可以配置在公司内部 DNS 上，限制访问源，增加安全性。当然，通过申请一个新的独立域名，也可以来做这件事，像 <code>lanvige.local</code> 这样，专门用于公司内部。</p>

<ul>
<li>dev.api.lanvige.local</li>
</ul>


<h2>REF::</h2>

<ul>
<li><a href="https://www.ibm.com/developerworks/community/blogs/c914709e-8097-4537-92ef-8982fc416138/entry/multistage_deployment_on_bluemix_with_ibm_devops_services?lang=zh">Multistage deployment on Bluemix with IBM DevOps Services</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Docker Deploy With Registry 2.0]]></title>
    <link href="http://blog.lanvige.com/2015/10/29/docker-deploy-with-registry/"/>
    <updated>2015-10-29T15:48:27+08:00</updated>
    <id>http://blog.lanvige.com/2015/10/29/docker-deploy-with-registry</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/ops/docker-logo.jpg" alt="docker" /></p>

<ul>
<li><a href="http://blog.lanvige.com/2014/12/12/docker-index/">Docker Index</a></li>
<li>Docker Image: <a href="https://hub.docker.com/_/registry/">https://hub.docker.com/_/registry/</a></li>
<li>Distribution: <a href="https://github.com/docker/distribution">https://github.com/docker/distribution</a></li>
</ul>


<h2>发布选型</h2>

<p>Docker Image Build 好了，并且在本地 Run 起来木牛问题，如何发布到服务器端呢？</p>

<p>有以下选择：</p>

<ol>
<li>Docker Hub &lt;hub.docker.com></li>
<li>第三方 Hub</li>
<li>Export &amp; Import Images</li>
<li>Private Registry</li>
</ol>


<p>前两种，如果许可，当然是最好的，但网络和信任问题，无法选用。Export &amp; Import 方案比较 Low，首先步骤特别繁琐，其次每次 Save 都会存储完整的 Image Layer。而无法选择增量导出，导出的文件特别大。</p>

<p>最终只能选定自建 Docker Registry。</p>

<h2>Run Registry with Docker Way</h2>

<blockquote><p>这里说明下 Registry V1 有漏洞，列在已经被废弃了，V2 虽然仍叫这个名字，但其项目名已经改为了 <a href="https://github.com/docker/distribution">Docker Distribution</a>，在使用 Registry Docker Image 时，一定记得带上 Tag 为 <code>2</code>。</p></blockquote>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">docker</span> <span class="n">run</span> <span class="o">-</span><span class="n">d</span> <span class="o">-</span><span class="nb">p</span> <span class="mi">5000</span><span class="p">:</span><span class="mi">5000</span> <span class="o">--</span><span class="n">restart</span><span class="o">=</span><span class="n">always</span> <span class="o">--</span><span class="nb">name</span> <span class="n">registry</span> <span class="ss">registry</span><span class="p">:</span><span class="mi">2</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># You can now use it with docker.</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># To stop your registry, you would:</span>
</span><span class='line'><span class="err">$</span> <span class="n">docker</span> <span class="n">stop</span> <span class="n">registry</span> <span class="o">&amp;&amp;</span> <span class="n">docker</span> <span class="n">rm</span> <span class="o">-</span><span class="n">v</span> <span class="n">registry</span>
</span></code></pre></td></tr></table></div></figure>


<p>这时，Registry 理论上就跑起来了，可以通过 5000 端口来查看。</p>

<p>但 Docker 访问 Registry 限制了 HTTP 协议，必须使用 HTTPS 访问，也就是说这时候
Docker CLI 仍是无法使用的。可以通过设置 <code>insecure-registry</code> 的方式来跳过 SSL 进行交互，但测试下来很不方便，就跳过这种方式，接下来会用 Nginx 作为 Proxy 来添加 SSL 加密。</p>

<h2>Nginx Proxy with SSL</h2>

<p>通过上两篇的关于 CA 和 SSL Cert 的介绍，我们有网站的根证书，把其配置到 Nginx 中：</p>

<p>配置文件：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'># nginx proxy to docker registry
</span><span class='line'>upstream docker-registry {
</span><span class='line'>  server localhost:5000;
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>server {
</span><span class='line'>  listen 443 ssl;
</span><span class='line'>  server_name d2labs.cn;
</span><span class='line'>
</span><span class='line'>  # SSL
</span><span class='line'>  ssl on;
</span><span class='line'>  ssl_certificate /etc/nginx/ssl/d2labs.cn.crt;
</span><span class='line'>  ssl_certificate_key /etc/nginx/ssl/d2labs.cn.key;
</span><span class='line'>
</span><span class='line'>  # disable any limits to avoid HTTP 413 for large image uploads
</span><span class='line'>  client_max_body_size 0;
</span><span class='line'>
</span><span class='line'>  # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
</span><span class='line'>  chunked_transfer_encoding on;
</span><span class='line'>
</span><span class='line'>  add_header Docker-Distribution-Api-Version registry/2.0 always;
</span><span class='line'>
</span><span class='line'>  proxy_set_header Host               $host;
</span><span class='line'>  proxy_set_header                    X-Forwarded-For $proxy_add_x_forwarded_for;
</span><span class='line'>  proxy_set_header                    X-Real-IP $remote_addr;
</span><span class='line'>  proxy_set_header                    X-Forwarded-Proto $scheme;
</span><span class='line'>  proxy_set_header                    X-Original-URI $request_uri;
</span><span class='line'>  proxy_set_header                    Docker-Distribution-Api-Version registry/2.0;
</span><span class='line'>  proxy_read_timeout                  900;
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>  location / {
</span><span class='line'>     # To add basic authentication to v2 use auth_basic setting plus add_header
</span><span class='line'>
</span><span class='line'>     proxy_pass http://docker-registry;
</span><span class='line'>   }
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>将配置文件 <code>d2labs.cn.conf</code> 放置到 <code>/etc/nginx/sites-available</code>，然后创建软连。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">ln</span> <span class="o">-</span><span class="n">s</span> <span class="sr">/etc/n</span><span class="n">ginx</span><span class="o">/</span><span class="n">sites</span><span class="o">-</span><span class="n">available</span><span class="o">/</span><span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">conf</span> <span class="sr">/etc/n</span><span class="n">ginx</span><span class="o">/</span><span class="n">sites</span><span class="o">-</span><span class="n">enabled</span><span class="o">/</span><span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">conf</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Restart Docker Service</h2>

<p>记得一定要重启 Docker Service，不然仍会有关于 HTTPS 的错误。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">service</span> <span class="n">docker</span> <span class="n">restart</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Testing</h2>

<p>浏览打开，调用 Registry API，看到如下，就表示正确了：</p>

<p><img src="http://blog.lanvige.com/uploads/ops/docker-registry-ssl.jpg"></p>

<p>同样，通过 Docker 命令行来进行操作，用来上传、下载制作好的 Images。</p>

<h4>- Prepare</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># Get any image from the hub</span>
</span><span class='line'><span class="err">$</span> <span class="n">docker</span> <span class="n">pull</span> <span class="n">ubuntu</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Tag it to point to your registry</span>
</span><span class='line'><span class="err">$</span> <span class="n">docker</span> <span class="n">tag</span> <span class="n">ubuntu</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">/</span><span class="n">ubuntu</span>
</span></code></pre></td></tr></table></div></figure>


<h4>- Push to Your Registry:</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">docker</span> <span class="n">push</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">/</span><span class="n">ubuntu</span>
</span></code></pre></td></tr></table></div></figure>


<h4>- Pull from New Registry:</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">docker</span> <span class="n">pull</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">/</span><span class="n">ubuntu</span>
</span></code></pre></td></tr></table></div></figure>


<h2>REF::</h2>

<ul>
<li>Docker Registry 2.0: <a href="https://docs.docker.com/registry/">https://docs.docker.com/registry/</a></li>
<li>Deploying a registry server: <a href="https://docs.docker.com/registry/deploying/">https://docs.docker.com/registry/deploying/</a></li>
<li><a href="https://github.com/docker/distribution/blob/master/docs/deploying.md">Deploying a registry server</a></li>
</ul>


<p>关于证书，参考：</p>

<ul>
<li><a href="https://github.com/docker/distribution/blob/master/docs/deploying.md#running-a-domain-registry">Running a domain registry</a></li>
<li><a href="https://github.com/phusion/baseimage-docker#login-to-the-container-or-running-a-command-inside-it-via-ssh">Login to the container, or running a command inside it, via SSH</a></li>
<li><a href="https://github.com/sameersbn/docker-gitlab#ssl">SSL</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Apache Thrift - Introduction]]></title>
    <link href="http://blog.lanvige.com/2015/10/23/apache-thrift-intro/"/>
    <updated>2015-10-23T15:16:16+08:00</updated>
    <id>http://blog.lanvige.com/2015/10/23/apache-thrift-intro</id>
    <content type="html"><![CDATA[<p>Apache Thrift
<a href="http://thrift.apache.org/">http://thrift.apache.org/</a></p>

<p><a href="https://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/">IBM:: Apache Thrift - 可伸缩的跨语言服务开发框架</a></p>

<p><a href="http://www.infoq.com/cn/news/2015/10/Uber-Thrift">Uber从单体架构转向微服务架构</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Nginx Config SSL Certificate]]></title>
    <link href="http://blog.lanvige.com/2015/10/22/nginx-config-ssl-certificate/"/>
    <updated>2015-10-22T16:04:46+08:00</updated>
    <id>http://blog.lanvige.com/2015/10/22/nginx-config-ssl-certificate</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/ops/ssl-https.jpg"></p>

<h2>Nginx 如何配置证书</h2>

<p>在上篇中，我们用自己的 <code>CA 证书</code> 为一个网站 d2labs.cn 进行了签名，生成了签名证书，现在我们将该证书配置到 nginx 服务器上，使其可以通过 HTTPS 进行访问。</p>

<h4>1. 将证书复制到服务器上：</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">scp</span> <span class="o">~</span><span class="sr">/ssl/n</span><span class="n">ginx</span><span class="o">/*</span> <span class="n">lanvige</span><span class="vi">@d2labs</span><span class="o">.</span><span class="n">cn</span><span class="ss">:/</span><span class="n">etc</span><span class="o">/</span><span class="n">nginx</span><span class="o">/</span><span class="n">ssl</span>
</span></code></pre></td></tr></table></div></figure>


<h4>2. 新加 Nginx Site 配置文件</h4>

<p>将配置文件 <code>d2labs.cn.conf</code> 放置到 <code>/etc/nginx/sites-available</code>，然后创建软连。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">ln</span> <span class="o">-</span><span class="n">s</span> <span class="sr">/etc/n</span><span class="n">ginx</span><span class="o">/</span><span class="n">sites</span><span class="o">-</span><span class="n">available</span><span class="o">/</span><span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">conf</span> <span class="sr">/etc/n</span><span class="n">ginx</span><span class="o">/</span><span class="n">sites</span><span class="o">-</span><span class="n">enabled</span><span class="o">/</span><span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">conf</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>server {
</span><span class='line'>  listen 80 default_server;
</span><span class='line'>  listen [::]:80 default_server ipv6only=on;
</span><span class='line'>
</span><span class='line'>  listen 443 ssl;
</span><span class='line'>  listen [::]:443 ssl ipv6only=on;
</span><span class='line'>
</span><span class='line'>  server_name d2labs.com;
</span><span class='line'>
</span><span class='line'>  ssl on;
</span><span class='line'>
</span><span class='line'>  ssl_certificate /etc/nginx/ssl/d2labs.cn.crt;
</span><span class='line'>  ssl_certificate_key /etc/nginx/ssl/d2labs.cn.key;
</span><span class='line'>
</span><span class='line'>  location / {
</span><span class='line'>    root   html;
</span><span class='line'>    index  index.html index.htm;
</span><span class='line'>  }
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<h4>重启 nginx</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>$ sudo service nginx restart
</span></code></pre></td></tr></table></div></figure>


<h2>验证</h2>

<p><img src="http://blog.lanvige.com/uploads/ops/ssl-ca-success.jpg"></p>

<h2>其它安全相关</h2>

<h4>dhparam</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='text'><span class='line'>$ openssl dhparam -out dhparam.pem 2048
</span></code></pre></td></tr></table></div></figure>


<h2>REF::</h2>

<ul>
<li><a href="http://datacenteroverlords.com/2012/03/01/creating-your-own-ssl-certificate-authority/">* Creating Your Own SSL Certificate Authority (and Dumping Self Signed Certs)</a></li>
<li><a href="http://www.liaoxuefeng.com/article/0014189023237367e8d42829de24b6eaf893ca47df4fb5e000">给Nginx配置一个自签名的SSL证书</a></li>
<li><a href="https://s.how/nginx-ssl/">NGINX 配置 SSL 证书 + 搭建 HTTPS 网站教程</a></li>
<li><a href="http://wangye.org/blog/archives/732/">利用OpenSSL创建自签名的SSL证书备忘</a></li>
<li><a href="https://www.digitalocean.com/community/tutorials/how-to-create-an-ssl-certificate-on-nginx-for-ubuntu-14-04">https://www.digitalocean.com/community/tutorials/how-to-create-an-ssl-certificate-on-nginx-for-ubuntu-14-04</a></li>
<li><a href="http://www.blogjava.net/alwayscy/archive/2006/12/01/84852.html">http://www.blogjava.net/alwayscy/archive/2006/12/01/84852.html</a></li>
<li><a href="https://jamielinux.com/docs/openssl-certificate-authority/sign-server-and-client-certificates.html">https://jamielinux.com/docs/openssl-certificate-authority/sign-server-and-client-certificates.html</a></li>
<li><a href="http://itigloo.com/security/generate-an-openssl-certificate-request-with-sha-256-signature/">http://itigloo.com/security/generate-an-openssl-certificate-request-with-sha-256-signature/</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Dumping Self Signed Certificates with Own CA]]></title>
    <link href="http://blog.lanvige.com/2015/10/21/dumping-self-signed-certificates/"/>
    <updated>2015-10-21T16:20:54+08:00</updated>
    <id>http://blog.lanvige.com/2015/10/21/dumping-self-signed-certificates</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/ops/ssl-certificate-logo.png"></p>

<p>上面的文章，介绍了如何创建一个 CA 根证书，并把该证书添加到一些设备中，现在就可以看看如何用该根证书，来签发网站 SSL 证书。</p>

<h2>1. 创建 <code>SSL 证书申请</code> - CSR</h2>

<h4>1.1 创建 SSL 私匙</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># 这里不需要密码</span>
</span><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">genrsa</span> <span class="o">-</span><span class="n">out</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">key</span> <span class="mi">2048</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>加密强度：这里加密强度仍然选择2048：</li>
</ul>


<h4>1.2 创建 CSR</h4>

<p>利用刚才的私匙建立 SSL 证书，用 key 产出 CSR：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># openssl req -new -newkey rsa:2048 -sha256 -key nginx.key -out nginx.csr -subj &quot;/C=CN/ST=Shanghai/O=D2Labs Co.,Ltd/CN=d2labs.com&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="kp">new</span> <span class="o">-</span><span class="n">sha256</span> <span class="o">-</span><span class="n">days</span> <span class="mi">36500</span> <span class="o">-</span><span class="n">key</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">key</span> <span class="o">-</span><span class="n">out</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">csr</span> <span class="o">-</span><span class="n">subj</span> <span class="s2">&quot;/C=CN/ST=Shanghai/O=D2Labs Co.,Ltd/CN=d2labs.com&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 这里需要注意的是：</span>
</span><span class='line'><span class="c1"># /O 字段内容必须与刚才的CA根证书相同；</span>
</span><span class='line'><span class="c1"># /CN 字段为公用名称(Common Name)，必须为网站的域名（不带 www）；</span>
</span><span class='line'><span class="c1"># /OU 字段最好也与为网站域名，当然选择其他名字也没关系。</span>
</span></code></pre></td></tr></table></div></figure>


<h4>1.3 认识 CSR 文件</h4>

<p>打开该 .csr 文件，格式如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>-----BEGIN CERTIFICATE REQUEST-----
</span><span class='line'>MIICkzCCAXsCAQAwTjELMAkGA1UEBhMCQ04xETAPBgNVBAgTCFNoYW5naGFpMRcw
</span><span class='line'>...
</span><span class='line'>fGOyPGV36dv8JbbxoBfIc3CG0IIqacaa8b80rALguZW+fgo6JgeH
</span><span class='line'>-----END CERTIFICATE REQUEST-----
</span></code></pre></td></tr></table></div></figure>


<h4>1.4 验证 CSR 文件</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="k">in</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">csr</span> <span class="o">-</span><span class="n">noout</span> <span class="o">-</span><span class="n">text</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 如果出现以下字段，表示正确使用了 `SHA256` 加密：</span>
</span><span class='line'><span class="c1"># Signature Algorithm: sha256WithRSAEncryption</span>
</span></code></pre></td></tr></table></div></figure>


<h2>2. 用 <code>CA 根证书</code> 签署 <code>SSL 证书</code></h2>

<h4>2.1 准备工作：</h4>

<p>OSX 下 OpenSSL 的默认配置位于：<code>/System/Library/OpenSSL/openssl.cnf</code>，如果使用默认配置文件，需要在 .key, .csr 同级目录下，进行以下操作：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">mkdir</span> <span class="o">-</span><span class="nb">p</span> <span class="n">demoCA</span><span class="o">/</span><span class="n">newcerts</span>
</span><span class='line'><span class="err">$</span> <span class="n">touch</span> <span class="n">demoCA</span><span class="o">/</span><span class="n">index</span><span class="o">.</span><span class="n">txt</span>
</span><span class='line'><span class="err">$</span> <span class="n">echo</span> <span class="s1">&#39;01&#39;</span> <span class="o">&gt;</span> <span class="n">demoCA</span><span class="o">/</span><span class="n">serial</span>
</span></code></pre></td></tr></table></div></figure>


<h4>2.2 签名证书：</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">ca</span> <span class="o">-</span><span class="n">days</span> <span class="mi">3750</span> <span class="o">-</span><span class="n">md</span> <span class="n">sha256</span> <span class="o">-</span><span class="k">in</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">csr</span> <span class="o">-</span><span class="n">cert</span> <span class="n">d2labs_root_ca</span><span class="o">.</span><span class="n">crt</span> <span class="o">-</span><span class="n">keyfile</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">key</span> <span class="o">-</span><span class="n">out</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">crt</span>
</span></code></pre></td></tr></table></div></figure>


<p>输出结果：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># 接下来有一段提示，找到Sign the certificate? [y/n]这句</span>
</span><span class='line'><span class="c"># 打入y并回车，然后出现out of 1 certificate requests certified， commit? [y/n]，同样y回车</span>
</span><span class='line'>
</span><span class='line'>Using configuration from /System/Library/OpenSSL/openssl.cnf
</span><span class='line'>Enter pass phrase <span class="k">for</span> d2labs.key:
</span><span class='line'>Check that the request matches the signature
</span><span class='line'>Signature ok
</span><span class='line'>Certificate Details:
</span><span class='line'>        Serial Number: <span class="m">1</span> <span class="o">(</span>0x1<span class="o">)</span>
</span><span class='line'>        Validity
</span><span class='line'>            Not Before: Oct <span class="m">28</span> 08:32:39 <span class="m">2015</span> GMT
</span><span class='line'>            Not After : Oct <span class="m">27</span> 08:32:39 <span class="m">2016</span> GMT
</span><span class='line'>        Subject:
</span><span class='line'>            <span class="nv">countryName</span>               <span class="o">=</span> CN
</span><span class='line'>            <span class="nv">stateOrProvinceName</span>       <span class="o">=</span> Shanghai
</span><span class='line'>            <span class="nv">organizationName</span>          <span class="o">=</span> D2Labs Co.,Ltd
</span><span class='line'>            <span class="nv">commonName</span>                <span class="o">=</span> d2labs.com
</span><span class='line'>        X509v3 extensions:
</span><span class='line'>            X509v3 Basic Constraints:
</span><span class='line'>                CA:FALSE
</span><span class='line'>            Netscape Comment:
</span><span class='line'>                OpenSSL Generated Certificate
</span><span class='line'>            X509v3 Subject Key Identifier:
</span><span class='line'>                3A:09:AC:8F:9C:3D:57:71:5E:7B:94:1D:5F:F6:89:45:4C:F4:78:12
</span><span class='line'>            X509v3 Authority Key Identifier:
</span><span class='line'>                keyid:C6:D8:9D:41:09:03:F0:36:A2:D2:F1:B6:00:C3:33:E9:E3:29:56:1A
</span><span class='line'>
</span><span class='line'>Certificate is to be certified <span class="k">until</span> Oct <span class="m">27</span> 08:32:39 <span class="m">2016</span> GMT <span class="o">(</span><span class="m">365</span> days<span class="o">)</span>
</span><span class='line'>Sign the certificate? <span class="o">[</span>y/n<span class="o">]</span>:y
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="m">1</span> out of <span class="m">1</span> certificate requests certified, commit? <span class="o">[</span>y/n<span class="o">]</span>y
</span><span class='line'>Write out database with <span class="m">1</span> new entries
</span><span class='line'>Data Base Updated
</span></code></pre></td></tr></table></div></figure>


<p>这时候，就会生成一个 d2labs.cn.crt 证书文件。</p>

<h4>2.3 Verify the certificate</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">x509</span> <span class="o">-</span><span class="n">noout</span> <span class="o">-</span><span class="n">text</span> <span class="o">-</span><span class="k">in</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">cn</span><span class="o">.</span><span class="n">crt</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 出现 sha256 表示正常</span>
</span><span class='line'><span class="c1"># Signature Algorithm: sha256WithRSAEncryption</span>
</span></code></pre></td></tr></table></div></figure>


<h2>成功</h2>

<p>好了，现在目录下有两个服务器需要的 <code>SSL证书</code> 及 <code>私钥文件</code> 了，分别是 <code>d2labs.cn.crt</code> 和 <code>d2labs.cn.key</code>，接下来就可以利用它们配置你的服务器软件了。</p>

<p>需要注意的是由于是自签名证书，所以客户端需要安装根证书，这在上一篇创建 CA 根证书中有介绍。</p>

<h2>REF::</h2>

<ul>
<li><a href="http://datacenteroverlords.com/2012/03/01/creating-your-own-ssl-certificate-authority/">* Creating Your Own SSL Certificate Authority (and Dumping Self Signed Certs)</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Creating Your Own SSL Certificate Authority]]></title>
    <link href="http://blog.lanvige.com/2015/10/21/creating-your-own-ssl-certificate-authority/"/>
    <updated>2015-10-21T11:25:18+08:00</updated>
    <id>http://blog.lanvige.com/2015/10/21/creating-your-own-ssl-certificate-authority</id>
    <content type="html"><![CDATA[<p>HTTPS 现在已进入全网时代，现在大多数的应用，都是以 HTTPS 为通讯基础，而不再支持 HTTP。</p>

<p>无论是申请 iOS Develop，还是申请 网站 SSL 都需要创建一个 <code>Certificate Request</code>，然后提交给一个 CA 机构，由它来签发一个证书，费用不菲哦。</p>

<p>其实这个 CA 就是在操作系统里放了一张根证书（含公钥），然后用该证书的私钥不停的签发证书。在 OSX 上，打开 <code>Keychain Access</code>，可以看到操作系统内所集成的 CA 机构。</p>

<p><img src="http://blog.lanvige.com/uploads/ops/ssl-ca-system.jpg"></p>

<p>如果服务仅用于公司内部，或者几台设备间，去专门的 CA 机构申请一张证书，还是挺浪费的，这时可以自行创建 CA 证书，只要把这个证书分发给相关的设备，进行安装确认，就可以在这些设备间享受 SSL 带来的安全性。</p>

<h2>Create the Root Certificate</h2>

<h3>1. Create a Private Keychain</h3>

<p>首为，我们需要为 <code>Root Certification Authority Certificate</code> 创建一个私钥。（！一定要保存好该私钥。）</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># 创建带密码的私钥</span>
</span><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">genrsa</span> <span class="o">-</span><span class="n">out</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">key</span> <span class="mi">2048</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1"># 为了安全，一般都会给私钥加上密码（要牢记该密码）</span>
</span><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">genrsa</span> <span class="o">-</span><span class="n">des3</span> <span class="o">-</span><span class="n">out</span> <span class="n">d2labs_des3</span><span class="o">.</span><span class="n">key</span> <span class="mi">2048</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1"># 可通过 OpenSSL 提取公钥：</span>
</span><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">rsa</span> <span class="o">-</span><span class="k">in</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">key</span> <span class="o">-</span><span class="n">pubout</span> <span class="o">-</span><span class="n">out</span> <span class="n">d2labs_pub</span><span class="o">.</span><span class="n">key</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>genrsa - RSA 方式加密。</li>
<li>2048 - 加密强度 （一般为 1024， 2048）。</li>
<li>des3 - 创建带密码的私钥。</li>
</ul>


<h3>2 Self-Sign this Certificate</h3>

<p>利用私钥创建自签名根证书</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="kp">new</span> <span class="o">-</span><span class="n">x509</span> <span class="o">-</span><span class="n">nodes</span> <span class="o">-</span><span class="n">days</span> <span class="mi">36500</span> <span class="o">-</span><span class="n">key</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">key</span> <span class="o">-</span><span class="n">out</span> <span class="n">d2labs_root_ca</span><span class="o">.</span><span class="n">crt</span>
</span></code></pre></td></tr></table></div></figure>


<p>接着会有交互提示进行证书设定：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>-----
</span><span class='line'>Country Name <span class="o">(</span><span class="m">2</span> letter code<span class="o">)</span> <span class="o">[</span>AU<span class="o">]</span>:CN
</span><span class='line'>State or Province Name <span class="o">(</span>full name<span class="o">)</span> <span class="o">[</span>Some-State<span class="o">]</span>:Shanghai
</span><span class='line'>Locality Name <span class="o">(</span>eg, city<span class="o">)</span> <span class="o">[]</span>:Shanghai
</span><span class='line'>Organization Name <span class="o">(</span>eg, company<span class="o">)</span> <span class="o">[</span>Internet Widgits Pty Ltd<span class="o">]</span>:D2Labs Co.,Ltd
</span><span class='line'>Organizational Unit Name <span class="o">(</span>eg, section<span class="o">)</span> <span class="o">[]</span>:D2Labs Root CA
</span><span class='line'>Common Name <span class="o">(</span>e.g. server FQDN or YOUR name<span class="o">)</span> <span class="o">[]</span>:D2Labs Root CA
</span><span class='line'>Email Address <span class="o">[]</span>:ca@d2labs.cn
</span><span class='line'>
</span><span class='line'>- /C 表示国家<span class="o">(</span>Country<span class="o">)</span>，只能是国家字母缩写，如CN、US等；
</span><span class='line'>- /ST 表示州或者省<span class="o">(</span>State/Provice<span class="o">)</span>；
</span><span class='line'>- /L 表示城市或者地区<span class="o">(</span>Locality<span class="o">)</span>；
</span><span class='line'>- /O 表示组织名<span class="o">(</span>Organization Name<span class="o">)</span>；
</span><span class='line'>- /OU 其他显示内容，一般会显示在颁发者这栏。
</span><span class='line'>- /CN 表示
</span></code></pre></td></tr></table></div></figure>


<p>如果需要多次签发，避免每次输入，可以通过 <code>subj 参数</code> 直接指定：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="kp">new</span> <span class="o">-</span><span class="n">x509</span> <span class="o">-</span><span class="n">nodes</span> <span class="o">-</span><span class="n">days</span> <span class="mi">3650</span> <span class="o">-</span><span class="n">key</span> <span class="n">d2labs</span><span class="o">.</span><span class="n">key</span> <span class="o">-</span><span class="n">out</span> <span class="n">d2labs_root_ca</span><span class="o">.</span><span class="n">crt</span>  <span class="p">\</span>
</span><span class='line'>  <span class="o">-</span><span class="n">subj</span> <span class="s2">&quot;/C=CN/ST=Shanghai/O=D2Labs Co.,Ltd/CN=D2Labs Root CA&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h5>参数说明</h5>

<ul>
<li>req -</li>
<li>x509 - 表示这是一个自签名证书。</li>
<li>nodes -</li>
<li>days - 证书有效期，3650 表示 10 年。</li>
</ul>


<p>这时，我们就拿到了一张有效期为 10 年的 CA 证书 <code>d2labs_root_ca.crt</code> 和一个签发该证书用的私钥 <code>d2labs.key</code>。有了这两样东西，我们就成为名副其实的 CA 机构，可以为其它公司签名证书了。</p>

<h2>Install Root Certificate on Workstation</h2>

<p>些时用该 <code>CA 证书</code> 签名出的证书，仍是不被信任的，只有在相关的设备上安装该 <code>CA 证书</code>，并设为受信才会有用。</p>

<h3>- Mac OSX</h3>

<p>双击 <code>d2labs_root_ca.crt</code> 文件，可以打开 Keychains Access，对证书进行导入，然后手工设定信任。（导入到 login 下，为当前用户可用，可以手工拖到 system 下，所有用户可用。）</p>

<p>或者，可以通过命令进行安装（直接安装到 system 下）：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">security</span> <span class="n">add</span><span class="o">-</span><span class="n">trusted</span><span class="o">-</span><span class="n">cert</span> <span class="o">-</span><span class="n">d</span> <span class="o">-</span><span class="n">r</span> <span class="n">trustRoot</span> <span class="o">-</span><span class="n">k</span> <span class="s2">&quot;/Library/Keychains/System.keychain&quot;</span> <span class="s2">&quot;/Users/lanvige/ssl/d2labs_root_ca.crt&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>OSX 安装受信该 CA 证书效果图：</p>

<p><img src="http://blog.lanvige.com/uploads/ops/ssl-ca-d2labs.jpg"></p>

<h3>- Ubuntu Server</h3>

<p>Ubuntu 的证书存放目录为 <code>/usr/share/ca-certificates</code>，将自己签发的 CA 根证书，放到该目录下，然后进行认证就可以了。</p>

<p>认证的原理，就是更新 <code>/etc/ca-certificates.conf</code>，加入新添证书路径，取消认证就是在证书前加上 <code>!</code>。</p>

<p>步骤如下：</p>

<ol>
<li>Create a directory for extra CA certificates in <code>/usr/share/ca-certificates</code></li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">mkdir</span> <span class="sr">/usr/s</span><span class="n">hare</span><span class="o">/</span><span class="n">ca</span><span class="o">-</span><span class="n">certificates</span><span class="o">/</span><span class="n">extra</span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>Copy the &lsquo;.crt&rsquo; file to the directory</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">cp</span> <span class="n">d2labs_root_ca</span><span class="o">.</span><span class="n">crt</span> <span class="sr">/usr/s</span><span class="n">hare</span><span class="o">/</span><span class="n">ca</span><span class="o">-</span><span class="n">certificates</span><span class="o">/</span><span class="n">extra</span><span class="o">/</span><span class="n">d2labs_root_ca</span><span class="o">.</span><span class="n">crt</span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>Let Ubuntu add the &lsquo;.crt&rsquo; file&rsquo;s path relative to <code>/usr/share/ca-certificates</code> to <code>/etc/ca-certificates.conf</code></li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># 如果 </span>
</span><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">apt</span><span class="o">-</span><span class="n">get</span> <span class="n">install</span> <span class="n">ca</span><span class="o">-</span><span class="n">certificates</span>
</span><span class='line'>
</span><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">dpkg</span><span class="o">-</span><span class="n">reconfigure</span> <span class="n">ca</span><span class="o">-</span><span class="n">certificates</span>
</span></code></pre></td></tr></table></div></figure>


<h3>CentOS Server</h3>

<h5>1. Install the ca-certificates package:</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">yum</span> <span class="n">install</span> <span class="n">ca</span><span class="o">-</span><span class="n">certificates</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>Loaded plugins: fastestmirror
</span><span class='line'>base                                                                                                                                                          <span class="p">|</span> 3.6 kB  00:00:00
</span><span class='line'>epel/x86_64/metalink                                                                                                                                          <span class="p">|</span> 4.9 kB  00:00:00
</span><span class='line'>epel                                                                                                                                                          <span class="p">|</span> 4.3 kB  00:00:00
</span><span class='line'>extras                                                                                                                                                        <span class="p">|</span> 3.4 kB  00:00:00
</span><span class='line'>updates                                                                                                                                                       <span class="p">|</span> 3.4 kB  00:00:00
</span><span class='line'><span class="o">(</span>1/2<span class="o">)</span>: epel/x86_64/updateinfo                                                                                                                                 <span class="p">|</span> <span class="m">376</span> kB  00:00:00
</span><span class='line'><span class="o">(</span>2/2<span class="o">)</span>: epel/x86_64/primary_db                                                                                                                                 <span class="p">|</span> 3.6 MB  00:00:12
</span><span class='line'>Loading mirror speeds from cached hostfile
</span><span class='line'> * base: mirrors.btte.net
</span><span class='line'> * epel: ftp.riken.jp
</span><span class='line'> * extras: mirrors.yun-idc.com
</span><span class='line'> * updates: mirror.neu.edu.cn
</span><span class='line'>Package ca-certificates-2015.2.4-70.0.el7_1.noarch already installed and latest version
</span><span class='line'>Nothing to <span class="k">do</span>
</span></code></pre></td></tr></table></div></figure>


<h5>2. Enable the dynamic CA configuration feature:</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">update</span><span class="o">-</span><span class="n">ca</span><span class="o">-</span><span class="n">trust</span> <span class="n">enable</span>
</span></code></pre></td></tr></table></div></figure>


<h5>3. Add it as a new file to /etc/pki/ca-trust/source/anchors/:</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">cp</span> <span class="n">foo</span><span class="o">.</span><span class="n">crt</span> <span class="sr">/etc/</span><span class="n">pki</span><span class="o">/</span><span class="n">ca</span><span class="o">-</span><span class="n">trust</span><span class="o">/</span><span class="n">source</span><span class="o">/</span><span class="n">anchors</span><span class="o">/</span>
</span></code></pre></td></tr></table></div></figure>


<h5>4. Use command:</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">update</span><span class="o">-</span><span class="n">ca</span><span class="o">-</span><span class="n">trust</span> <span class="n">extract</span>
</span></code></pre></td></tr></table></div></figure>


<h3>- Windows</h3>

<p>双击，下一步 &hellip;</p>

<h2>REF::</h2>

<ul>
<li><a href="http://datacenteroverlords.com/2012/03/01/creating-your-own-ssl-certificate-authority/">* Creating Your Own SSL Certificate Authority (and Dumping Self Signed Certs)</a></li>
<li><a href="https://www.digitalocean.com/community/tutorials/how-to-create-an-ssl-certificate-on-apache-for-centos-7">How To Create an SSL Certificate on Apache for CentOS 7</a></li>
<li><a href="http://kb.kerio.com/product/kerio-connect/server-configuration/ssl-certificates/adding-trusted-root-certificates-to-the-server-1605.html">Adding trusted root certificates to the server</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Certification Guide]]></title>
    <link href="http://blog.lanvige.com/2015/10/20/certification-guide/"/>
    <updated>2015-10-20T15:00:33+08:00</updated>
    <id>http://blog.lanvige.com/2015/10/20/certification-guide</id>
    <content type="html"><![CDATA[<h2>那些证书相关 Keywords</h2>

<ul>
<li>SSL</li>
<li>.p12</li>
<li>.key</li>
<li>.pem</li>
<li>.csr</li>
<li>.crt</li>
</ul>


<h3>SSL</h3>

<h5>SSL - Secure Sockets Layer</h5>

<p>现在应该叫 <code>TLS</code>，但由于习惯问题，我们还是叫 SSL 比较多。HTTP 协议默认情况下是不加密内容的，这样就很可能在内容传播的时候被别人监听到，对于安全性要求较高的场合，必须要加密，HTTPS 就是带加密的 HTTP 协议，而 HTTPS 的加密是基于 SSL 的。它执行的是一个比较下层的加密，也就是说，在加密前，你的服务器程序在干嘛，加密后也一样在干嘛，不用动，这个加密对用户和开发者来说都是透明的。</p>

<h5>OpenSSL - Open Secure Sockets Layer</h5>

<p>简单地说，OpenSSL 是 SSL 的一个实现，SSL 只是一种规范。理论上来说，SSL 这种规范是安全的，目前的技术水平很难破解，但 SSL 的实现就可能有些漏洞，如著名的 &ldquo;心脏出血&#8221;。</p>

<p>OpenSSL 还提供了一大堆强大的工具软件，强大到 90% 我们都用不到。</p>

<h2>1. 证书标准</h2>

<h5>X.509 -</h5>

<p>这是一种证书标准，主要定义了证书中应该包含哪些内容，其详情可以参考 RFC5280，SSL 使用的就是这种证书标准。</p>

<h3>2. 编码格式</h3>

<p>同样的 <code>X.509</code> 证书，可能有不同的编码格式，目前有以下两种编码格式.</p>

<h5>PEM - Privacy Enhanced Mail</h5>

<p>打开看文本格式，以 &ldquo;&mdash;&ndash;BEGIN&hellip;&rdquo; 开头，&#8221;&mdash;&ndash;END&hellip;&ldquo;结尾，内容是BASE64编码。</p>

<p>查看PEM格式证书的信息:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">openssl</span> <span class="n">x509</span> <span class="o">-</span><span class="k">in</span> <span class="n">certificate</span><span class="o">.</span><span class="n">pem</span> <span class="o">-</span><span class="n">text</span> <span class="o">-</span><span class="n">noout</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>Apache</code> 和 <code>*NIX</code> 服务器偏向于使用这种编码格式。</p>

<h5>DER - Distinguished Encoding Rules</h5>

<p>打开看是二进制格式，不可读。</p>

<p>查看DER格式证书的信息：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">openssl</span> <span class="n">x509</span> <span class="o">-</span><span class="k">in</span> <span class="n">certificate</span><span class="o">.</span><span class="n">der</span> <span class="o">-</span><span class="n">inform</span> <span class="n">der</span> <span class="o">-</span><span class="n">text</span> <span class="o">-</span><span class="n">noout</span>
</span></code></pre></td></tr></table></div></figure>


<p>Java 和 Windows 服务器偏向于使用这种编码格式。</p>

<h2>3. 相关的文件扩展名</h2>

<p>这是比较误导人的地方，虽然我们已经知道有 PEM 和 DER 这两种编码格式，但文件扩展名并不一定就叫 &ldquo;PEM&rdquo; 或者 &ldquo;DER&#8221;，常见的扩展名除了 PEM 和 DER 还有以下这些，它们除了编码格式可能不同之外，内容也有差别，但大多数都能相互转换编码格式。</p>

<h5>CRT - Certificate 缩写</h5>

<p>其实还是证书的意思，常见于 *NIX 系统，有可能是PEM编码，也有可能是DER编码，大多数应该是PEM编码，相信你已经知道怎么辨别。</p>

<h5>CER - 还是 Certificate 缩写</h5>

<p>还是证书，常见于 Windows 系统，同样的，可能是PEM编码，也可能是DER编码，大多数应该是DER编码。</p>

<h5>KEY -</h5>

<p>通常用来存放一个公钥或者私钥，并非 X.509 证书，编码同样的，可能是 PEM，也可能是 DER。</p>

<p>查看KEY的办法:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">openssl</span> <span class="n">rsa</span> <span class="o">-</span><span class="k">in</span> <span class="n">mykey</span><span class="o">.</span><span class="n">key</span> <span class="o">-</span><span class="n">text</span> <span class="o">-</span><span class="n">noout</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 如果是DER格式的话，同理应该这样了:</span>
</span><span class='line'><span class="n">openssl</span> <span class="n">rsa</span> <span class="o">-</span><span class="k">in</span> <span class="n">mykey</span><span class="o">.</span><span class="n">key</span> <span class="o">-</span><span class="n">text</span> <span class="o">-</span><span class="n">noout</span> <span class="o">-</span><span class="n">inform</span> <span class="n">der</span>
</span></code></pre></td></tr></table></div></figure>


<h5>CSR - Certificate Signing Request</h5>

<p>即证书签名请求，这个并不是证书，而是向权威证书颁发机构获得签名证书的申请，其核心内容是一个公钥（当然还附带了一些别的信息），在生成这个申请的时候，同时也会生成一个私钥，私钥要自己保管好。做过 iOS APP 的朋友都应该知道是怎么向苹果申请开发者证书的吧。</p>

<p>查看的办法:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">req</span> <span class="o">-</span><span class="n">noout</span> <span class="o">-</span><span class="n">text</span> <span class="o">-</span><span class="k">in</span> <span class="n">my</span><span class="o">.</span><span class="n">csr</span> <span class="p">(</span><span class="err">如果是</span><span class="no">DER</span><span class="err">格式的话照旧加上</span><span class="o">-</span><span class="n">inform</span> <span class="n">der</span><span class="err">，这里不写了</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<h5>PFX/P12 - Predecessor of PKCS#12</h5>

<p>对 *nix 服务器来说，一般 CRT 和 KEY 是分开存放在不同文件中的，但 Windows 的 IIS 则将它们存在一个 PFX 文件中，（因此这个文件包含了证书及私钥）这样会不会不安全？应该不会，PFX通常会有一个&#8221;提取密码&#8221;，你想把里面的东西读取出来的话，它就要求你提供提取密码，PFX使用的时DER编码，如何把PFX转换为PEM编码？</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">pkcs12</span> <span class="o">-</span><span class="k">in</span> <span class="k">for</span><span class="o">-</span><span class="n">iis</span><span class="o">.</span><span class="n">pfx</span> <span class="o">-</span><span class="n">out</span> <span class="k">for</span><span class="o">-</span><span class="n">iis</span><span class="o">.</span><span class="n">pem</span> <span class="o">-</span><span class="n">nodes</span>
</span><span class='line'><span class="c1"># 这个时候会提示你输入提取代码. for-iis.pem就是可读的文本.</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 生成pfx的命令类似这样:</span>
</span><span class='line'><span class="err">$</span> <span class="n">openssl</span> <span class="n">pkcs12</span> <span class="o">-</span><span class="n">export</span> <span class="o">-</span><span class="n">out</span> <span class="n">certificate</span><span class="o">.</span><span class="n">pfx</span> <span class="o">-</span><span class="n">inkey</span> <span class="n">privateKey</span><span class="o">.</span><span class="n">key</span> <span class="o">-</span><span class="k">in</span> <span class="n">certificate</span><span class="o">.</span><span class="n">crt</span> <span class="o">-</span><span class="n">certfile</span> <span class="no">CACert</span><span class="o">.</span><span class="n">crt</span>
</span></code></pre></td></tr></table></div></figure>


<p>其中CACert.crt是CA(权威证书颁发机构)的根证书，有的话也通过-certfile参数一起带进去.这么看来，PFX其实是个证书密钥库。</p>

<h2>REF::</h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iMac 27 升级 Fusion Drive]]></title>
    <link href="http://blog.lanvige.com/2015/10/18/imac-27-upgrade-fusion-drive/"/>
    <updated>2015-10-18T16:43:04+08:00</updated>
    <id>http://blog.lanvige.com/2015/10/18/imac-27-upgrade-fusion-drive</id>
    <content type="html"><![CDATA[<p>iMac 5K 2015 终于发布了，虽然上了最想要的 <code>Skylake Processor</code>，但却缺少 <code>DDR 4</code>，<code>Thunderbolt 3 (USB-C)</code>，并且 <code>Fusion Drive</code> 1TB 中 SSD 减为了 24G（预测可是全系标配）。</p>

<p>决定暂等 2016。同时将 MBP 旧件拆解，对 <code>iMac 2011 MC814</code> 进行升级。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-2011.png" width="520" height="520"></p>

<h2>安装 SSD</h2>

<h3>1. 拆机</h3>

<p>iMac 拆机现早已轻车熟路，吸盘打开屏幕玻璃，取下左右两侧的 8 颗螺丝，然后从上方慢慢翘开屏幕，一定要慢，其中有 4 根连线，连线都取下后，方可把显示器移除。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-fd-1.jpg" width="520" height="520"></p>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-fd-2.jpg" width="720" height="720"></p>

<h3>2. 拆换光驱，装入 SSD支架</h3>

<p>拿掉显示器后，就可以看到光驱位，拧开四周的 4 颗螺丝，然后取下光驱，换上光驱支架。</p>

<blockquote><p>PS： 旧的光驱支架，说来很神奇，2 年前为了给 MBP 13 升 SSD，入手了一款支架，但却买错了型号，又懒得退货。今日一试，竟然完全匹配。</p></blockquote>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-fd-4.jpg" width="520" height="520"></p>

<p>图中可以看到，完全一样的接口。只是光驱上带一根线，目测应该是温控器，不知能不能取下，不装会不会有问题。</p>

<h3>3. 风扇</h3>

<p>将机器重新装起后，伴随着开机的同时，风扇也是狂转，立即想到没有装入的光驱温控单元。 TB 上搜了下，没有同型号 <code>593-1376 A 1212f</code>，其它型号不确定是否能用。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-fd-5.jpg" width="520" height="520"></p>

<p>犹豫了很久，慢慢的撕开光驱上的温控器胶带，用力拧了下，竟然动了，取下温控芯片，重装粘到 SSD 上去。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-fd-6.jpg" width="520" height="520"></p>

<h3>4. 完工</h3>

<p>再开机，完美，风扇没了狂躁。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-fd-3.jpg" width="520" height="520"></p>

<h2>Fusion Drive</h2>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-fd-7.jpg" width="640" height="640"></p>

<p>硬盘装好后，对于是使用 <code>2 块独立硬盘</code>，还是做 <code>Fusion Drive</code>，确实纠结了下。不过看着现款 MBP 系统盘渐满的空间，还是决定做 FD。</p>

<p>网上到处是教程，这里只是记录下步骤：</p>

<h3>1. 进入 <code>引导模式</code></h3>

<p>重启，按住 Option 键，进入 <code>引导模式</code>。</p>

<h3>2. 格式化 2 个硬盘</h3>

<p>通过菜单，打开 Utils，将 2 块硬盘分别进行格式化。</p>

<h3>3. 组成 Fusion Drive</h3>

<p>菜单中，进入 Terminal，通过 disktuil 命令进行以下操作。</p>

<h4>3.1  列出所有磁盘信息</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">diskutil</span> <span class="n">list</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 查看所有磁盘信息，disk0 为机械硬盘，disk1 为 SSD。</span>
</span><span class='line'>
</span><span class='line'><span class="sr">/dev/</span><span class="n">disk0</span> <span class="p">(</span><span class="n">internal</span><span class="p">,</span> <span class="n">physical</span><span class="p">):</span>
</span><span class='line'>   <span class="c1">#:                       TYPE NAME                    SIZE       IDENTIFIER</span>
</span><span class='line'>   <span class="mi">0</span><span class="p">:</span>      <span class="no">GUID_partition_scheme</span>                        <span class="o">*</span><span class="mi">128</span><span class="o">.</span><span class="mi">0</span> <span class="no">GB</span>   <span class="n">disk0</span>
</span><span class='line'>   <span class="mi">1</span><span class="p">:</span>                        <span class="no">EFI</span> <span class="no">EFI</span>                     <span class="mi">209</span><span class="o">.</span><span class="mi">7</span> <span class="no">MB</span>   <span class="n">disk0s1</span>
</span><span class='line'><span class="sr">/dev/</span><span class="n">disk1</span> <span class="p">(</span><span class="n">internal</span><span class="p">,</span> <span class="n">physical</span><span class="p">):</span>
</span><span class='line'>   <span class="c1">#:                       TYPE NAME                    SIZE       IDENTIFIER</span>
</span><span class='line'>   <span class="mi">0</span><span class="p">:</span>      <span class="no">GUID_partition_scheme</span>                        <span class="o">*</span><span class="mi">1000</span><span class="o">.</span><span class="mi">1</span> <span class="no">GB</span>   <span class="n">disk1</span>
</span></code></pre></td></tr></table></div></figure>


<h4>3.2 将两个硬盘进行合并</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">diskutil</span> <span class="n">cs</span> <span class="n">create</span> <span class="no">Fusion</span> <span class="n">disk0</span> <span class="n">disk1</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 出现 Finished CoreStorage operation 表示完成</span>
</span></code></pre></td></tr></table></div></figure>


<h4>3.3 列出合并后的磁盘信息</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">diskutil</span> <span class="n">cs</span> <span class="n">list</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 出现 Logical Volume Group，复制 UUID 该值</span>
</span><span class='line'>
</span><span class='line'><span class="o">|</span>
</span><span class='line'><span class="o">+--</span> <span class="no">Logical</span> <span class="no">Volume</span> <span class="no">Group</span> <span class="no">D5141325123</span><span class="o">-</span><span class="mi">4232</span><span class="o">-</span><span class="mi">32</span><span class="no">AD</span><span class="o">-</span><span class="no">AA10</span><span class="o">-</span><span class="no">B4312BGDAFA</span>
</span><span class='line'>    <span class="o">============================================================</span>
</span><span class='line'>    <span class="ss">Name</span><span class="p">:</span>           <span class="no">Fusion</span>
</span><span class='line'>    <span class="ss">Size</span><span class="p">:</span>           <span class="o">-</span>
</span><span class='line'>    <span class="no">Free</span> <span class="ss">Space</span><span class="p">:</span>     <span class="o">-</span>
</span><span class='line'>    <span class="o">|</span>
</span><span class='line'>    <span class="o">+-&lt;</span> <span class="no">Physical</span> <span class="no">Volume</span> <span class="no">XX</span>
</span><span class='line'>    <span class="o">|</span>
</span><span class='line'>    <span class="o">+-&lt;</span> <span class="no">Physical</span> <span class="no">Volume</span> <span class="no">XX</span>
</span><span class='line'>    <span class="o">|</span>
</span></code></pre></td></tr></table></div></figure>


<h4>3.4 制作 Fusion Drive</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">diskutil</span> <span class="n">coreStorage</span> <span class="n">createVolume</span> <span class="s1">&#39;UUID&#39;</span> <span class="n">jhfs</span><span class="o">+</span> <span class="s2">&quot;Macintosh Fusion&quot;</span> <span class="mi">100</span><span class="o">%</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 替换 UUID 为上面的值</span>
</span><span class='line'><span class="c1"># 出现 Finished CoreStorage operation 表示完成</span>
</span></code></pre></td></tr></table></div></figure>


<h3>4. 用<code>U盘</code>重装系统</h3>

<p>如何制作 <code>引导U盘</code>，推荐工具 <code>DiskMaker X</code>，<a href="http://diskmakerx.com/">http://diskmakerx.com/</a> 。</p>

<h2>REF::</h2>

<ul>
<li>制作 FD，<a href="http://www.macuknow.com/node/21313">http://www.macuknow.com/node/21313</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iMac 5K 2015 预测 & 真机]]></title>
    <link href="http://blog.lanvige.com/2015/10/13/imac-5k-2015/"/>
    <updated>2015-10-13T08:25:28+08:00</updated>
    <id>http://blog.lanvige.com/2015/10/13/imac-5k-2015</id>
    <content type="html"><![CDATA[<h2>预测</h2>

<p>自 Dell U2515H 退货后，便在选显示器的路上纠结许久，直到看上新 iMac 5K，就是不知新款何时发布，是否和预想的一般。</p>

<p>按照苹果以往的传统，在9月份的秋季新品发布会之后，苹果还会在10月份举行另外一个新品发布会，一般会在该发布会上发布新的 iPad、Mac 等产品，然而有外媒爆料，苹果今年将打破传统，将不再于10月份举办新品发布会。</p>

<h3>Devices</h3>

<p>预计今年更新的产品会有如下：</p>

<ul>
<li>iMac 5K [Update with &hellip; ]

<ul>
<li>Skylake Processer</li>
<li>DDR 4</li>
<li>Thunderbolt 3 with USBC 接口</li>
<li>Fusion Drive 标配</li>
</ul>
</li>
<li>Macbook Pro [Update with Skylake Processer]</li>
<li>iMac 4K [New]</li>
<li>Mac Mini</li>
<li>iPad Air 3 [New]</li>
<li>iMac All New Keyboard, Mouse, Trackpad</li>
</ul>


<blockquote><p>最期待的就是 iMac 5K 的更新了，达标就剁手！！！</p></blockquote>

<h2>2015 十月新品发布</h2>

<p><strong>2015.10.13</strong></p>

<p>本以为没有发布会，一系列设备就不会再有更新了，没想到苹果官网直接上架了一堆的新品，都没有个说明。全新 iMac 4K, 全新键盘鼠标触摸板，iMac 27 也得到了更新。</p>

<h3>实际发布</h3>

<ul>
<li>iMac 5K [14,988.00]</li>
<li>iMac 4K [完全没兴趣]</li>
<li>iMac Keyboard [728], Mouse[588], Trackpad[988]</li>
</ul>


<h2>iMac 5K 2015 Later</h2>

<p>有 3 款，中高配</p>

<ul>
<li>MK462CH</li>
<li>MK472CH</li>
<li>MK482CH</li>
</ul>


<h3>MK472CH 参数</h3>

<ul>
<li>Skylake Processor</li>
<li>AMD Radeon R9 M390 with 2GB video memory</li>
<li>配备全新 Keyboard, Mouse, 选装 Trackpad</li>
<li>x DDR 4，理论上 Skylake 应配 DDR 4，好在可以加装</li>
<li>x Thunderbolt 3 with USBC 接口，Intel 发布了全新的 TB3 接口，使用 USBC 的，这个完全不能加装，所以~~~</li>
<li>x Fusion Drive 未标配，且 1TB  简配为 24G SSD， SSD 可单独更换，但如果看完 ifixit 的教程后，我想，还是放弃吧。</li>
</ul>


<blockquote><p>又是一次让人没有欲望的升级，忽略。。。</p></blockquote>

<h2>REF::</h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PostgreSQL in Action]]></title>
    <link href="http://blog.lanvige.com/2015/09/30/postgres-in-action/"/>
    <updated>2015-09-30T10:27:00+08:00</updated>
    <id>http://blog.lanvige.com/2015/09/30/postgres-in-action</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/develop/postgres-logo.jpg"></p>

<p><a href="http://www.postgresql.org/">http://www.postgresql.org/</a></p>

<h2>Install</h2>

<h3>- Mac with Homebrew</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">brew</span> <span class="n">install</span> <span class="n">postgres</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># ==&gt; Downloading https://homebrew.bintray.com/bottles/postgresql-9.4.5.el_capitan.bottle.tar.gz</span>
</span><span class='line'><span class="c1"># Already downloaded: /Library/Caches/Homebrew/postgresql-9.4.5.el_capitan.bottle.tar.gz</span>
</span><span class='line'><span class="c1"># ==&gt; Pouring postgresql-9.4.5.el_capitan.bottle.tar.gz</span>
</span><span class='line'><span class="c1"># ==&gt; /usr/local/Cellar/postgresql/9.4.5/bin/initdb /usr/local/var/postgres</span>
</span><span class='line'><span class="c1"># ==&gt; Caveats</span>
</span><span class='line'><span class="c1"># If builds of PostgreSQL 9 are failing and you have version 8.x installed,</span>
</span><span class='line'><span class="c1"># you may need to remove the previous version first. See:</span>
</span><span class='line'><span class="c1">#   https://github.com/Homebrew/homebrew/issues/2510</span>
</span><span class='line'><span class="c1"># </span>
</span><span class='line'><span class="c1"># To migrate existing data from a previous major version (pre-9.4) of PostgreSQL, see:</span>
</span><span class='line'><span class="c1">#   https://www.postgresql.org/docs/9.4/static/upgrading.html</span>
</span><span class='line'><span class="c1"># </span>
</span><span class='line'><span class="c1"># To reload postgresql after an upgrade:</span>
</span><span class='line'><span class="c1">#   launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist</span>
</span><span class='line'><span class="c1">#   launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist</span>
</span><span class='line'><span class="c1"># Or, if you don&#39;t want/need launchctl, you can just run:</span>
</span><span class='line'>  <span class="c1"># postgres -D /usr/local/var/postgres</span>
</span><span class='line'><span class="c1"># ==&gt; Summary</span>
</span><span class='line'><span class="c1"># 🍺  /usr/local/Cellar/postgresql/9.4.5: 3021 files, 40M</span>
</span></code></pre></td></tr></table></div></figure>


<p>过程中，Brew 帮我们默认初始化了数据库目录：<code>/usr/local/var/postgres</code>。</p>

<h5>手动建立数据库目录并进行初始化</h5>

<p>可以手工初始化 DB 目录，来了解到其中原理：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">initdb</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">postgres</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1"># The files belonging to this database system will be owned by user &quot;lanvige&quot;.</span>
</span><span class='line'><span class="c1"># This user must also own the server process.# </span>
</span><span class='line'>
</span><span class='line'><span class="c1"># The database cluster will be initialized with locales</span>
</span><span class='line'><span class="c1">#   COLLATE:  C</span>
</span><span class='line'><span class="c1">#   CTYPE:    UTF-8</span>
</span><span class='line'><span class="c1">#   MESSAGES: C</span>
</span><span class='line'><span class="c1">#   MONETARY: C</span>
</span><span class='line'><span class="c1">#   NUMERIC:  C</span>
</span><span class='line'><span class="c1">#   TIME:     C</span>
</span><span class='line'><span class="c1"># The default database encoding has accordingly been set to &quot;UTF8&quot;.</span>
</span><span class='line'><span class="c1"># initdb: could not find suitable text search configuration for locale &quot;UTF-8&quot;</span>
</span><span class='line'><span class="c1"># The default text search configuration will be set to &quot;simple&quot;.# </span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Data page checksums are disabled.# </span>
</span><span class='line'>
</span><span class='line'><span class="c1"># creating directory /usr/local/var/postgres ... ok</span>
</span><span class='line'><span class="c1"># creating subdirectories ... ok</span>
</span><span class='line'><span class="c1"># selecting default max_connections ... 100</span>
</span><span class='line'><span class="c1"># selecting default shared_buffers ... 128MB</span>
</span><span class='line'><span class="c1"># selecting dynamic shared memory implementation ... posix</span>
</span><span class='line'><span class="c1"># creating configuration files ... ok</span>
</span><span class='line'><span class="c1"># creating template1 database in /usr/local/var/postgres/base/1 ... ok</span>
</span><span class='line'><span class="c1"># initializing pg_authid ... ok</span>
</span><span class='line'><span class="c1"># initializing dependencies ... ok</span>
</span><span class='line'><span class="c1"># creating system views ... ok</span>
</span><span class='line'><span class="c1"># loading system objects&#39; descriptions ... ok</span>
</span><span class='line'><span class="c1"># creating collations ... ok</span>
</span><span class='line'><span class="c1"># creating conversions ... ok</span>
</span><span class='line'><span class="c1"># creating dictionaries ... ok</span>
</span><span class='line'><span class="c1"># setting privileges on built-in objects ... ok</span>
</span><span class='line'><span class="c1"># creating information schema ... ok</span>
</span><span class='line'><span class="c1"># loading PL/pgSQL server-side language ... ok</span>
</span><span class='line'><span class="c1"># vacuuming database template1 ... ok</span>
</span><span class='line'><span class="c1"># copying template1 to template0 ... ok</span>
</span><span class='line'><span class="c1"># copying template1 to postgres ... ok</span>
</span><span class='line'><span class="c1"># syncing data to disk ... ok# </span>
</span><span class='line'>
</span><span class='line'><span class="c1"># WARNING: enabling &quot;trust&quot; authentication for local connections</span>
</span><span class='line'><span class="c1"># You can change this by editing pg_hba.conf or using the option -A, or</span>
</span><span class='line'><span class="c1"># --auth-local and --auth-host, the next time you run initdb.# </span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Success. You can now start the database server using:# </span>
</span><span class='line'>
</span><span class='line'><span class="c1">#     pg_ctl -D /usr/local/var/postgres -l logfile start</span>
</span></code></pre></td></tr></table></div></figure>


<p>过程中，建了 2 个数据库：<code>template1</code> &amp; <code>postgres</code>，同时创建一个和系统用户同名的用户，密码为空。</p>

<h3>- Install with Docker</h3>

<ul>
<li><a href="https://hub.docker.com/_/postgres/">https://hub.docker.com/_/postgres/</a></li>
<li><a href="https://github.com/docker-library/postgres">https://github.com/docker-library/postgres</a></li>
</ul>


<h4>Docker compose 文件</h4>

<figure class='code'><figcaption><span>postgres-compose.yml</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">postgres</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">container_name</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">postgres-9.4.4</span>
</span><span class='line'>  <span class="l-Scalar-Plain">image</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">postgres:latest</span>
</span><span class='line'>  <span class="l-Scalar-Plain">ports</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="p-Indicator">-</span> <span class="s">&quot;5432:5432&quot;</span>
</span><span class='line'>  <span class="l-Scalar-Plain">environment</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">POSTGRES_PASSWORD=docker1</span>
</span><span class='line'>    <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">POSTGRES_USER=docker1</span>
</span><span class='line'>  <span class="l-Scalar-Plain">volumes</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">/data/docker/postgres:/var/lib/postgresql/data</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>绑定端口</li>
<li>创建时指定用户名，密码</li>
<li>共享 volume</li>
</ul>


<h4>创建、启动 Container</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">docker</span><span class="o">-</span><span class="n">compose</span> <span class="o">-</span><span class="n">f</span> <span class="n">postgres</span><span class="o">-</span><span class="n">compose</span><span class="o">.</span><span class="n">yml</span> <span class="n">up</span> <span class="o">-</span><span class="n">d</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Basic Operation</h2>

<h3>1. 连接数据库</h3>

<p>pg 连接中，需要指定用户名和数据库名，默认用户为<code>系统用户</code>，默认 DB 为 <code>系统用户同名 DB</code>。</p>

<p>这里 DB 可以连  <code>postgres</code>， user 可以用当前系统用户 <code>whoami</code>。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">psql</span> <span class="n">db_name</span> <span class="n">your_username</span>
</span><span class='line'><span class="c1"># 示例</span>
</span><span class='line'><span class="err">$</span> <span class="n">psql</span> <span class="n">postgres</span> <span class="sb">`whoami`</span>
</span></code></pre></td></tr></table></div></figure>


<h3>2. 添加用户 &amp; 新建 DB</h3>

<h5>新建用户</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">pg</span><span class="err">$</span> <span class="no">CREATE</span> <span class="no">USER</span> <span class="n">dbauser</span> <span class="no">WITH</span> <span class="no">PASSWORD</span> <span class="s1">&#39;password&#39;</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<h5>修改密码</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">pg</span><span class="err">$</span> <span class="p">\</span><span class="n">password</span> <span class="n">lanvige</span>
</span></code></pre></td></tr></table></div></figure>


<h5>新建数据库并指定所有者</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">pg</span><span class="err">$</span> <span class="no">CREATE</span> <span class="no">DATABASE</span> <span class="n">newdb</span> <span class="no">OWNER</span> <span class="n">dbauser</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<h5>给用户 dabuser 操作 <code>新DB</code> 的权限</h5>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">GRANT</span> <span class="no">ALL</span> <span class="no">PRIVILEGES</span> <span class="no">ON</span> <span class="no">DATABASE</span> <span class="n">newdb</span> <span class="n">to</span> <span class="n">dbauser</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>更多参见：<code>SQL Commands</code> <a href="http://www.postgresql.org/docs/9.5/static/sql-commands.html">http://www.postgresql.org/docs/9.5/static/sql-commands.html</a></li>
</ul>


<h3>3. 常用数据库操作</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="p">\</span><span class="n">h</span><span class="err">：查看</span><span class="no">SQL</span><span class="err">命令的解释，比如</span><span class="p">\</span><span class="n">h</span> <span class="nb">select</span><span class="err">。</span>
</span><span class='line'><span class="p">\</span><span class="sc">?：</span><span class="err">查看</span><span class="n">psql</span><span class="err">命令列表。</span>
</span><span class='line'><span class="p">\</span><span class="n">l</span><span class="err">：列出所有数据库。</span>
</span><span class='line'><span class="p">\</span><span class="n">c</span> <span class="o">[</span><span class="n">database_name</span><span class="o">]</span><span class="err">：连接其他数据库。</span>
</span><span class='line'><span class="p">\</span><span class="n">d</span><span class="err">：列出当前数据库的所有表格。</span>
</span><span class='line'><span class="p">\</span><span class="n">d</span> <span class="o">[</span><span class="n">table_name</span><span class="o">]</span><span class="err">：列出某一张表格的结构。</span>
</span><span class='line'><span class="p">\</span><span class="n">du</span><span class="err">：列出所有用户。</span>
</span><span class='line'><span class="p">\</span><span class="n">e</span><span class="err">：打开文本编辑器。</span>
</span><span class='line'><span class="p">\</span><span class="n">conninfo</span><span class="err">：列出当前数据库和连接的信息。</span>
</span><span class='line'><span class="p">\</span><span class="ss">q</span><span class="p">:</span> <span class="err">退出</span>
</span></code></pre></td></tr></table></div></figure>


<h4>Example: 列出所有数据库</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">pg</span><span class="c1"># \l</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1">#     #                          List of databases</span>
</span><span class='line'><span class="c1">#    Name    |  Owner  | Encoding | Collate |    Ctype    |  Access privileges</span>
</span><span class='line'><span class="c1"># -----------+---------+----------+---------+-------------+---------------------</span>
</span><span class='line'><span class="c1">#  postgres  | lanvige | UTF8     | C       | en_US.UTF-8 |</span>
</span><span class='line'><span class="c1">#  template0 | lanvige | UTF8     | C       | en_US.UTF-8 | =c/lanvige         +</span>
</span><span class='line'><span class="c1">#            |         |          |         |             | lanvige=CTc/lanvige</span>
</span><span class='line'><span class="c1">#  template1 | lanvige | UTF8     | C       | en_US.UTF-8 | =c/lanvige         +</span>
</span><span class='line'><span class="c1">#            |         |          |         |             | lanvige=CTc/lanvige</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Set Up with a Rails App</h2>

<p>First, install the pg gem:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">gem</span> <span class="n">install</span> <span class="n">pg</span> <span class="o">--</span> <span class="o">--</span><span class="n">with</span><span class="o">-</span><span class="n">pg</span><span class="o">-</span><span class="n">config</span><span class="o">=</span><span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">pg_config</span>
</span></code></pre></td></tr></table></div></figure>


<p>Make sure you include the pg gem in your Gemfile, and run</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">bundle</span> <span class="n">install</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now, set up your config/database.yml file to point to your Posgres database.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="ss">development</span><span class="p">:</span>
</span><span class='line'>  <span class="ss">adapter</span><span class="p">:</span> <span class="n">postgresql</span>
</span><span class='line'>  <span class="ss">encoding</span><span class="p">:</span> <span class="n">unicode</span>
</span><span class='line'>  <span class="ss">database</span><span class="p">:</span> <span class="n">myapp_dev</span>
</span><span class='line'>  <span class="ss">pool</span><span class="p">:</span> <span class="mi">5</span>
</span><span class='line'>  <span class="ss">username</span><span class="p">:</span> <span class="n">your_username_on_mac</span>
</span><span class='line'>  <span class="ss">password</span><span class="p">:</span>
</span><span class='line'>
</span><span class='line'><span class="nb">test</span><span class="p">:</span>
</span><span class='line'>  <span class="ss">adapter</span><span class="p">:</span> <span class="n">postgresql</span>
</span><span class='line'>  <span class="ss">encoding</span><span class="p">:</span> <span class="n">unicode</span>
</span><span class='line'>  <span class="ss">database</span><span class="p">:</span> <span class="n">myapp_test</span>
</span><span class='line'>  <span class="ss">pool</span><span class="p">:</span> <span class="mi">5</span>
</span><span class='line'>  <span class="ss">username</span><span class="p">:</span> <span class="n">your_username_on_mac</span>
</span><span class='line'>  <span class="ss">password</span><span class="p">:</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let’s create the development and test databases:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">rake</span> <span class="ss">db</span><span class="p">:</span><span class="ss">create</span><span class="p">:</span><span class="n">all</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now you can run pending migrations, if there are any.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">rake</span> <span class="ss">db</span><span class="p">:</span><span class="n">migrate</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Migration from MySQL</h2>

<p>将旧的数据库从 MySQL 迁移到 Postgres：</p>

<ul>
<li><a href="https://github.com/lanyrd/mysql-postgresql-converter">https://github.com/lanyrd/mysql-postgresql-converter</a></li>
</ul>


<p>导出 MySQL：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">mysqldump</span> <span class="o">--</span><span class="n">compatible</span><span class="o">=</span><span class="n">postgresql</span> <span class="o">--</span><span class="n">default</span><span class="o">-</span><span class="n">character</span><span class="o">-</span><span class="n">set</span><span class="o">=</span><span class="n">utf8</span> <span class="o">-</span><span class="n">r</span> <span class="n">databasename</span><span class="o">.</span><span class="n">mysql</span> <span class="o">-</span><span class="n">u</span> <span class="n">root</span> <span class="o">-</span><span class="nb">p</span> <span class="n">databasename</span>
</span></code></pre></td></tr></table></div></figure>


<p>转换数据：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">python</span> <span class="n">db_converter</span><span class="o">.</span><span class="n">py</span> <span class="n">gitlabhq_prod</span><span class="o">.</span><span class="n">mysql</span> <span class="n">gitlabhq_prod</span><span class="o">.</span><span class="n">psql</span>
</span></code></pre></td></tr></table></div></figure>


<p>导入 pg：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">psql</span> <span class="o">-</span><span class="n">f</span> <span class="n">databasename</span><span class="o">.</span><span class="n">psql</span>
</span></code></pre></td></tr></table></div></figure>


<p>或者，直接在 pgAdmin 中新建数据库，然后执行 pgScript。</p>

<h2>GUI Tools</h2>

<ul>
<li>pgAdmin3</li>
<li>Postic</li>
<li>PSequel</li>
</ul>


<h2>REF::</h2>

<ul>
<li><a href="http://www.ruanyifeng.com/blog/2013/12/getting_started_with_postgresql.html">阮一峰: PostgreSQL新手入门</a></li>
<li><a href="http://postgres.cn/">Postgres 中国</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iPhone 6s Plus - Rose Gold]]></title>
    <link href="http://blog.lanvige.com/2015/09/25/iphone-6s-plus-rose-gold/"/>
    <updated>2015-09-25T20:00:32+08:00</updated>
    <id>http://blog.lanvige.com/2015/09/25/iphone-6s-plus-rose-gold</id>
    <content type="html"><![CDATA[<p>抢货时，没注意 25 号发货日为周五，想去修改地址时，Apple 告之可能会延迟发货，看来第一时间是肯定不行了，第一天也几乎没希望。</p>

<p>早上上班时，听到同事接到快递电话，要自提，EMS 不送货上门【EMS 请滚出快递界】。然后办公室一天全是各种关于 6s 的声音。还好晚上下班早，赶在 EMS 最后一个员工下班时，取到了手机。</p>

<h2>开箱记</h2>

<p>说实话，拿到手机时没啥兴趣，这次的变化主要是硬件上的，样式上没变化的结果就没什么兴趣。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/iphone-6sp-rg-1.jpg" width="700" height="700"></p>

<h2>Rose Gold == 粉红</h2>

<p>打开手机，发现真机还是偏红色的，很女性，还好没想着自用。</p>

<h2>参数</h2>

<h3>2G RAM</h3>

<p>一直传言要加内存，结果 5s 没加，6 依然没加，6s 发布时也未提及，不过 Android 阵营普遍都是 2G/3G 了。这个也是对 6s 呼声最高的了。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/iphone-6sp-device.jpg" width="320" height="320"></p>

<h3>A9 + M9</h3>

<p>据说， A9 + 2G 打趴带个安卓阵营没有问题。</p>

<h3>3D Touch</h3>

<p>试用了下 3D Touch，算是程序中多了新的交互，大部分时间，可以代替长按，不过有一点让人凌乱的是长按和重压，傻傻分不清楚。特别是在首屏，不知哪个程序可以重压，按的力度和时间控制不好，就变成了删除 App。</p>

<h3>iSight Camera</h3>

<p>新相机带来了 1200W 像素，前置也增加到了 500W，这样，我的红圈真的就再也带不出门了。</p>

<p>清，非常清，这是对新相机的唯一一句评语了。随着相机还有好多好玩的东东。因为相机，所以选内存时，必须是 64G 起了。</p>

<p>Wechat 视频聊天时，被前置 Camera 感动了，实在太清楚了，配上大屏，从未有的感觉。</p>

<h3>Touch ID 2</h3>

<p>Touch ID 真的很好用，从 5 升到 5s 最大的感触就是它了。但经常在手湿，还有一些其它情况下无法解锁，让人无奈，目测，Touch ID 2 现在好了很多。</p>

<h3>USB Type-C</h3>

<p>很喜欢这个标准，不再是 Apple 垄断了，在 MacBook 上配备后，本以为会大面铺开，结果 MacBook 到现在依然是孤独的。</p>

<h2>iPhone 6+ == me</h2>

<p>终于，我换上了 6+，车里再也不能很方便的插手机，还有那个日版拍照咔嚓声。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Node Deploy with Shipit]]></title>
    <link href="http://blog.lanvige.com/2015/09/24/nodejs-deploy-with-shipit/"/>
    <updated>2015-09-24T15:11:32+08:00</updated>
    <id>http://blog.lanvige.com/2015/09/24/nodejs-deploy-with-shipit</id>
    <content type="html"><![CDATA[<p><img src="http://blog.lanvige.com/uploads/node/node-logo.png"></p>

<ul>
<li><a href="http://blog.lanvige.com/2015/09/01/node-index/">Node Index</a></li>
</ul>


<p><img src="http://blog.lanvige.com/uploads/node/shipit.jpg" alt="shipit" /></p>

<ul>
<li><a href="https://github.com/shipitjs/shipit">https://github.com/shipitjs/shipit</a></li>
<li><a href="https://github.com/shipitjs/shipit-deploy">https://github.com/shipitjs/shipit-deploy</a></li>
</ul>


<p>说白点都是“Universal automation and deployment tool”，通用自动化部署工具而已。</p>

<h2>Deploy using Shipit</h2>

<h3>Launch command</h3>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ shipit staging pwd</span></code></pre></td></tr></table></div></figure>


<p>安装</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ cnpm install --global shipit-cli
</span><span class='line'>$ cnpm install --save-dev shipit-cli shipit-deploy shipit-npm shipit-pm2
</span></code></pre></td></tr></table></div></figure>


<h2>Create a shipitfile.js</h2>

<p>You can easily deploy a project using Shipit and its plugin shipit-deploy.</p>

<p>Example shipitfile.js</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>module.exports = function (shipit) {
</span><span class='line'>  require('shipit-deploy')(shipit);
</span><span class='line'>
</span><span class='line'>  shipit.initConfig({
</span><span class='line'>    default: {
</span><span class='line'>      workspace: '/tmp/github-monitor',
</span><span class='line'>      deployTo: '/tmp/deploy_to',
</span><span class='line'>      repositoryUrl: 'https://github.com/user/repo.git',
</span><span class='line'>      ignores: ['.git', 'node_modules'],
</span><span class='line'>      rsync: ['--del'],
</span><span class='line'>      keepReleases: 2,
</span><span class='line'>      key: '/path/to/key',
</span><span class='line'>      shallowClone: true
</span><span class='line'>    },
</span><span class='line'>    staging: {
</span><span class='line'>      servers: 'user@myserver.com'
</span><span class='line'>    }
</span><span class='line'>  });
</span><span class='line'>};</span></code></pre></td></tr></table></div></figure>


<h2>Plug-in</h2>

<h3>shipit-deploy</h3>

<h3>shipit-npm</h3>

<h3>shipit-pm2</h3>

<h2>REF::</h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Node Start]]></title>
    <link href="http://blog.lanvige.com/2015/09/21/node-start/"/>
    <updated>2015-09-21T23:56:17+08:00</updated>
    <id>http://blog.lanvige.com/2015/09/21/node-start</id>
    <content type="html"><![CDATA[<p>Node.js 环境准备。业务线上开始用 node 做一些 api 的事情，所以想借机写一系列随记，帮助想要同样想要学习的人。</p>

<p><img src="http://blog.lanvige.com/uploads/node/node-logo.png"></p>

<h2>nvm</h2>

<p><img src="http://blog.lanvige.com/uploads/node/nvm.jpg" width="480" height="480"></p>

<p>如何安装 node？可能不是一个大问题，但现在 node 三天一个大版本，没有个 node version manager，都不好意思给别人打招呼。</p>

<p>OSX 上的 brew 更新还是挺慢的，所以选择了 nvm，它可以方便的在本机上安装多个指定 node 版本，并方便的在版本间进行切换。</p>

<p><a href="https://github.com/creationix/nvm">https://github.com/creationix/nvm</a></p>

<h3>Install</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># 安装命令</span>
</span><span class='line'><span class="err">$</span> <span class="n">curl</span> <span class="o">-</span><span class="n">o</span><span class="o">-</span> <span class="ss">https</span><span class="p">:</span><span class="sr">//</span><span class="n">raw</span><span class="o">.</span><span class="n">githubusercontent</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">creationix</span><span class="o">/</span><span class="n">nvm</span><span class="o">/</span><span class="n">v0</span><span class="o">.</span><span class="mi">26</span><span class="o">.</span><span class="mi">1</span><span class="o">/</span><span class="n">install</span><span class="o">.</span><span class="n">sh</span> <span class="o">|</span> <span class="n">bash</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Usage</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># 显示所有 nodejs/iojs 版本</span>
</span><span class='line'><span class="err">$</span> <span class="n">nvm</span> <span class="n">ls</span><span class="o">-</span><span class="n">remote</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 本地已安装版本</span>
</span><span class='line'><span class="c1"># nvm ls</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 安装 4.1.1</span>
</span><span class='line'><span class="err">$</span> <span class="n">nvm</span> <span class="n">install</span> <span class="mi">4</span><span class="o">.</span><span class="mi">1</span><span class="o">.</span><span class="mi">1</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 当前 Shell 中配置 node 版本</span>
</span><span class='line'><span class="c1"># nvm use 4.1.1</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># 配置 Shell 默认 node 版本</span>
</span><span class='line'><span class="c1"># nvm alias default 4.1.1</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Testing</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">node</span> <span class="o">-</span><span class="n">v</span>
</span><span class='line'><span class="n">v4</span><span class="o">.</span><span class="mi">1</span><span class="o">.</span><span class="mi">1</span>
</span><span class='line'>
</span><span class='line'><span class="err">$</span> <span class="n">npm</span> <span class="o">-</span><span class="n">v</span>
</span><span class='line'><span class="mi">2</span><span class="o">.</span><span class="mi">14</span><span class="o">.</span><span class="mi">4</span>
</span></code></pre></td></tr></table></div></figure>


<p>It works</p>

<blockquote><p>node 版本小插曲，社区不满 node 的专权和傲慢，于是分裂出了 io.js，1.0, 2.0, 3.0，发展很迅速，但这样不利于长久发展，于是成立了 node 基金会，两家投票后进行了合并，新的 node 基于 io.js 发展而来，版本号从 4.0 开始。rc3 和 rc4 只隔 2 个小时哦～</p></blockquote>

<h2>cnpm</h2>

<p>npm 是 node 的 package manager，像 maven 或 gem 一样。通过它可以很方便的找到和合用非常多的工具集。</p>

<p><img src="http://blog.lanvige.com/uploads/node/npm-logo.jpg" width="480" height="480"></p>

<p>恩，cgoogle，ctwitter，cgithub，当听到这些新名词时，心里一股暖流，当然，npm 也有它的 c 版，并且是由 taobao 提供：</p>

<ul>
<li><a href="http://npm.taobao.org/">http://npm.taobao.org/</a></li>
</ul>


<h3>Install</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="err">$</span> <span class="n">npm</span> <span class="n">install</span> <span class="o">-</span><span class="n">g</span> <span class="n">cnpm</span> <span class="o">--</span><span class="n">registry</span><span class="o">=</span><span class="ss">https</span><span class="p">:</span><span class="sr">//</span><span class="n">registry</span><span class="o">.</span><span class="n">npm</span><span class="o">.</span><span class="n">taobao</span><span class="o">.</span><span class="n">org</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Usage</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># 更新 npm</span>
</span><span class='line'><span class="err">$</span> <span class="n">cnpm</span> <span class="n">update</span> <span class="o">-</span><span class="n">g</span> <span class="n">npm</span><span class="vi">@latest</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># 全局安装</span>
</span><span class='line'><span class="err">$</span> <span class="n">cnpm</span> <span class="n">install</span> <span class="o">-</span><span class="n">g</span> <span class="n">nodemon</span>
</span></code></pre></td></tr></table></div></figure>


<blockquote><p>全局安装是指安装在 <code>~/.nvm/versions/node/v4.1.1/lib/node_modules</code></p></blockquote>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># 非全局安装</span>
</span><span class='line'><span class="err">$</span> <span class="n">cnpm</span> <span class="n">install</span> <span class="n">express</span>
</span></code></pre></td></tr></table></div></figure>


<blockquote><p>非全局安装是指安装在当前目录 <code>${pwd}/node_modules</code></p></blockquote>

<h2>the end</h2>

<p>有了这 node 和 npm，差不多，就等于入了 node 的大门，接下来各般武艺向你扑来，注意接收、学习 &amp; 消化。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[IT 设备折腾记 - 1509]]></title>
    <link href="http://blog.lanvige.com/2015/09/12/my-it-news/"/>
    <updated>2015-09-12T07:46:51+08:00</updated>
    <id>http://blog.lanvige.com/2015/09/12/my-it-news</id>
    <content type="html"><![CDATA[<h2>Dell U2515H</h2>

<p>我的码码配置为 MBP 15 [2012]（i7/16G/SSD） 外接 iMac 27，直到 LP 收回了她的 iMac，直接退回到 Dell 2414h，发现各种不爽，分辨率太小，左右分屏时，单侧无法显示完整信息，于是有了换显示器的想法。</p>

<p>当然了，本着买显示器的唯一原则，Dell U 系，发现了 U2515h，这款显示器，朋友一口气买了 2 个，那叫赞不绝口。于是直接对比了下价格，官网下单。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/dell-u2515h.jpg" alt="dell-u2515h" /></p>

<h3>Dell 电商</h3>

<p>不得不吐槽下 Dell 自己做的电商，下完单，无法在自己账号里看到定单，隔天会有人邮件给你联系，问是否付款，回是，对方说会花 2 天时间进行确认。</p>

<p>几天后说显示器开始生产，再过几天发货。这流程，哪是一个现代化电商的脚步啊～</p>

<h3>八字不合</h3>

<p>显示器到货后，接上发现信号能检测到，但就是黑屏，试了 MBP &amp; iMac，均有些问题。HDMI 分辨率达不到，DP 则无法正常显示，差不多就是换个分辨率，能好一会，会有闪屏现象。</p>

<p>隔天，拿公司的 rMBP 13 [2014]，接上就亮，试了下 DP &amp; HDMI 均无问题。</p>

<h3>退货</h3>

<p>联系 Dell 客户关怀，他们说有 7 天无条件退货。于是申请，结果每次客服都让我描述一堆的问题，反正就是想证明不是显示器问题。后来还因我将发标 title 开成了公司，而没退成。不过最终他们还是收回了显示器。服务也很 nice。</p>

<p>期间把显示器带到公司，给同事用了下，本想价格优惠外加分期让利出掉，结果同事太纠结了。</p>

<h2>iMac 5K</h2>

<p>退了 Dell 之后，就真的没有什么可选的了。虽然另一同事将 AOC 28 4K 搬到了公司用。字体细腻，但真的没兴趣。只有另一个选择了 iMac 27 5K。</p>

<p><img src="http://blog.lanvige.com/uploads/iampc/imac-retina.jpg" alt="imac-retina" /></p>

<p>为止，还开通了上下班拼车，每个月赚个千百元，当然，用储备金可以立即下单，但这样好玩，另话了。</p>

<p>期待新款的一些特性：</p>

<ul>
<li>Skylake CPU</li>
<li>USBC</li>
<li>Fusion Drive Storge 标配</li>
<li>HBM 版 R300 显卡</li>
</ul>


<p>然后就是不知新款什么时间会上市，毕竟 2015 苹果已经开了 2 次发布会，而且秋季出了这么多东西。</p>

<p>其次，就是不知 MBP 能不能外接 iMac 27。</p>

<h2>iPhone 6s+ Rose Gold</h2>

<p><img src="http://blog.lanvige.com/uploads/iampc/iphone-6sp-rg.jpg" alt="imac-retina" /></p>

<p>Apple 一直不宣布到底用了多大内存，这让我对 6s 有着很多不确定性。因为 5s 依然很完美，对大屏没有需求。</p>

<p>后来，开始抢购那开，还是用了点了一个多小时，战果就是收了3台 6s+ 玫瑰金，当然，是系统的 bug 所致。后来退了 2 台。</p>

<p>其余的，只能等真机了。不过听说客服回答是 2G RAM，不明白为啥一直宣传 A9，1200W，但到了内存这里，就不在乎硬件，只要体验好就 OK，什么逻辑。</p>

<p>等，等等等等 &hellip;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Node Index]]></title>
    <link href="http://blog.lanvige.com/2015/09/01/node-index/"/>
    <updated>2015-09-01T09:57:19+08:00</updated>
    <id>http://blog.lanvige.com/2015/09/01/node-index</id>
    <content type="html"><![CDATA[<p>Node.js 环境准备。业务线上开始用 node 做一些 api 的事情，所以想借机写一系列随记，帮助想要同样想要学习的人。</p>

<p><img src="http://blog.lanvige.com/uploads/node/node-logo.png"></p>
]]></content>
  </entry>
  
</feed>
