<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Just a Blog</title>
    <link>https://super.writeas.com/</link>
    <description></description>
    <pubDate>Tue, 05 May 2026 07:50:42 +0000</pubDate>
    <item>
      <title>Install docker on Raspbian Pi 4</title>
      <link>https://super.writeas.com/install-docker-on-raspbian-pi-4?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Raspbian Version: Pi 4&#xA;OS System: Raspbian/buster (use lsb_release -cs to print)&#xA;Verified Date: 2020/04/12&#xA;&#xA;1. Uninstall old versions&#xA;&#xA;$ sudo apt-get remove docker docker-engine docker.io containerd runc&#xA;&#xA;2. Install Tool Chain&#xA;$ sudo apt-get update&#xA;&#xA;$ sudo apt-get install \&#xA;    apt-transport-https \&#xA;    ca-certificates \&#xA;    curl \&#xA;    gnupg-agent \&#xA;    software-properties-common&#xA;3. Add GPG key&#xA;&#xA;$ curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo apt-key add -&#xA;&#xA;4. Add repository&#xA;&#xA;$ sudo vim /etc/apt/sources.list.d/docker.list&#xA;&#xA;Add this line and save:&#xA;&#xA;add docker repository&#xA;deb [arch=armhf] https://download.docker.com/linux/raspbian buster stable&#xA;&#xA;5. Install via apt&#xA; $ sudo apt-get update&#xA; $ sudo apt-get install docker-ce docker-ce-cli containerd.io&#xA;&#xA;Troubleshooting&#xA;You may encounter this error when apt install running:&#xA;Errors were encountered while processing:&#xA; aufs-dkms&#xA;We can simply ignore it. Because aufs-dkms is not a dependency of docker-ce, but a recommendation. &#xA;&#xA;Docker is not default to use aufs anymore; It now default prefer to use overlayfs2, which have been merged to the linux kernel mainline since 3.18.&#xA;&#xA;[1] https://docs.docker.com/engine/install/debian/&#xA;[2] https://github.com/raspberrypi/linux/issues/3021#issuecomment-508704040]]&gt;</description>
      <content:encoded><![CDATA[<p>Raspbian Version: Pi 4
OS System: Raspbian/buster (use <code>lsb_release -cs</code> to print)
Verified Date: 2020/04/12</p>

<h3 id="1-uninstall-old-versions" id="1-uninstall-old-versions">1. Uninstall old versions</h3>

<p><code>$ sudo apt-get remove docker docker-engine docker.io containerd runc</code></p>

<h3 id="2-install-tool-chain" id="2-install-tool-chain">2. Install Tool Chain</h3>

<pre><code>$ sudo apt-get update

$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
</code></pre>

<h3 id="3-add-gpg-key" id="3-add-gpg-key">3. Add GPG key</h3>

<p><code>$ curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo apt-key add -</code></p>

<h3 id="4-add-repository" id="4-add-repository">4. Add repository</h3>

<p><code>$ sudo vim /etc/apt/sources.list.d/docker.list</code></p>

<p>Add this line and save:</p>

<pre><code># add docker repository
deb [arch=armhf] https://download.docker.com/linux/raspbian buster stable
</code></pre>

<h3 id="5-install-via-apt" id="5-install-via-apt">5. Install via apt</h3>

<pre><code> $ sudo apt-get update
 $ sudo apt-get install docker-ce docker-ce-cli containerd.io
</code></pre>

<h3 id="troubleshooting" id="troubleshooting">Troubleshooting</h3>

<p>You may encounter this error when apt install running:</p>

<pre><code>Errors were encountered while processing:
 aufs-dkms
</code></pre>

<p>We can simply ignore it. Because aufs-dkms is not a dependency of docker-ce, but a recommendation.</p>

<p>Docker is not default to use aufs anymore; It now default prefer to use overlayfs2, which have been merged to the linux kernel mainline since 3.18.</p>

<p>[1] <a href="https://docs.docker.com/engine/install/debian/" rel="nofollow">https://docs.docker.com/engine/install/debian/</a>
[2] <a href="https://github.com/raspberrypi/linux/issues/3021#issuecomment-508704040" rel="nofollow">https://github.com/raspberrypi/linux/issues/3021#issuecomment-508704040</a></p>
]]></content:encoded>
      <guid>https://super.writeas.com/install-docker-on-raspbian-pi-4</guid>
      <pubDate>Sun, 12 Apr 2020 11:24:34 +0000</pubDate>
    </item>
    <item>
      <title>“Can&#39;t reach Google Drive” From Google Drive File Stream</title>
      <link>https://super.writeas.com/cant-reach-google-drive-from-google-drive-file-stream?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[System: Windows 10&#xA;Software: Drive File Stream&#xA;Error: After installation and login then encounter a error message: “Can&#39;t reach Google Drive”&#xA;&#xA;Drive File Stream: Can&#39;t reach Google Drive&#xA;&#xA;Solution:&#xA;&#xA;Open your Registry Editor, In HKEY\LOCAL\MACHINE\Software\Google\DriveFS, create two new DWORD values, DisableCRLCheck and DirectConnection, assigning value data as 1.&#xA;&#xA;solution&#xA;&#xA;Reference: https://tinyapps.org/blog/201909120700can&#39;treachgoogledrive.html&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>System: Windows 10
Software: Drive File Stream
Error: After installation and login then encounter a error message: “Can&#39;t reach Google Drive”</p>

<p><img src="https://tinyapps.org/screenshots/cant-reach-google-drive.png" alt="Drive File Stream: Can&#39;t reach Google Drive"/></p>

<p>Solution:</p>

<p>Open your Registry Editor, In <code>HKEY\_LOCAL\_MACHINE\Software\Google\DriveFS</code>, create two new DWORD values, DisableCRLCheck and DirectConnection, assigning value data as 1.</p>

<p><img src="https://i.imgur.com/N8pxr8L.png" alt="solution"/></p>

<p>Reference: <a href="https://tinyapps.org/blog/201909120700_can&#39;t_reach_google_drive.html" rel="nofollow">https://tinyapps.org/blog/201909120700_can&#39;t_reach_google_drive.html</a></p>
]]></content:encoded>
      <guid>https://super.writeas.com/cant-reach-google-drive-from-google-drive-file-stream</guid>
      <pubDate>Wed, 20 Nov 2019 12:39:47 +0000</pubDate>
    </item>
    <item>
      <title>使用树莓派4搭建下载机</title>
      <link>https://super.writeas.com/shi-yong-shu-mei-pai-4da-jian-xia-zai-ji?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[下载机是指可以远程操控下载文件到本地的机器，一般要 24 小时开启。树莓派因为其耗电量极低非常适合此应用场景。&#xA;&#xA;树莓派安装&#xA;&#xA;至少需要以下硬件：树莓派4主板 + TF 存储卡 + USB存储设备 + 电源(3V/5A) + 连网（有线）&#xA;&#xA;操作工具：PC一台 + USB 接口的 TF 读卡器 + 连网（有线或无线均可）&#xA;&#xA;流程如下：&#xA;&#xA;下载官方镜像，插入读卡器，使用软件写入 TF 卡（PC上操作）&#xA;修改 TF 卡镜像文件中部分配置（PC上操作）&#xA;把 TF 卡从读卡器取出并插入树莓派主板（操作树莓派）&#xA;接网线、电源、USB存储设备，通电（操作树莓派）&#xA;进入路由器查看树莓派的 IP（PC上操作）&#xA;SSH 连接（PC上操作）&#xA;&#xA;细节补充 !--more--&#xA;&#xA;官方镜像请使用 lite 版本：Raspbian Buster Lite。Desktop 不在讨论之列。写入镜像使用 Win32 Disk Imager：https://sourceforge.net/projects/win32diskimager/&#xA;只需要在 TF 卡新的分区中新建一个空白的文件，名字为 ssh&#xA;树莓派主板上有个插口用来接 TF 卡的。如果直接把 USB 读卡器塞到 USB 接口里，系统不会启动。&#xA;电源最好 3V 以上，否则怕电压不稳。USB 存储设备最好能独立供电。&#xA;这一步需要有路由器权限，如果无法进路由器，下载一个内网 ARP 扫描器也可以。树莓派的 Hostname 就是英文的 raspberry pi。如果路由器里没有看到树莓派，那就是树莓派没有启动，需要检查 3、4 步骤是否正确。&#xA;用户名和密码分别是 pi 和 raspberry。进去后先 passwd 改密码。进入 SSH 后更新源等操作略过。&#xA;&#xA;挂载 USB 存储&#xA;&#xA;检查存储设备是否被识别&#xA;安装 ntfs-3g&#xA;挂载 ntfs 分区&#xA;&#xA;先看看自己的设备是否有被识别到：sudo lsblk -f 或者 sudo fdisk -l&#xA;&#xA;265319cccec5af92b1e87cdc4199d7ac.png&#xA;&#xA;为了方便存储日后与 Windows 共享，我的存储设备使用的 NTFS 格式的文件系统。所以在分区系统里会有 sda1 和 sda2，sda1 是 NTFS 自用预留的分区，sd2 是数据存放区，也是需要挂载的分区。在 NTFS 系统上读写需要在 Linux 上安装 ntfs-3g：apt install ntfs-3g&#xA;&#xA;最后将存储设备挂载到 /mnt/hd1 目录下：&#xA;mkdir /mnt/hd1 &amp;&amp; sudo mount -t ntfs-3g /dev/sda2 /mnt/hd1 &#xA;挂载完成后使用 df -h 即可看到可用空间已经增加。&#xA;&#xA;Aria2 安装&#xA;安装并建立配置文件与下载目录&#xA;写入配置文件&#xA;启动守护进程，提供 rpc 服务&#xA;&#xA;使用 apt install aria2 安装后需要为其建立一个配置文件存放地，我选择放在 pi 目录下。mkdir ~/.aria2。建立以下两个文件：touch ~/.aria2/aria2.conf 和 touch ~/.aria2/aria2.session 后面配置会用到。建立一个下载文件的目录，我选择在 USB 存储设备上建立 mkdir /mnt/hd1/downloads&#xA;&#xA;写入以下内容到 aria2.conf 中：&#xA;dir=/mnt/hd1/downloads&#xA;continue=true&#xA;disable-ipv6=true&#xA;input-file=/home/pi/.aria2/aria2.session&#xA;save-session=/home/pi/.aria2/aria2.session&#xA;enable-rpc=true&#xA;rpc-listen-port=6800&#xA;rpc-secure=false&#xA;rpc-listen-all=true&#xA;rpc-allow-origin-all=true&#xA;rpc-secret=密码&#xA;&#xA;启动守护进程：aria2c --conf-path ~/.aria2/aria2.conf -D。这样 aria2 会在后端监听 6800 端口。每次修改完配置文件后，需要杀掉进程重启 killall aria2c。你当然可以把 aria2c 做成服务，但我太懒了。&#xA;&#xA;Aria2 WebUI 安装和设置&#xA;&#xA;下载文件&#xA;放到树莓派 Nginx 下&#xA;使用 token 配置并访问&#xA;&#xA;Aria2 WebUI 本质上就是一个静态 HTML 文件，通过 Javascript 远程向 rpc 服务发送 http 请求。在这里直接下载 zip 文件：https://github.com/ziahamza/webui-aria2/archive/master.zip &#xA;&#xA;下载后的文件夹一大堆文件，请仅保留 docs 目录，其他的都删除即可。&#xA;&#xA;安装 nginx apt install nginx 把 docs 目录放到 /var/www/html 之下。&#xA;&#xA;在 PC 端浏览器输入 http://树莓派IP/docs 即可进入 webui 界面。进去后点击 Connection Settings &#xA;&#xA;在这一栏 Enter the port: 写 6800&#xA;在这一栏 Enter the secret token (optional):  写进去上一步的密码即可。&#xA;&#xA;连接成功后，左侧会出现配置文件等信息。&#xA;&#xA;eae935e42aa40130ca927ac33fdf2f7f.png&#xA;&#xA;目前为止仅仅支持内网访问。你可以绑定一个域名，用 ddns 去映射到公共网络，或者如果你在内网，使用 frp 穿透到公共网络。这些需要额外设置一下 nginx。由于本人太懒，就先写到这里了。😁&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>下载机是指可以远程操控下载文件到本地的机器，一般要 24 小时开启。树莓派因为其耗电量极低非常适合此应用场景。</p>

<h2 id="树莓派安装">树莓派安装</h2>

<p>至少需要以下硬件：树莓派4主板 + TF 存储卡 + USB存储设备 + 电源(3V/5A) + 连网（有线）</p>

<p>操作工具：PC一台 + USB 接口的 TF 读卡器 + 连网（有线或无线均可）</p>

<p>流程如下：</p>
<ol><li>下载官方镜像，插入读卡器，使用软件写入 TF 卡（PC上操作）</li>
<li>修改 TF 卡镜像文件中部分配置（PC上操作）</li>
<li>把 TF 卡从读卡器取出并插入树莓派主板（操作树莓派）</li>
<li>接网线、电源、USB存储设备，通电（操作树莓派）</li>
<li>进入路由器查看树莓派的 IP（PC上操作）</li>
<li>SSH 连接（PC上操作）</li></ol>

<p>细节补充 </p>
<ol><li>官方镜像请使用 lite 版本：Raspbian Buster Lite。Desktop 不在讨论之列。写入镜像使用 Win32 Disk Imager：<a href="https://sourceforge.net/projects/win32diskimager/" rel="nofollow">https://sourceforge.net/projects/win32diskimager/</a></li>
<li>只需要在 TF 卡新的分区中新建一个空白的文件，名字为 ssh</li>
<li>树莓派主板上有个插口用来接 TF 卡的。如果直接把 USB 读卡器塞到 USB 接口里，系统不会启动。</li>
<li>电源最好 3V 以上，否则怕电压不稳。USB 存储设备最好能独立供电。</li>
<li>这一步需要有路由器权限，如果无法进路由器，下载一个内网 ARP 扫描器也可以。树莓派的 Hostname 就是英文的 raspberry pi。如果路由器里没有看到树莓派，那就是树莓派没有启动，需要检查 3、4 步骤是否正确。</li>
<li>用户名和密码分别是 <code>pi</code> 和 <code>raspberry</code>。进去后先 <code>passwd</code> 改密码。进入 SSH 后更新源等操作略过。</li></ol>

<h2 id="挂载-usb-存储" id="挂载-usb-存储">挂载 USB 存储</h2>
<ol><li>检查存储设备是否被识别</li>
<li>安装 ntfs-3g</li>
<li>挂载 ntfs 分区</li></ol>

<p>先看看自己的设备是否有被识别到：<code>sudo lsblk -f</code> 或者 <code>sudo fdisk -l</code></p>

<p><img src="https://286.im/images/2019/08/04/265319cccec5af92b1e87cdc4199d7ac.png" alt="265319cccec5af92b1e87cdc4199d7ac.png"/></p>

<p>为了方便存储日后与 Windows 共享，我的存储设备使用的 NTFS 格式的文件系统。所以在分区系统里会有 sda1 和 sda2，sda1 是 NTFS 自用预留的分区，sd2 是数据存放区，也是需要挂载的分区。在 NTFS 系统上读写需要在 Linux 上安装 ntfs-3g：<code>apt install ntfs-3g</code></p>

<p>最后将存储设备挂载到 /mnt/hd1 目录下：
<code>mkdir /mnt/hd1 &amp;&amp; sudo mount -t ntfs-3g /dev/sda2 /mnt/hd1</code>
挂载完成后使用 <code>df -h</code> 即可看到可用空间已经增加。</p>

<h2 id="aria2-安装" id="aria2-安装">Aria2 安装</h2>
<ol><li>安装并建立配置文件与下载目录</li>
<li>写入配置文件</li>
<li>启动守护进程，提供 rpc 服务</li></ol>

<p>使用 <code>apt install aria2</code> 安装后需要为其建立一个配置文件存放地，我选择放在 pi 目录下。<code>mkdir ~/.aria2</code>。建立以下两个文件：<code>touch ~/.aria2/aria2.conf</code> 和 <code>touch ~/.aria2/aria2.session</code> 后面配置会用到。建立一个下载文件的目录，我选择在 USB 存储设备上建立 <code>mkdir /mnt/hd1/downloads</code></p>

<p>写入以下内容到 aria2.conf 中：</p>

<pre><code>dir=/mnt/hd1/downloads
continue=true
disable-ipv6=true
input-file=/home/pi/.aria2/aria2.session
save-session=/home/pi/.aria2/aria2.session
enable-rpc=true
rpc-listen-port=6800
rpc-secure=false
rpc-listen-all=true
rpc-allow-origin-all=true
rpc-secret=密码
</code></pre>

<p>启动守护进程：<code>aria2c --conf-path ~/.aria2/aria2.conf -D</code>。这样 aria2 会在后端监听 6800 端口。每次修改完配置文件后，需要杀掉进程重启 <code>killall aria2c</code>。你当然可以把 aria2c 做成服务，但我太懒了。</p>

<h2 id="aria2-webui-安装和设置" id="aria2-webui-安装和设置">Aria2 WebUI 安装和设置</h2>
<ol><li>下载文件</li>
<li>放到树莓派 Nginx 下</li>
<li>使用 token 配置并访问</li></ol>

<p>Aria2 WebUI 本质上就是一个静态 HTML 文件，通过 Javascript 远程向 rpc 服务发送 http 请求。在这里直接下载 zip 文件：<a href="https://github.com/ziahamza/webui-aria2/archive/master.zip" rel="nofollow">https://github.com/ziahamza/webui-aria2/archive/master.zip</a></p>

<p>下载后的文件夹一大堆文件，请仅保留 docs 目录，其他的都删除即可。</p>

<p>安装 nginx <code>apt install nginx</code> 把 docs 目录放到 <code>/var/www/html</code> 之下。</p>

<p>在 PC 端浏览器输入 http://树莓派IP/docs 即可进入 webui 界面。进去后点击 Connection Settings</p>

<p>在这一栏 Enter the port: 写 6800
在这一栏 Enter the secret token (optional):  写进去上一步的密码即可。</p>

<p>连接成功后，左侧会出现配置文件等信息。</p>

<p><img src="https://286.im/images/2019/08/04/eae935e42aa40130ca927ac33fdf2f7f.png" alt="eae935e42aa40130ca927ac33fdf2f7f.png"/></p>

<p>目前为止仅仅支持内网访问。你可以绑定一个域名，用 ddns 去映射到公共网络，或者如果你在内网，使用 frp 穿透到公共网络。这些需要额外设置一下 nginx。由于本人太懒，就先写到这里了。😁</p>
]]></content:encoded>
      <guid>https://super.writeas.com/shi-yong-shu-mei-pai-4da-jian-xia-zai-ji</guid>
      <pubDate>Sun, 04 Aug 2019 12:32:09 +0000</pubDate>
    </item>
    <item>
      <title>mastodon 使用 minio 托管媒体文件</title>
      <link>https://super.writeas.com/mastodon-shi-yong-minio-tuo-guan-mei-ti-wen-jian?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[安装 minio&#xA;&#xA;minio 发音是迷你欧，是一个兼容 S3 协议的存储系统，使用 Go 开发，推荐用 docker 部署。&#xA;&#xA;docker pull minio/minio&#xA;&#xA;用最少参数启动 minio：docker run -p 9000:9000 minio/minio server /data 这样启动的容器无法保留数据，重启后数据会清零，不能在生产环境使用。&#xA;&#xA;实际环境中：docker run -p 9000:9000 --name minio1 -e &#34;MINIOACCESSKEY=YOURKEY&#34; -e &#34;MINIOSECRETKEY=YOURSECRET&#34; -e &#34;MINIOBROWSER=off&#34; -v /mnt/data:/data -v /mnt/config:/root/.minio minio/minio server /data，如果是第一次建立镜像，Key 参数可以省略，会自动生成 Key 和 Secret。&#xA;&#xA;这些参数建立的容器可以把配置文件和数据文件持久化到 /mnt/ 目录下。带上访问 Key 参数否则每次新建的容器都会产生新的随机密钥。MINIOBROWSER=off 带上这个环境变量可以关闭 web ui 界面。使用官方的 mc 客户端管理功能强大，不建议开启 web 界面，只会增加安全风险。!--more--&#xA;&#xA;配置 nginx&#xA; server {&#xA;  listen 80;&#xA;  servername example.com;&#xA;  ignoreinvalidheaders off;&#xA;  clientmaxbodysize 0;&#xA;  proxybuffering off;&#xA; &#xA;  location / {&#xA;    proxyhttpversion 1.1&#xA;    proxysetheader Host $httphost;&#xA;    proxyreadtimeout 15m;&#xA;    proxysendtimeout 15m;&#xA;    proxyrequestbuffering off;&#xA;    proxypass http://localhost:9000;    &#xA;  }&#xA; }&#xA;&#xA;这是 80 端口的配置，443 端口类似。官方给的配置中包含 healthcheck uri=/minio/health/ready; 这个是商业版的 nginx 才有的功能。&#xA;&#xA;mc 设置&#xA;mc 是连接 bucket 的客户端工具，安装在 rails app 所在的服务器上方便直接拷贝相关文件。&#xA;&#xA;wget https://dl.min.io/client/mc/release/linux-amd64/mc&#xA;chmod +x mc&#xA;./mc config&#xA;以上命令下载 mc 并生成默认配置文件。&#xA;&#xA;vim .mc/config.json 编辑配置文件，直接修改 play 的 block，把 Key 填写进去。&#xA;&#xA;mc admin info play 看到类似信息就说明连接成功了。&#xA;&#xA;  ●  example.com&#xA;  Uptime: 33 minutes                                                                                                     &#xA;  Version: 2019-07-17T22:54:12Z&#xA;  Storage: Used 2.9 GiB&#xA;&#xA;bucket 设置&#xA;&#xA;mc md play/mastodon 新建一个桶，mc policy download play/mastodon 使得可以通过 http(s)://base-url/mastodon/file-path.jpg 来直接访问文件。&#xA;&#xA;以上设置会导致访问目录时列出所有文件。当前使用 mc 客户端无法设置 S3 兼容的 policy，所以还需要下载 aws-cli 来设置更精准的权限。&#xA;&#xA;aws 安装后首先配置 aws configure&#xA;&#xA;AWS Access Key ID [*************9TA4]:&#xA;AWS Secret Access Key [************Puw8]:&#xA;Default region name [None]:&#xA;Default output format [None]: text&#xA;&#xA;准备好 /tmp/policy.json 文件，内容如下：&#xA;&#xA;{&#xA;   &#34;Version&#34;:&#34;2012-10-17&#34;,&#xA;   &#34;Statement&#34;:[&#xA;      {&#xA;         &#34;Effect&#34;:&#34;Allow&#34;,&#xA;         &#34;Principal&#34;:{&#xA;            &#34;AWS&#34;:[&#xA;               &#34;&#34;&#xA;            ]&#xA;         },&#xA;         &#34;Action&#34;:[&#xA;            &#34;s3:GetObject&#34;&#xA;         ],&#xA;         &#34;Resource&#34;:[&#xA;            &#34;arn:aws:s3:::mastodon/&#34;&#xA;         ]&#xA;      }&#xA;   ]&#xA;}&#xA;&#xA;把 policy 更新到 minio：aws --endpoint-url http://localhost:9000 s3api put-bucket-policy --bucket mastodon --policy file:///tmp/policy.json &#xA;&#xA;注意本地文件名必须要以 file:// 协议打开，否则会返回如下错误：&#xA;&#xA;  An error occurred (MalformedPolicy) when calling the PutBucketPolicy operation: Policy has invalid resource.&#xA;&#xA;复制文件到 minio&#xA;mc cp --recursive ~/live/public/system play/mastodon 会把 system 文件夹复制到 minio 的 mastodon 桶里。可以在切换 mastodon 配置时候重新执行一次  mc cp --recursive --newer-than 0d1h ~/live/public/system play/mastodon 这样会只复制 1 小时之前到现在产生的文件。&#xA;&#xA;修改 mastodon 环境配置&#xA;&#xA; S3ENABLED=true&#xA; S3PROTOCOL=https&#xA; S3BUCKET=mastodon&#xA; S3HOSTNAME=example.com&#xA; AWSACCESSKEYID=YOURKEY&#xA; AWSSECRETACCESSKEY=YOURSECRET&#xA; S3ENDPOINT=http://example.com/&#xA;&#xA;修改完毕后重启 web、streaming 和 sidekiq 服务。sudo systemctl restart mastodon-。刷新前端，图片应该已经改为 minio 的网址了。格式为：http(s)://your-minio-domain/mastodon/mediaattachments/files/***&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<h3 id="安装-minio" id="安装-minio">安装 minio</h3>

<p>minio 发音是迷你欧，是一个兼容 S3 协议的存储系统，使用 Go 开发，推荐用 docker 部署。</p>

<p><code>docker pull minio/minio</code></p>

<p>用最少参数启动 minio：<code>docker run -p 9000:9000 minio/minio server /data</code> 这样启动的容器无法保留数据，重启后数据会清零，不能在生产环境使用。</p>

<p>实际环境中：<code>docker run -p 9000:9000 --name minio1 -e &#34;MINIO_ACCESS_KEY=YOURKEY&#34; -e &#34;MINIO_SECRET_KEY=YOURSECRET&#34; -e &#34;MINIO_BROWSER=off&#34; -v /mnt/data:/data -v /mnt/config:/root/.minio minio/minio server /data</code>，如果是第一次建立镜像，Key 参数可以省略，会自动生成 Key 和 Secret。</p>

<p>这些参数建立的容器可以把配置文件和数据文件持久化到 /mnt/ 目录下。带上访问 Key 参数否则每次新建的容器都会产生新的随机密钥。<code>MINIO_BROWSER=off</code> 带上这个环境变量可以关闭 web ui 界面。使用官方的 mc 客户端管理功能强大，不建议开启 web 界面，只会增加安全风险。</p>

<h3 id="配置-nginx" id="配置-nginx">配置 nginx</h3>

<pre><code>server {
  listen 80;
  server_name example.com;
  ignore_invalid_headers off;
  client_max_body_size 0;
  proxy_buffering off;
 
  location / {
    proxy_http_version 1.1
    proxy_set_header Host $http_host;
    proxy_read_timeout 15m;
    proxy_send_timeout 15m;
    proxy_request_buffering off;
    proxy_pass http://localhost:9000;    
  }
 }
</code></pre>

<p>这是 80 端口的配置，443 端口类似。官方给的配置中包含 <code>health_check uri=/minio/health/ready;</code> 这个是商业版的 nginx 才有的功能。</p>

<h3 id="mc-设置" id="mc-设置">mc 设置</h3>

<p>mc 是连接 bucket 的客户端工具，安装在 rails app 所在的服务器上方便直接拷贝相关文件。</p>

<pre><code>wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
./mc config
</code></pre>

<p>以上命令下载 mc 并生成默认配置文件。</p>

<p><code>vim .mc/config.json</code> 编辑配置文件，直接修改 play 的 block，把 Key 填写进去。</p>

<p><code>mc admin info play</code> 看到类似信息就说明连接成功了。</p>

<blockquote><p>●  example.com
   Uptime: 33 minutes<br/>
   Version: 2019-07-17T22:54:12Z
  Storage: Used 2.9 GiB</p></blockquote>

<h3 id="bucket-设置" id="bucket-设置">bucket 设置</h3>

<p><code>mc md play/mastodon</code> 新建一个桶，<del><code>mc policy download play/mastodon</code> 使得可以通过 http(s)://base-url/mastodon/file-path.jpg 来直接访问文件。</del></p>

<p>以上设置会导致访问目录时列出所有文件。当前使用 mc 客户端无法设置 S3 兼容的 policy，所以还需要下载 aws-cli 来设置更精准的权限。</p>

<p>aws 安装后首先配置<code>aws configure</code></p>

<pre><code>AWS Access Key ID [****************9TA4]:
AWS Secret Access Key [****************Puw8]:
Default region name [None]:
Default output format [None]: text
</code></pre>

<p>准备好 /tmp/policy.json 文件，内容如下：</p>

<pre><code>{
   &#34;Version&#34;:&#34;2012-10-17&#34;,
   &#34;Statement&#34;:[
      {
         &#34;Effect&#34;:&#34;Allow&#34;,
         &#34;Principal&#34;:{
            &#34;AWS&#34;:[
               &#34;*&#34;
            ]
         },
         &#34;Action&#34;:[
            &#34;s3:GetObject&#34;
         ],
         &#34;Resource&#34;:[
            &#34;arn:aws:s3:::mastodon/*&#34;
         ]
      }
   ]
}
</code></pre>

<p>把 policy 更新到 minio：<code>aws --endpoint-url http://localhost:9000 s3api put-bucket-policy --bucket mastodon --policy file:///tmp/policy.json</code></p>

<p>注意本地文件名必须要以 file:// 协议打开，否则会返回如下错误：</p>

<blockquote><p>An error occurred (MalformedPolicy) when calling the PutBucketPolicy operation: Policy has invalid resource.</p></blockquote>

<h3 id="复制文件到-minio" id="复制文件到-minio">复制文件到 minio</h3>

<p><code>mc cp --recursive ~/live/public/system play/mastodon</code> 会把 system 文件夹复制到 minio 的 mastodon 桶里。可以在切换 mastodon 配置时候重新执行一次  <code>mc cp --recursive --newer-than 0d1h ~/live/public/system play/mastodon</code> 这样会只复制 1 小时之前到现在产生的文件。</p>

<h3 id="修改-mastodon-环境配置" id="修改-mastodon-环境配置">修改 mastodon 环境配置</h3>

<pre><code> S3_ENABLED=true
 S3_PROTOCOL=https
 S3_BUCKET=mastodon
 S3_HOSTNAME=example.com
 AWS_ACCESS_KEY_ID=YOURKEY
 AWS_SECRET_ACCESS_KEY=YOURSECRET
 S3_ENDPOINT=http://example.com/
</code></pre>

<p>修改完毕后重启 web、streaming 和 sidekiq 服务。<code>sudo systemctl restart mastodon-*</code>。刷新前端，图片应该已经改为 minio 的网址了。格式为：http(s)://your-minio-domain/mastodon/media_attachments/files/***</p>
]]></content:encoded>
      <guid>https://super.writeas.com/mastodon-shi-yong-minio-tuo-guan-mei-ti-wen-jian</guid>
      <pubDate>Fri, 26 Jul 2019 09:55:42 +0000</pubDate>
    </item>
    <item>
      <title>部署 Azure CDN 的血泪经历</title>
      <link>https://super.writeas.com/bu-shu-azure-cdn-de-xie-lei-jing-li?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Cloudflare 的问题&#xA;&#xA;想要使用 Cloudflare 必须要修改域名的 Name Server。Cloudflare 的 DNS 系统在界面和功能都堪称业界一流，就单说 CNAME Flattening 就非常的好用，支持这个功能的 DNS Provider 也没几家。还有就是解析速度快的飞起，修改解析记录后，本地网络几乎都是秒级响应。&#xA;&#xA;最大的问题是在于中国境内复杂的网络环境下，Cloudflare 的优势荡然无存。无论从连接的稳定性还是速度都很差，往往不如直接访问源主机更快。&#xA;&#xA;Cloudflare 适合以下的情况使用：&#xA;&#xA;访客群体在中国大陆以外&#xA;网站经常经受高强度 DDos 攻击&#xA;&#xA;满足以上任意一条，Cloudflare 都是很好的选择。其他情况下几乎都不是好的选择。!--more--&#xA;&#xA;Google Cloud CDN 的问题&#xA;&#xA;Google 的 CDN 只能给自己云上的实例使用，不支持外部源。这点让自己处于二线选手。&#xA;&#xA;Windows Azure&#xA;&#xA;Windows Azure 的优势和劣势也很明显。优势是他家的 CDN 部署后，在中国的访问速度非常快；劣势就是烦人的后台操作以及感人的价格。&#xA;&#xA;就单 Azure 的操作界面来讲，功能和布局算是合理的。后台之所以烦人，是因为几乎所有的操作都需要等待时间。当你点击了任意的按钮，右上角的 Notifications 就开始转了起来。接下来你可以去上个厕所回来再喝个咖啡，然后它可能还在转。我一点也没有夸张。&#xA;&#xA;想要在 Windows Azure CDN 中使用 APEX/ROOT 域名是一个高难度的操作。 我用了几天的时间才琢磨出来解决方法，期间一度想要放弃。&#xA;&#xA;基本思路如下：&#xA;&#xA;域名使用 Azure 的 DNS 服务&#xA;@ 绑定 Azure resource，选择你的 CDN Endpoint&#xA;在 CDN Endpoint 中添加自定义域名，绑定 APEX&#xA;在 CDN Endpoint 中添加外部购买的自定义 SSL&#xA;&#xA;以上是思路，而不是操作。如果你按照上边步骤去执行，会发现每一步操作可能都会遇到问题。&#xA;&#xA;Endpoint 建立&#xA;&#xA;关于 Endpoint，一定要选择 S1 Standard Verizon，而不是 S3。S1 是外部的 Verizon 供应商，S3 是微软自己的。在使用中发现，S1 功能比 S3 更多，对缓存规则能做更多的控制。使用 S3 后，Mastodon 系统出现了 401 Invalid Token 的错误。切换到 S1 则无此问题。考虑到两者目前是相同价格，强烈推荐不要使用 S1。&#xA;&#xA;20897f5d30286770dbecddbc3a81c0d4.md.png]&#xA;&#xA;在 CDN 的 Caching rules 中，必须要设定 Bypass caching for query strings，否则 mastodon 无法登录。对复杂交互的动态网站的缓存还是要尽可能的少，否则很容易遇到 WebSocket 和 token 方面的问题。&#xA;&#xA;购买 SSL 时注意点&#xA;&#xA;添加自定义 SSL，首先要去买一个 Azure 支持的 SSL 证书。虽然文档里有列出来支持哪些，但是坑爹的是对方写的是一些技术参数。当你去购买 SSL 证书的时候，你无法知道证书内部的细节，比如我们欣慰的看到了列表中包含了 Godaddy 的以下证书：&#xA;&#xA;Go Daddy Root Certificate Authority - G2&#xA;Go Daddy Secure Certificate Authority - G2&#xA;&#xA;当你兴冲冲的去了 Godaddy 官网时，发现情况完全不对。几乎所有销售 SSL 的网站都不会列出来技术细节。你无法知道你选择的证书是否满足 Azure 变态的要求。&#xA;&#xA;9faebd6a895bec7931c1290d6e58e1f5.md.png]&#xA;&#xA;把证书导入到 Key vault 中&#xA;&#xA;在 Key vault - Certificates 下，选择 Generate/Import，然后你可能悲哀地发现自己下载的 SSL 证书文件竟然无法导入。因为格式不对，Azure 只支持 .Pem 和 .Pfx 格式。只好再去复习一遍 SSL 证书各种格式的区别。&#xA;&#xA;另外需要注意这里上传的证书文件，需要包含 Private Key 信息。&#xA;&#xA;我购买的 Rapid SSL 供应商签发的证书文件中有 P7B 格式，使用了这个 SSL 格式转换网站  可以把 P7B 文件 + 证书链文件 + Private Key 文件转化为一个 Pfx 文件。&#xA;&#xA;42e38a876ab92397241fbea148391da9.md.png&#xA;&#xA;成功导入以后并没有万事大吉。你发现还需要为 CDN 添加刚才的 Key Valt 访问权限 。吃惊的是，这一切竟然无法在 Azure 界面完成，你需要下载 Powershell，然后敲一堆命令行（过程也并非一帆风顺会遇到隐含的设置）。如果不去搜索并翻看相关文档，你可能永远无法成功添加一个自定义 SSL。&#xA;&#xA;我曾经想过去联系他们的客服，但是点击 Help 会引导你订购他们的 Basic Support。每月 29 刀会有 24 小时以内响应的 Email 支持。到这里我只能说 Azure 真的太高级了，设计之初就并不是给所有人使用的。&#xA;&#xA;CDN 等待时间&#xA;&#xA;当你验证 CNAME 记录时候，可能需要 30 分钟左右。当你上传并设置好 SSL 以后，部署到 CDN 最高要 30 个小时。总之，在 Azure 中进行某一操作以后，往往不会立即生效。给我隐隐的感觉就好像他们会把每一步操作拿去给领导签字一样，确认以后才放行。这还是云计算服务吗？每当页面转圈圈的时候，就非常怀念 AWS。&#xA;&#xA;截至目前，SSL 状态依然是 Deploying certificate to CDN POPs。使用云计算尤其是 Azure CDN，真的要保持好心态不能急躁。&#xA;&#xA; 部署成功 5 个小时以后更新&#xA;&#xA;本来以为成功部署了就没问题了。截至现在还是遇到 SSL 证书错误问题。Azure 并没有把我的自定义域名放到 CDN 上，目前证书还是 sni.msft.default.wpc.edgecastcdn.net 这里的。我看到了&lt;有同样的人遇到此问题  ，有的是部署成功后几小时内才成功的，有的是部署5天后还是错误。这里只能拼人品了……&#xA;&#xA; 部署成功 15 个小时以后更新&#xA;&#xA;大约昨日凌晨 4:00 am 左右提交证书，早上 10:00 ~12:00 am 点之间 Azure 后台显示部署成功。但是实际证书变得可用还得十多个小时。在晚上 8:00 pm 左右微软的 edge 浏览器开始认出来了自定义的证书，再往后到了 11:00 pm 查看的时候各浏览器中 SSL 证书已经完全正常了。&#xA;&#xA;从提交证书到正常使用，前前后后需要将近 20 个小时！我推断这 20 个小时中必然会有一些人工审批的过程，否则按照计算机系统处理速度和国际互联网传输速度，不可能在同步到个节点的过程中花费如此长的时间。微软成功的把大公司的官僚作风带入了自家的云计算中。相比 AWS，部分新注册用户或者敏感服务比如 SES 会有明确的提示，告诉你需要填表申请并且人工审核，你自己可以对完成的时间做到心里有数。Azure 则不会告诉你哪些操作有隐形的审核步骤，只会告诉你一个大概时间，但是实际需要的时间往往比他们预估时间要更久。&#xA;&#xA;这次的经历告诉我们：如果要在生产系统上部署 Azure CDN 并且使用 SSL，一定要慎重考虑如何做好过度，否则等待 SSL 生效的时候流量强行中断，老板可能已经把你炒鱿鱼了。&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="cloudflare-的问题" id="cloudflare-的问题">Cloudflare 的问题</h2>

<p>想要使用 Cloudflare 必须要修改域名的 Name Server。Cloudflare 的 DNS 系统在界面和功能都堪称业界一流，就单说 CNAME Flattening 就非常的好用，支持这个功能的 DNS Provider 也没几家。还有就是解析速度快的飞起，修改解析记录后，本地网络几乎都是秒级响应。</p>

<p>最大的问题是在于中国境内复杂的网络环境下，Cloudflare 的优势荡然无存。无论从连接的稳定性还是速度都很差，往往不如直接访问源主机更快。</p>

<p>Cloudflare 适合以下的情况使用：</p>
<ol><li>访客群体在中国大陆以外</li>
<li>网站经常经受高强度 DDos 攻击</li></ol>

<p>满足以上任意一条，Cloudflare 都是很好的选择。其他情况下几乎都不是好的选择。</p>

<h2 id="google-cloud-cdn-的问题" id="google-cloud-cdn-的问题">Google Cloud CDN 的问题</h2>

<p>Google 的 CDN 只能给自己云上的实例使用，不支持外部源。这点让自己处于二线选手。</p>

<h2 id="windows-azure" id="windows-azure">Windows Azure</h2>

<p>Windows Azure 的优势和劣势也很明显。优势是他家的 CDN 部署后，在中国的访问速度非常快；劣势就是烦人的后台操作以及感人的价格。</p>

<p>就单 Azure 的操作界面来讲，功能和布局算是合理的。后台之所以烦人，是因为几乎所有的操作都需要等待时间。当你点击了任意的按钮，右上角的 Notifications 就开始转了起来。接下来你可以去上个厕所回来再喝个咖啡，然后它可能还在转。我一点也没有夸张。</p>

<p><strong>想要在 Windows Azure CDN 中使用 APEX/ROOT 域名是一个高难度的操作。</strong> 我用了几天的时间才琢磨出来解决方法，期间一度想要放弃。</p>

<p>基本思路如下：</p>
<ol><li>域名使用 Azure 的 DNS 服务</li>
<li>@ 绑定 Azure resource，选择你的 CDN Endpoint</li>
<li>在 CDN Endpoint 中添加自定义域名，绑定 APEX</li>
<li>在 CDN Endpoint 中添加外部购买的自定义 SSL</li></ol>

<p>以上是思路，而不是操作。如果你按照上边步骤去执行，会发现每一步操作可能都会遇到问题。</p>

<h4 id="endpoint-建立" id="endpoint-建立">Endpoint 建立</h4>

<p>关于 Endpoint，一定要选择 S1 Standard Verizon，而不是 S3。S1 是外部的 Verizon 供应商，S3 是微软自己的。在使用中发现，S1 功能比 S3 更多，对缓存规则能做更多的控制。使用 S3 后，Mastodon 系统出现了 401 Invalid Token 的错误。切换到 S1 则无此问题。考虑到两者目前是相同价格，强烈推荐不要使用 S1。</p>

<p><img src="https://286.im/images/2019/07/14/20897f5d30286770dbecddbc3a81c0d4.md.png" alt="20897f5d30286770dbecddbc3a81c0d4.md.png"/>]</p>

<p>在 CDN 的 Caching rules 中，必须要设定 Bypass caching for query strings，否则 mastodon 无法登录。对复杂交互的动态网站的缓存还是要尽可能的少，否则很容易遇到 WebSocket 和 token 方面的问题。</p>

<h4 id="购买-ssl-时注意点" id="购买-ssl-时注意点">购买 SSL 时注意点</h4>

<p>添加自定义 SSL，首先要去买一个 <a href="https://docs.microsoft.com/en-us/azure/cdn/cdn-troubleshoot-allowed-ca" rel="nofollow">Azure 支持的 SSL 证书</a>。虽然文档里有列出来支持哪些，但是坑爹的是对方写的是一些技术参数。当你去购买 SSL 证书的时候，你无法知道证书内部的细节，比如我们欣慰的看到了列表中包含了 Godaddy 的以下证书：</p>
<ul><li>Go Daddy Root Certificate Authority – G2</li>
<li>Go Daddy Secure Certificate Authority – G2</li></ul>

<p>当你兴冲冲的去了 Godaddy 官网时，发现情况完全不对。几乎所有销售 SSL 的网站都不会列出来技术细节。你无法知道你选择的证书是否满足 Azure 变态的要求。</p>

<p><img src="https://286.im/images/2019/07/14/9faebd6a895bec7931c1290d6e58e1f5.md.png" alt="9faebd6a895bec7931c1290d6e58e1f5.md.png"/>]</p>

<h4 id="把证书导入到-key-vault-中" id="把证书导入到-key-vault-中">把证书导入到 Key vault 中</h4>

<p>在 Key vault – Certificates 下，选择 Generate/Import，然后你可能悲哀地发现自己下载的 SSL 证书文件竟然无法导入。因为格式不对，Azure 只支持 .Pem 和 .Pfx 格式。只好再去复习一遍 SSL 证书各种格式的区别。</p>

<p>另外需要注意这里上传的证书文件，需要包含 Private Key 信息。</p>

<p>我购买的 Rapid SSL 供应商签发的证书文件中有 P7B 格式，使用了这个 <a href="https://www.sslshopper.com/ssl-converter.html" rel="nofollow">SSL 格式转换网站</a>  可以把 P7B 文件 + 证书链文件 + Private Key 文件转化为一个 Pfx 文件。</p>

<p><img src="https://286.im/images/2019/07/14/42e38a876ab92397241fbea148391da9.md.png" alt="42e38a876ab92397241fbea148391da9.md.png"/></p>

<p>成功导入以后并没有万事大吉。你发现还需要为 CDN 添加刚才的 Key Valt 访问权限 。吃惊的是，这一切竟然无法在 Azure 界面完成，你需要下载 Powershell，然后敲一堆命令行（过程也并非一帆风顺会遇到隐含的设置）。如果不去搜索并翻看<a href="https://docs.microsoft.com/en-us/azure/cdn/cdn-custom-ssl?tabs=option-2-enable-https-with-your-own-certificate" rel="nofollow">相关文档</a>，你可能永远无法成功添加一个自定义 SSL。</p>

<p>我曾经想过去联系他们的客服，但是点击 Help 会引导你订购他们的 Basic Support。每月 29 刀会有 24 小时以内响应的 Email 支持。到这里我只能说 Azure 真的太高级了，设计之初就并不是给所有人使用的。</p>

<h4 id="cdn-等待时间" id="cdn-等待时间">CDN 等待时间</h4>

<p>当你验证 CNAME 记录时候，可能需要 30 分钟左右。当你上传并设置好 SSL 以后，部署到 CDN 最高要 30 个小时。总之，在 Azure 中进行某一操作以后，往往不会立即生效。给我隐隐的感觉就好像他们会把每一步操作拿去给领导签字一样，确认以后才放行。这还是云计算服务吗？每当页面转圈圈的时候，就非常怀念 AWS。</p>

<p>截至目前，SSL 状态依然是 Deploying certificate to CDN POPs。使用云计算尤其是 Azure CDN，真的要保持好心态不能急躁。</p>

<p>== 部署成功 5 个小时以后更新</p>

<p>本来以为成功部署了就没问题了。截至现在还是遇到 SSL 证书错误问题。Azure 并没有把我的自定义域名放到 CDN 上，目前证书还是 sni.msft.default.wpc.edgecastcdn.net 这里的。我看到了<a href="https://social.msdn.microsoft.com/Forums/en-US/03cac02f-6f5b-42b2-89df-9fd6f07d7aa5/invalid-certificate-issues?forum=azurecdn" rel="nofollow">&lt;&lt;有同样的人遇到此问题&gt;&gt;</a>，有的是部署成功后几小时内才成功的，有的是部署5天后还是错误。这里只能拼人品了……</p>

<p>== 部署成功 15 个小时以后更新</p>

<p>大约昨日凌晨 4:00 am 左右提交证书，早上 10:00 ~12:00 am 点之间 Azure 后台显示部署成功。但是实际证书变得可用还得十多个小时。在晚上 8:00 pm 左右微软的 edge 浏览器开始认出来了自定义的证书，再往后到了 11:00 pm 查看的时候各浏览器中 SSL 证书已经完全正常了。</p>

<p>从提交证书到正常使用，前前后后需要将近 20 个小时！我推断这 20 个小时中必然会有一些人工审批的过程，否则按照计算机系统处理速度和国际互联网传输速度，不可能在同步到个节点的过程中花费如此长的时间。微软成功的把大公司的官僚作风带入了自家的云计算中。相比 AWS，部分新注册用户或者敏感服务比如 SES 会有明确的提示，告诉你需要填表申请并且人工审核，你自己可以对完成的时间做到心里有数。<strong>Azure 则不会告诉你哪些操作有隐形的审核步骤</strong>，只会告诉你一个大概时间，但是实际需要的时间往往比他们预估时间要更久。</p>

<p>这次的经历告诉我们：如果要在生产系统上部署 Azure CDN 并且使用 SSL，一定要慎重考虑如何做好过度，否则等待 SSL 生效的时候流量强行中断，老板可能已经把你炒鱿鱼了。</p>
]]></content:encoded>
      <guid>https://super.writeas.com/bu-shu-azure-cdn-de-xie-lei-jing-li</guid>
      <pubDate>Sun, 14 Jul 2019 23:41:04 +0000</pubDate>
    </item>
    <item>
      <title>pghero: Query stats must be enabled for slow queries</title>
      <link>https://super.writeas.com/pghero-query-stats-must-be-enabled-for-slow-queries?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[After installation Mastodon under the official guide, I notice that PgHero keep showing this error. Here is the way to solve it. &#xA;&#xA;1. Edit postgresql.conf&#xA;&#xA;sudo vim /etc/postgresql/9.5/main/postgresql.conf&#xA;&#xA;Add the following to your postgresql.conf:&#xA;&#xA;  sharedpreloadlibraries = &#39;pgstatstatements&#39;&#xA;  pgstatstatements.track = all&#xA;  pgstatstatements.max = 10000&#xA;  trackactivityquerysize = 2048&#xA;&#xA;Then restart the PostgreSQL server: sudo systemctl restart postgresql&#xA;&#xA;2. Create extension&#xA;&#xA;sudo -u postgres psql&#xA;&#xA;postgres=# \c mastodonproduction&#xA;&#xA;mastodonproduction=# CREATE extension pgstat_statements;&#xA;&#xA;3. Refresh your PgHero Page&#xA;&#xA;All items are green!&#xA;&#xA;Reference:&#xA;https://github.com/ankane/pghero/blob/master/guides/Query-Stats.md&#xA;https://github.com/tootsuite/mastodon/issues/935&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>After installation Mastodon under the official guide, I notice that PgHero keep showing this error. Here is the way to solve it.</p>

<h2 id="1-edit-postgresql-conf" id="1-edit-postgresql-conf">1. Edit postgresql.conf</h2>

<p><code>sudo vim /etc/postgresql/9.5/main/postgresql.conf</code></p>

<p>Add the following to your postgresql.conf:</p>

<blockquote><p>shared<em>preload</em>libraries = &#39;pg<em>stat</em>statements&#39;
pg<em>stat</em>statements.track = all
pg<em>stat</em>statements.max = 10000
track<em>activity</em>query_size = 2048</p></blockquote>

<p>Then restart the PostgreSQL server: <code>sudo systemctl restart postgresql</code></p>

<h2 id="2-create-extension" id="2-create-extension">2. Create extension</h2>

<p><code>sudo -u postgres psql</code></p>

<p>postgres=# <code>\c mastodon_production</code></p>

<p>mastodon_production=# <code>CREATE extension pg_stat_statements;</code></p>

<h2 id="3-refresh-your-pghero-page" id="3-refresh-your-pghero-page">3. Refresh your PgHero Page</h2>

<p>All items are green!</p>

<h2 id="reference" id="reference">Reference:</h2>
<ul><li><a href="https://github.com/ankane/pghero/blob/master/guides/Query-Stats.md" rel="nofollow">https://github.com/ankane/pghero/blob/master/guides/Query-Stats.md</a></li>
<li><a href="https://github.com/tootsuite/mastodon/issues/935" rel="nofollow">https://github.com/tootsuite/mastodon/issues/935</a></li></ul>
]]></content:encoded>
      <guid>https://super.writeas.com/pghero-query-stats-must-be-enabled-for-slow-queries</guid>
      <pubDate>Thu, 11 Jul 2019 15:04:10 +0000</pubDate>
    </item>
    <item>
      <title>今日在 Write.as 开博，顺便讲讲自己多年来关于文章记录的心得</title>
      <link>https://super.writeas.com/new-start-in-write-as?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[独立博客已成历史&#xA;&#xA;时隔多年，我又开始写博客了。十多年前我经常在 bo-blog、WordPress 之间徘徊，后来因为某些特殊的原因，想要跟以前的自己说再见，所以把博客彻底停掉了，长期以来用的域名也丢掉了。&#xA;&#xA;其实回想当初写博客的时候，自己虽然很用心，时常更换一些 theme，添加一些插件，甚至还自己在 WordPress 发布过一款插件，但是每日访问量少的可怜，博客的评论中也大部分都是来发垃圾外链的。不禁在思考，自己使用独立博客的目的到底是什么？是否有必要花费大量精力维护一个除了自己没什么人看的博客？答案似乎是显而易见的。&#xA;&#xA;有人可能要讲，独立博客其实也没什么需要花费精力的地方啊，买域名、VPS，安装 WordPress 都是分分钟的事情，有那么麻烦吗？这个问题对于有大量空闲时间和精力的人（比如学生）来讲，确实是这样，对他们来说生活中并没有太多的其他的事项需要处理。随着年龄增长，工作繁杂以及成家立业以后，每日大脑中思考的杂项大约是学生时代的上百倍，就连吃饭睡觉这样的事情有时候都会消耗精力。维护服务器域名需要记着续费，并且服务器可能还会被黑客入侵，你要去花费时间做一些基础的防护工作，加上哪天博客忽然访问不了了还需要去诊断原因。这种需要经常“惦记着它”的微小压力，会逐渐积累直至某一天将你击溃，产生放弃独立博客的想法。对于成年人来讲，大多数是本着多一事不如少一事的想法，开始追求安逸抵制麻烦，并不会像年少时候那样喜欢折腾了。!--more--&#xA;&#xA;两种文章记录方式&#xA;&#xA;虽说放弃了独立博客，但是对于一个偶尔折腾一下的人来说，还是会有需求来记录一些技术操作或者经过整理的想法的。根据公开性质的不同，我把记录分为两类：&#xA;&#xA;给自己看的文章&#xA;如果涉及到了不适合公开的隐私类型文章，则记录在本地的日记里，这些是专门给自己看的。这类文章一般有如下诉求：&#xA;&#xA;数据本地化&#xA;因为不需要分享，所以没有必要将文章发布在公网；&#xA;&#xA;支持第三方备份并多端同步数据&#xA;能够在私有云上备份数据，比如 Dropbox 等，并且在多个设备上自动同步。谨慎使用软件自带的云端同步服务，因为你无法判断服务提供者是否会将你的内容用于大数据分析或者提供给第三者。&#xA;&#xA;私密性&#xA;最好能够加密文章数据，并且能够设定访问软件界面的密码。这涉及到两个场景：如果你的电脑硬盘被别人暴力夺取或悄悄偷走，你写的文章是否能够被读取？如果你在开机状态下离开了几分钟，潜入到电脑前的第三者是否能够读取到你的文章信息？&#xA;&#xA;纯文本编辑&#xA;因为技术取向，对于暗地里操作格式的富文本编辑器非常厌恶，所以支持 markdown 几乎是必须的。&#xA;&#xA;我考察了很多的日记软件，比如 Evernote、OneNote、SimpleNote 等各种知名或者不知名的软件（国产的一个没试过），最终发现一个终极软件：Standard Notes。推荐原因不展开说，完全满足以上 1、2、3、4。&#xA;&#xA;自己认为有传播价值同时也希望别人能看到的文章&#xA;&#xA;这就是传统的网络博客适用的场景，本想着自己再建一个 WordPress 博客，回味以前独立博客的体验真的有些担心能否坚持。并且目前市面上的博客系统重的太重，轻的太轻。重的系统有如 WordPress 之流，PHP + MySQL，代码动辄几十上百兆字节，功能繁杂无比。相比个人博客，WordPress 更适合做多栏目多分类，每日更新很多条的大中型资讯网站。轻的博客系统有各种基于 GitHub 的生成器，比如 Hexo、Jekyll。这类型系统使用起来很繁琐，传统的撰写、发布操作被复杂化，你需要先对 Git 有初步了解才可以使用，然后各种命令提交、合并、Push。与其说是在写博客，更不如说是在不停地把玩 Git 命令。在这种现状下，我认为有必要使用一种功能简约、操作简单、省心省力的博客服务，也没费太大心思就找到了，那就是 write.as。&#xA;&#xA;当使用一种免费或者付费服务时，首先要思考对方的经营模式是什么，他是否有盈利，盈利模式是否能够支持服务维持下去的开支。目前从我对 write.as 的简单观察来看，这家服务提供商成本很低，并且系统维护起来并不太复杂，或许背后是一个几人的小团队。目前的付费模式完全可能支持他们继续下去。&#xA;&#xA;以上部分是对长文章类型的总结，这些文字写作环境以 PC 端为佳。大段的文字要在大屏幕下配合键盘（最好是机械键盘）才方便撰写，有时候要旁征博引，需要在不同的网页、文件等资源切换，这个时候使用电脑来操作能够事半功倍。所以对于移动端并没有要求。&#xA;&#xA;短文或想法分享&#xA;&#xA;使用日记软件或者博客服务对于内容较多的长文章来讲很合适，但是对于一些几十字的短句、瞬间闪过的想法以及照片+配文的场景来说，是完全不适用的。这种情况下需要类似微博、微信朋友圈或 Twitter 的 timeline 模式才会产生最佳的体验。当时立即想到了使用 Twitter。使用一段时间后发现，Twitter 是一个热闹嘈杂的地方，用户多而杂，精英、小白和无脑黑都混在了一起，很难发现值得去 Follow 的账号，因此信息流中往往的都是一些自己不感兴趣的东西。还有一些国内翻墙后的愤青，无论有理无理都想要黑一把某党某国，似乎不谈这些自己就跟不上 Twitter 的潮流。自己只是想找到一个能发表闲言碎语的地方，最好能安静一些，远离那些与自己不在一个象限内的人。&#xA;&#xA;mastodon 是在我有了相关需求之后很久才出现的。因此在发现它之后我大致看了看便立刻搭建一个实例试用起来。开始的时候是被实例+网络的分布式结构吸引，听起来非常新颖，似乎有着很大的潜力值得来深究一下。试用一段时间后发现，无论在 Web 端还是 APP 端，mastodon 的体验都不输 Twitter。与 Twitter 不同的是，mastodon 是一个非常新的东西，关注并使用 mastodon 的用户，在一定程度上说明了是一个好奇心强并且内心追求新鲜事物的人，这样的人正好是我希望去了解更多的群体，在这里往往能接触到新的理念和思维。对 “mastodon” 不太满意的地方是我并不喜欢这个名字，英文角度来看字母太多打起来不方便，中文翻译又叫长毛象，听起来让人无好感。&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="独立博客已成历史">独立博客已成历史</h2>

<p>时隔多年，我又开始写博客了。十多年前我经常在 bo-blog、WordPress 之间徘徊，后来因为某些特殊的原因，想要跟以前的自己说再见，所以把博客彻底停掉了，长期以来用的域名也丢掉了。</p>

<p>其实回想当初写博客的时候，自己虽然很用心，时常更换一些 theme，添加一些插件，甚至还自己在 WordPress 发布过一款插件，但是每日访问量少的可怜，博客的评论中也大部分都是来发垃圾外链的。不禁在思考，自己使用独立博客的目的到底是什么？是否有必要花费大量精力维护一个除了自己没什么人看的博客？答案似乎是显而易见的。</p>

<p>有人可能要讲，独立博客其实也没什么需要花费精力的地方啊，买域名、VPS，安装 WordPress 都是分分钟的事情，有那么麻烦吗？这个问题对于有大量空闲时间和精力的人（比如学生）来讲，确实是这样，对他们来说生活中并没有太多的其他的事项需要处理。随着年龄增长，工作繁杂以及成家立业以后，每日大脑中思考的杂项大约是学生时代的上百倍，就连吃饭睡觉这样的事情有时候都会消耗精力。维护服务器域名需要记着续费，并且服务器可能还会被黑客入侵，你要去花费时间做一些基础的防护工作，加上哪天博客忽然访问不了了还需要去诊断原因。这种需要经常“惦记着它”的微小压力，会逐渐积累直至某一天将你击溃，产生放弃独立博客的想法。对于成年人来讲，大多数是本着多一事不如少一事的想法，开始追求安逸抵制麻烦，并不会像年少时候那样喜欢折腾了。</p>

<h2 id="两种文章记录方式">两种文章记录方式</h2>

<p>虽说放弃了独立博客，但是对于一个偶尔折腾一下的人来说，还是会有需求来记录一些技术操作或者经过整理的想法的。根据公开性质的不同，我把记录分为两类：</p>

<h3 id="给自己看的文章">给自己看的文章</h3>

<p>如果涉及到了不适合公开的隐私类型文章，则记录在本地的日记里，这些是专门给自己看的。这类文章一般有如下诉求：</p>
<ol><li><p>数据本地化
因为不需要分享，所以没有必要将文章发布在公网；</p></li>

<li><p>支持第三方备份并多端同步数据
能够在私有云上备份数据，比如 Dropbox 等，并且在多个设备上自动同步。谨慎使用软件自带的云端同步服务，因为你无法判断服务提供者是否会将你的内容用于大数据分析或者提供给第三者。</p></li>

<li><p>私密性
最好能够加密文章数据，并且能够设定访问软件界面的密码。这涉及到两个场景：如果你的电脑硬盘被别人暴力夺取或悄悄偷走，你写的文章是否能够被读取？如果你在开机状态下离开了几分钟，潜入到电脑前的第三者是否能够读取到你的文章信息？</p></li>

<li><p>纯文本编辑
因为技术取向，对于暗地里操作格式的富文本编辑器非常厌恶，所以支持 markdown 几乎是必须的。</p></li></ol>

<p>我考察了很多的日记软件，比如 Evernote、OneNote、SimpleNote 等各种知名或者不知名的软件（国产的一个没试过），<strong>最终发现一个终极软件：Standard Notes</strong>。推荐原因不展开说，完全满足以上 1、2、3、4。</p>

<h3 id="自己认为有传播价值同时也希望别人能看到的文章">自己认为有传播价值同时也希望别人能看到的文章</h3>

<p>这就是传统的网络博客适用的场景，本想着自己再建一个 WordPress 博客，回味以前独立博客的体验真的有些担心能否坚持。并且目前市面上的博客系统重的太重，轻的太轻。重的系统有如 WordPress 之流，PHP + MySQL，代码动辄几十上百兆字节，功能繁杂无比。相比个人博客，WordPress 更适合做多栏目多分类，每日更新很多条的大中型资讯网站。轻的博客系统有各种基于 GitHub 的生成器，比如 Hexo、Jekyll。这类型系统使用起来很繁琐，传统的撰写、发布操作被复杂化，你需要先对 Git 有初步了解才可以使用，然后各种命令提交、合并、Push。与其说是在写博客，更不如说是在不停地把玩 Git 命令。在这种现状下，我认为有必要使用一种<strong>功能简约、操作简单、省心省力的博客服务</strong>，也没费太大心思就找到了，那就是 write.as。</p>

<p>当使用一种免费或者付费服务时，首先要思考对方的经营模式是什么，他是否有盈利，盈利模式是否能够支持服务维持下去的开支。目前从我对 write.as 的简单观察来看，这家服务提供商成本很低，并且系统维护起来并不太复杂，或许背后是一个几人的小团队。目前的付费模式完全可能支持他们继续下去。</p>

<p>以上部分是对长文章类型的总结，这些文字写作环境以 PC 端为佳。大段的文字要在大屏幕下配合键盘（最好是机械键盘）才方便撰写，有时候要旁征博引，需要在不同的网页、文件等资源切换，这个时候使用电脑来操作能够事半功倍。所以对于移动端并没有要求。</p>

<h2 id="短文或想法分享">短文或想法分享</h2>

<p>使用日记软件或者博客服务对于内容较多的长文章来讲很合适，但是对于一些几十字的短句、瞬间闪过的想法以及照片+配文的场景来说，是完全不适用的。这种情况下需要类似微博、微信朋友圈或 Twitter 的 timeline 模式才会产生最佳的体验。当时立即想到了使用 Twitter。使用一段时间后发现，Twitter 是一个热闹嘈杂的地方，用户多而杂，精英、小白和无脑黑都混在了一起，很难发现值得去 Follow 的账号，因此信息流中往往的都是一些自己不感兴趣的东西。还有一些国内翻墙后的愤青，无论有理无理都想要黑一把某党某国，似乎不谈这些自己就跟不上 Twitter 的潮流。自己只是想找到一个能发表闲言碎语的地方，最好能安静一些，远离那些与自己不在一个象限内的人。</p>

<p>mastodon 是在我有了相关需求之后很久才出现的。因此在发现它之后我大致看了看便立刻搭建一个实例试用起来。开始的时候是被实例+网络的分布式结构吸引，听起来非常新颖，似乎有着很大的潜力值得来深究一下。试用一段时间后发现，无论在 Web 端还是 APP 端，mastodon 的体验都不输 Twitter。与 Twitter 不同的是，mastodon 是一个非常新的东西，关注并使用 mastodon 的用户，在一定程度上说明了是一个好奇心强并且内心追求新鲜事物的人，这样的人正好是我希望去了解更多的群体，在这里往往能接触到新的理念和思维。对 “mastodon” 不太满意的地方是我并不喜欢这个名字，英文角度来看字母太多打起来不方便，中文翻译又叫长毛象，听起来让人无好感。</p>
]]></content:encoded>
      <guid>https://super.writeas.com/new-start-in-write-as</guid>
      <pubDate>Wed, 10 Jul 2019 20:57:28 +0000</pubDate>
    </item>
  </channel>
</rss>