• My Samsung 980 Pro Also Got Issues

    Recently, I met bunch of issues related with 2TB version of Samsung 980 pro NVMe in the work place(which caused much troubles). So it reminds me I should also prepare some regular backup for my 980 PRO(though it’s a 1TB model and shouldn’t affected by the 0E Issue).

  • Won't Use OVH again


  • Migrate Grafana & Prometheus's Docker volume

    Over the past few weeks, I migrated the services that I had deployed on my Chromebook Pixel and old Celeron NUC to my newly purchased NUC 13. The only thing worth mentioning is that Docker volumes require some caution when being migrated. Hence, I have taken a brief note of the process here.

  • Exploring Stable Diffusion and ControlNet: Challenges in Precisely Generating Images

    The problem

  • Docker Swarm Practices for Lightweight Home Server Operation

    Is It Worth the Time?, xkcd 1205
    Is It Worth the Time? (source: xkcd 1205)

    Unlike people in homelab have so many fancy gears, I only have a disused laptop (Chromebook Pixel 2015 16G) and a cheap Intel NUC(NUC5CPYH) for all my in-home IT service demands (NAS, networking services, monitoring, etc.). Since I don’t want cost too much energy on operation things, I seldom do operation works for my home servers except they don’t work (But I still update them quarterly for new distributions and kernels). So for quite a long time, most of my services were managed by systemd, cronjob, or bash scripts. However, I recently started trying many new things with multiple dependencies. And I don’t want these things to penetrate my existing environments. So I wonder if the docker ecosystem may be a good solution. After some trial and errors, I feel like I generally experienced the docker toolchain (Though I wrote lots Dockerfile configures for CI/CD purposes at work, I seldom use it for service management), so I decided to write a short review about it.

    Some Dockerized Services at Home

    The followings are some services I deployed at home recently. Though they’re not fully IaC (Infrastructure as Code), the docker swarm orchestrations greatly simplified the deployment process. And, 100% IaC needs much toil to achieve. Which means doing many trial-and-error things on deployment scripts. Unless I need to deploy the same service once a week, I don’t think it is worth the toil.


    In my previous article, I wrote some details about Mastodon’s deployment using docker swarm. The whole deployment cost me about 1 day, and most of the time was spent on Nginx and Cloudflare’s configuration. Most configurations I need to start the service could be configured in docker-compose.yml(except the ulimit setting for elasticsearch). After running for several days, I transferred the /public data folder to an HDD to get more available space). And I found it relatively easy to update the service configuration while the services were managed by the docker stack.


    Nextcloud is an useful tool for data management and transfer. I use snap to deploy it previously. After I deployed many services with docker swarm, I planned to migrate the Nextcloud service to docker too. Though the snap works out-of-the-box, the ecosystem seems not rich as docker. And the most important reason is I don’t want to maintain services with two different tools while the commands of these tools are not so intuitively.

    Nextcloud gives many different docker configurations in their repo. I chose the one that I feel most comfortable with to start (postgresql + PHP fpm). The deployment process is pretty smooth, but somehow I reassigned the postgresql’s user privileges manually after setting up the admin account because the account creation scripts in Nextcloud seems didn’t correctly alter the tables privileges after the creation of the admin account:

    PDOException: SQLSTATE[42501]: Insufficient privilege: 7 ERROR:  permission denied for table oc_appconfig in /var/www/html/3rdparty/doctrine/dbal/src/Driver/PDO/Connection.php:82
    Stack trace:
    #0 /var/www/html/3rdparty/doctrine/dbal/src/Driver/PDO/Connection.php(82): PDO->query('SELECT * FROM "...')
    #1 /var/www/html/3rdparty/doctrine/dbal/src/Connection.php(1062): Doctrine\DBAL\Driver\PDO\Connection->query('SELECT * FROM "...')

    Though I have an existing Nextcloud deployment via snap, the migration process is complex. Snap just copy all folders in the package with its backup tools. It’s not easy to restore with other tools. And snap use MySQL by default. I also need to do database migration if I want to keep the old configuration, which seems more complex and error-prone. So instead of migration, I made a new deployment.


    Last month I planned to use prometheus+Grafana stack to replace Munin for my network status monitor purpose. And there is a well-maintained docker-compose repo for the deployment. This’s the first service I deployed with the docker stack. However, the services running smoothly after a month (afterward, I found that the default data expiration time is 30 days).


    After I deployed these services with docker swarm, I felt I had some views to write down: What is the benefit from the stack, and what issues do we need to pay attention to. So I summarized them as follows.


    • Easily extend your operation capacity at home. Docker’s ecosystem is rich, so most of the services I could reach have docker images. It’s essential for services that have multiple or the same dependencies. I could wipe the whole thing easily if I made a mass. It’s necessary for the tech stack, which I am unfamiliar with.
    • Convenient to make command into service. I could run a single command and turn the container into a service with docker update --restart always <container-name> then review them with docker ps. It’s much more convenient than systemd, especially when I need to change the services now and then.
    • Works out of the box (mostly). The deployment from the compose files works out of the box and is reproducible, especially in well-maintained repos. Most of the toil is to fine-tune some configurations I need to customize.
    • Transparency: with the commands like docker service logs, docker logs or docker exec -it <container> /bin/sh, it’s easy to obtain logs from the system or debug on the containers. After understanding the basic concepts of the docker swarm, the debugging experience is almost close to debug in the local environment.
    • Convenient for experiments: I could set up the network environment easily in the docker compose file. So testing some distributed services are convenient than before. Though I could achieve this by using VM management tools like Vagrant, the docker container is a more resource-saving solution. And the network definition in the docker compose file is easier.


    • Automation, but not that automatic. While using docker swarm on multiple nodes (physical machines), I found that the network between containers could work smoothly (If the firewall on nodes was properly set). But obviously, the data volume can’t achieve this. If there are some persistent data, it always needs extra effort to make things work. From the docker data volume documents, they say:

      If you bind mount a host path into your service’s containers, the path must exist on every swarm node. The Docker swarm mode scheduler can schedule containers on any machine that meets resource availability requirements and satisfies all constraints and placement preferences you specify.

      In my situation, when a service starts, the node manager tries several times to boot the container on the machine that doesn’t have a specific data path:

        anzwltkogbgaeltn8qvb436yw   nextcloud_app.1        nextcloud:fpm-alpine@sha256:c88a48b8b32f42a0146c45d1817e64124ab0b23976797ea339d46e4cf56cc859   piksel                  Running         Running 2 days ago
        xfn21y22k5jvajqc9ish078m5    \_ nextcloud_app.1    nextcloud:fpm-alpine@sha256:c88a48b8b32f42a0146c45d1817e64124ab0b23976797ea339d46e4cf56cc859   localhost.localdomain   Shutdown        Rejected 2 days ago   "invalid mount config for type "bind": bind source path does not exist: /mnt/data/nextcloud/nextcloud"
        isiqams6kmic5nzakbo18n6qn    \_ nextcloud_app.1    nextcloud:fpm-alpine@sha256:c88a48b8b32f42a0146c45d1817e64124ab0b23976797ea339d46e4cf56cc859   localhost.localdomain   Shutdown        Rejected 2 days ago   "invalid mount config for type "bind": bind source path does not exist: /mnt/data/nextcloud/nextcloud"
    • Some node(host) specified network configurations are not easy to eliminate. For example, if you want to attach docker containers on your local network using macvlan, it may be complicated on docker swarm. So I only configured several services that booted by the docker run command to use this feature.
    • Top level named volume can’t have a certain path. When I started to configure the data volume in compose file, I thought top level named volume like this could have a specific path. But I’m wrong, it’s not works like a variable name in a template. The docker will generate a named volume on the node like this:

        $  docker volume ls
        local     prom_grafana_data
        local     prom_prometheus_data

      So it’s impossible to make docker swarm run this:

                mountpoint: /data/path/to/db

      You can only achieve this with the plugin that make a new driver:

                driver: local-persist
                mountpoint: /data/path/to/db

      Therefore, instead of named volume, I specify bind mount everywhere I need to configure a data path because my home directory on Chromebook isn’t enough, so I need to make data write on the HDD.

    • Needs to remember some commands. Unless you work with docker swarm daily, it’s easy to forget many deploying or debugging commands. Unlike Linux commands I use daily, these commands are less intuitive (but still better than snap and Kubernetes). I took notes of some commonly used command combinations just in case.


    The docker swarm is a nice orchestrator for home IT applications. It has good maintainability, portability, and observability. And keep the orchestration file relatively simple at the same time. I didn’t find an equivalent at the moment. If you know some alternatives, please tell me, and I’m willing to have a try.


  • Deployed a Mastodon Instance at Home

    P.S: My Mastodon account: @nyanshell@mastodon.nyanshell.com

  • A Week in Music-Making Part 2

    This memo is part 2 of my last week’s music-making learning.

  • A Week in Music-Making Part 1: A Glance of Voice Synthesizer

    In the previous week, I got some time to learn some music-making things. Last week, my original intention was to test some voice synthesizers, but many ideas were generated after I tried Synthesizer V. So I started to learn more about my DAW(Digital audio workstation, I am using Abelton Live 11 Lite), which was only used to record my Strat’s sound before.

  • Assembly of a Fender American Deluxe-Like Stratocaster


  • Install Emacs & Emacs-rime on WSL 1 (OpenSUSE 15.3)

    Setup VcXsrv as X11 Environment

  • A Strong Pale Ale with Dual Yeasts

    Finally, I just brewed another batch of ale after two years. I made this batch around May 2021. Due to some procrastination, I didn’t write it down until now.


    • Yeast
    • Malt
      • Thomas Fawcett Maris Otter Pale Ale 2kg
      • 2-Row Pale Ale Malt 2.5kg
    • Hops
      • Amarillo, 13g
      • Galaxy, 6g
    • Water 10L


    Brew day Checklist

    • Wash the bucket & pot, equipment
    • Wash the kitchen sink
    • Prepare sanitizer
    • Crush malt
    • Pour malt into the bucket
    • Boil water to 80℃
    • Pour water into the bucket
    • Mashing 1h
    • Keep water in 65-68℃
    • Mashing time: 1h
    • Boiling 1h
    • Take sample & measure SG
    • Cool down, around 3 hours
    • Melt yeast & add yeast

    Crushing the Malt (0504)

    I intended to crushed the malt on this day. However, I spent over 1 hour on finding bolt for the lever stick of the malt crusher. Because I don’t use it for a while, I can’t find it anywhere. I tried use electric screw driver instead, unfortunately, the power isn’t enough. Finally I found a proper bolt in my skateboard’s spare parts.

    But I also feel hard to turn the grinder and spent ten minutes to crush 4.5kg malts.

    Mashing & Boiling (0505)


    • T+0, added 5L water into crushed malt, 69°C after added.
    • T+20min, 69°C.
    • T+30min, 63.2°C.
    • T+40min, add another 5L water, 69°C(surface) after added, 63°C on bottom of the bucket.
    • T+70min,60°C-64°C, stop mashing.


    • 16:30, start boiling the wort.
    • 16:50, boiling.
    • 16:58, hot break.
    • 17:01, first hopping, added Amarillo hops.
    • 17:20, second hopping, added Galaxy hops.
    • 17:33, stop heating.

    Start Gravity: BRIX: >25, gravity: >1.1057 (refractometer’s range exceeded).

    Adding yeast (0506)

    Environment temperature: 25.1°C, humidity: 67.9%.

    Because I didn’t have any device to cool down the wort instantly, I kept wort in the sealed pot overnight and added yeast the next morning. I chose two high alcohol tolerance yeast in this batch. Because room temperature isn’t in LALBREW CBC-1’s primary fermentation range (20°C), I added one pack of LALVIN ICV-D47 to raise the ABV. However, both were not in the ideal fermentation temperature while using.

    Fermentation (0507-0529)

    Environment temperature: 26.3°C, humidity: 63.2%.

    Compared with the previous batch, fermentation was not fierce on the first two days. Even though the airlock keeps bubbling during the two weeks.

    Bottling (0529)

    Ordinary sanitizing and bottling process. I bought half a dozen 300ml Heineken lager beer to reuse its bottle. However, when I started capping, I found this kind of bottle couldn’t be recapped with the hand capper. The raised part of the bottleneck is too thin for the hand capper. Wondering I didn’t notice it before. Luckily, I have enough Chimay and Delirium bottles.

    Bottling day gravity BRIX: 14.5, gravity: 1.0590, ABV 6.13%.

    Taste & Conclusion

    I opened up a bottle after two weeks, its tastes just like the previous batch in two years but more a strong yeast flavor. The ABV is enough, with a slight sweetness from maltose and a little thickness. However, the secondary fermentation was not succeeded. The beer totally didn’t get carbonated. There is still no foam in the bottle after two months of aging.

    Taste after half-year: The body seems to become more strong and drier. The BRIX in the last bottle is 13.6, slightly higher than fresh bottled.

    Maybe next time, I need to start brewing at a proper room temperature. According to the last few trials, a fierce fermentation in the first 1-2 days always got carbonated results.


  • Yet Another Cinnamon Mead

    After a long time halt, I made another cinnamon mead again. It is pretty simple to make. At last time, I tried to make the Nord mead from The Elder Scrolls Official Cookbook. But I have garbled cassia with cinnamon, so I made without it. However, it’s a determinative flavor. You can’t say it’s a Nord mead without cinnamon. So this time, I bought a pack of cinnamon powder to ensure the flavor.


    • Yeast: LALVIN ICV-D47
    • Honey: 1kg
    • Water: NongFu Spring nature water 5L
    • Spices: Cinnamon powder
    • Sanitizer: StarSan Sanitizer


    1. Sanitize the instruments, including airlock, containers, bucket, stopper.
    2. Remove 1.5kg water from the bucket for the room of fermentation and honey.
    3. Add 500g water into a small pot, boiling, add 50g cinnamon powder, keep boiling for 5 minutes. Then cool down a little while and add to the bucket.
    4. Add honey to the rest of the water. Shake well to make sure the honey and the water are well mixed.
    5. Measuring OG (But I forgot it).
    6. Add yeast. Dissolve 10g yeast with 30-50ml water in a sanitized cup. Dissolve the yeast at first is very important. When I skipped at first, the mixture didn’t start the fermentation after 24 hours. So I used another 10g yeast to ensure the success of the fermentation.
    7. Add the airlock to the bucket, and ferment the mixture for 14 days.


    After around 14 days of fermentation, transfer the mixture to the sanitized glass bottle, store them in the fridge. And at the end of the fermentation, there were around 1/6 protein and cinnamon precipitation in the bucket. I chose not to add them to the bottles. Then store the bottles 2 weeks more to ensure stability.


    I forgot to measure the OG before starting the fermentation, so I just estimate the alcohol with the FG and the standard OG of a mead. Maybe the ABV is around 10%-14%. And I’m pretty sure it’s stronger than before. The completed liquid smells rich in floral, honey, and cinnamon. It tastes a little intense and seldom sweet. And also a strong yeast flavor in the aftertaste. Absolutely it’s a mead.



    I’ll try the 10L bucket next time. And put some Irish moss I bought last year to decrease the yeast precipitation in the liquid. Maybe some spicy flavor like ginger can also help to increase the taste.

  • Nord Mead 試作

    這次根據之前訂購的Elder Scrolls: The Official Cookbook上的配方準備嘗試一下 Nord Mead,然而最後的成品因為沒有掌握好調料的比例,感覺並沒有喝出來蜂蜜和酵母之外的味道。


    • 酵母:M05 MEAD YEAST 10g
    • 蜂蜜: DNZ Multiflora Honey 1kg
    • 水:桶装农夫山泉 5L
    • 香料:小豆蔻(cardamom)、姜丝、丁香、陈皮、肉桂。
    • 消毒劑:StarSan Sanitizer



    將香料放入鍋中煮水冷卻待用。因為氣溫原因,蜂蜜是結晶狀態的(稍微在烤箱裡加熱了一下並沒有明顯變化)。所以消毒了一個量杯用於攪拌蜂蜜(塊狀的蜂蜜難以放入桶中)。然而開始倒出的用於煮香料的水略少。放入 1kg 蜂蜜後桶基本就快滿了,這也是最後感覺不到香料味的原因之一。之後活化酵母加入桶中即可,這次酵母加入後很快就開始劇烈發酵。為了防止之前瓶塞被氣體頂出來的問題,這次外面還綁了一層塑料袋。


    再次買了半打 IKEA 的 1L 帶塞瓶子用於灌裝。沿用上次的經驗,配製好消毒液之後一個個瓶子消毒,然後放到烤箱裡面烘乾,需要注意的是不要溫度過高把橡膠塞烤壞。






    • 配方上沒有明確說明放多少,隨便用500ml水煮了一些香料(各种约10g),尝了一下水感觉小豆蔻的辣味很明显。結果投放到桶裡之後却沒有什麼味道。
    • 開始把肉桂(cinnamon)和桂皮(cassia)搞混了,後來準備投放的時候特地看了一下這類介紹,發現不是一個東西,所以乾脆沒放,結果少了一種決定性的味道。
    • 因為開始發酵時桶裝得太滿,不方便採樣,因此沒有測量比重。
    • 二次發酵不足(也可能是因為 IKEA 的橡膠塞瓶子密封性不夠),導致開瓶時基本沒氣,影響口感。



  • 復現 Kamoniwannaleiyah American Barleywine

    復現 Kamoniwannaleiyah American Barleywine

    在一年之前買的 How To Brew 的第二版上看到了這個配方,本來在去年十一月的時候購置了材料準備按照書中的配料和方法製作這款高酒度 ale ,但是因為各種原因一直到 2019 年一月纔開始製作。相比之前,這次在出糖上花費了更多的工夫,並購置了一些能夠一次處理完 10 升麥芽汁的容器。



    • Warrior 50g
    • Amarillo 25g
    • Galaxy 25g


    • M42 New Word Strong Ale (10g)

    Malt & Malt Extract

    • Pale Ale Malt 4kg
    • Special B 250g
    • MunichⅡ 250g
    • CBW Bavarian Wheat DME 5756 500g

    农夫山泉 5kg * 2



    Brew Day(2019/01/13)


    原本開始製作的日期是兩週之前,但是使用之前的咖啡磨豆機處理麥芽時,到了還剩五分之一的時候磨豆機過熱燒毀了,所以只好暫停並下單了一台 Kegco KM7GM-2R 麥芽破碎機。這台磨組裝起來之後5分鐘就將剩餘的麥芽全部處理完成了。


    • 初始水溫: 79°C
    • 目標溫度: 65°C

    考慮到一共有 4.5 千克的麥芽和 10 千克的水,所以提前買了一個直徑 25cm 高 40cm (容量约 17 升)的不銹鋼桶用於出糖。出糖時將鍋放置在廚房水槽中,將水槽加滿 70°C 左右的水,並使用低溫烹飪設備保持水溫。基本保持了水溫的恆定。


    開始的設想是將用於出糖不銹鋼鍋套上一個濾網直接倒入煮沸麥芽汁的深鍋中去。但實際上實在難以平穩操作一個 15 公斤的圓柱體。只好分批次倒入小鍋進行過濾。考慮下次使用一個流量高一點的移液泵進行過濾麥芽汁的操作。


    為了一次將麥芽汁處理完成,這次特地買了 IKEA 10L 的深鍋。在煮沸後立即將麥芽提取物(類似麥芽糖)加入鍋中。原本認為麥芽提取物應當是粉狀物質,但是加入後發現這是一個難以切分的硬塊,直到半個小時後纔融化殆盡。出現明顯的蛋白質休止(protein rest)後加入啤酒花,持續煮沸約 10 分鐘後關火。







    因為採取了一些保溫措施,發酵時房間溫度基本在 18°C 左右。


    使用上次配製的消毒液對瓶子進行消毒。這次使用了烤箱將消毒後的瓶子烘乾,十分方便,很快就完成了消毒。但是在處理瓶蓋的時候由於一部分的瓶蓋是朝上的,一部分瓶蓋的橡膠片被烤變形了。排除大部分發酵的絮狀物沉澱,一共裝滿了 13 瓶(有三瓶含有三分之一以上的絮狀物)。




    • 初始比重(Origin Gravity):>= 1.093
    • 装瓶前比重:1.0759
    • 結束比重(Final Gravity):1.0746(2019/04/14)


    update 2019/04/14:裝瓶後過了兩個多月喝起來還是有點甜,二氧化碳含量也比較少。口感上類似於最近喝到的一種高酒度的啤酒 ATLAS。從指標上來看二次發酵程度也遠遠沒有達標(這款酒的結束比重預期是 1.028 左右)。不知道是後來室溫過高減緩了二次發酵的速度還是本身酵母的活化程度的問題,也許以後可以嘗試一下其他種類的酵母。不過這個溫度下還是考慮試製一下能夠在冰箱裡發酵的 lager 吧。

    • 更自動化的麥芽汁過濾方法。
    • 比重較高的麥芽汁煮沸後絮狀物較多影響口感,下次嘗試使用愛爾蘭苔蘚/卡拉膠之類的澄清劑;
    • 考慮購置量程更大的折光儀。
    • 苦度過高,下次減少啤酒花的煮沸時間。
  • Install tensorflow-rocm

    Hardware Environment

    Software Environment

    • Ubuntu 16.04.5
    • Kernel: 4.15.0-39-generic

    Procedure & Notice

    • Follow ROCM & tensorflow-rocm install instruction. Ubuntu 16.04 LTS come with kernel 4.4.x, need to switch to proper kernel version. tensorflow-rocm has extra dependencies other than rocm-dkms.
    • If abnormal information shown in dmesg -T | grep kfd, HWE may needed, in this case, linux-hwe-tools-4.15.0-39 & linux-modules-extra-4.15.0-39-generic were needed.
    • Issues like hsa api call failure at line 900, file: /home/jenkins/jenkins-root/workspace/compute-rocm-rel-1.8/rocminfo/rocminfo.cc. Call returned 4104 may caused by various reasons, caution on dmesg output & rocm-dkms build log.

    After Successful Installation

    $ /opt/rocm/bin/rocm-smi
    ====================    ROCm System Management Interface    ====================
     GPU  Temp    AvgPwr   SCLK     MCLK     Fan      Perf    SCLK OD    MCLK OD
      0   42c     115.217W 1380Mhz  1000Mhz  29.8%    auto      0%         0%
    ====================           End of ROCm SMI Log          ====================
    $ sudo dkms status
    amdgpu, 1.9-307, 4.15.0-39-generic, x86_64: installed
    (venv) $ pip freeze | grep -i rocm
    (venv) $ python
    Python 3.6.7 (default, Nov 25 2018, 01:02:31)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import tensorflow as tf
    WARNING:tensorflow:From /home/marisa/venv/lib/python3.6/site-packages/tensorflow/python/ops/distributions/distribution.py:265: ReparameterizationType.__init__ (from tensorflow.python.ops.distributions.distribution) is deprecated and will be removed after 2019-01-01.
    Instructions for updating:
    The TensorFlow Distributions library has moved to TensorFlow Probability (https://github.com/tensorflow/probability). You should update all references to use `tfp.distributions` instead of `tf.distributions`.
    WARNING:tensorflow:From /home/marisa/venv/lib/python3.6/site-packages/tensorflow/python/ops/distributions/bernoulli.py:169: RegisterKL.__init__ (from tensorflow.python.ops.distributions.kullback_leibler) is deprecated and will be removed after 2019-01-01.
    Instructions for updating:
    The TensorFlow Distributions library has moved to TensorFlow Probability (https://github.com/tensorflow/probability). You should update all references to use `tfp.distributions` instead of `tf.distributions`.
  • Tips for install archlinux with LVM & XFS

    Just follow the archwiki install guidelines with few notices:

    Otherwise you will meet a boot error like this:

    mount: mount(2) failed: /new_root: No such file or directory
    You are no being dropped into an emergency shell
    sh: can't access tty; job control turned off
  • Mead

    11月中旬本來想使用一些放置時間比較久的酵母來製作工序相對簡單的蜂蜜酒(mead),但是查閱了一些配方後發現需要使用大量的蜂蜜,感覺如果發酵不成功的話有些浪費。另外製作蜂蜜酒和果酒、葡萄酒使用的酵母一般也是產生泡沫較少的品種,因此剩餘的 Safbrew T-58 並不適合用來製作蜂蜜酒。做了一些搜索之後,決定使用據稱泡沫產生較少且酒精耐受度較高的 Lalvin EC-1118 酵母。








    可能是因爲沒有在玻璃容器中長時間放置(aging)的原因,酵母味還很重(加之瓶底的酵母稍微搖晃很容易上浮)。不過甜味倒是幾乎沒有了。密封的容器積累了一些二氧化碳,稍微增加了一點氣泡酒的感覺。總之 mead 相比啤酒來說,制作方法簡單了許多,也比較容易做出穩定的成品。下次準備買一個20L的玻璃罐並提高蜂蜜的比例,看看口感會不會好一些。


    純淨水 4L x 2(桶裝農夫山泉)

    蜂蜜 450ml x 3

    酵母 5g(Lalvin EC-1118)



    Bucket #0 1.052

    Bucket #1 1.05






  • 製作啤酒,其之二


  • Regenerate initramfs in CentOS 7

    If you change motherboard you may meet a boot issue like /dev/centos/root does not exist. Just follow the tips in CentOS wiki to rebuild initramfs and the issue should be resolved.

  • LVM Create Snapshot

    $ lvcreate --size 900G --snapshot --name mdb-snap01 /dev/mapper/vg-data
    $ mount /dev/vg/mdb-snap01 /mnt/backup/ -onouuid,ro
    # backup things
    $ umount /mnt/backup
    $ lvremove /dev/vg/mdb-snap01
  • Host Jekyll Site with Nginx


    • Firewall port
    • SELinux
    • Force SSL(ssl on configure) should be off at first
  • Migrated to Jekyll

    Editing blog templates on Blogger just feel like what I am did ten years ago. Now it’s year 2017, use something contemporary.

  • Configuring L2TP/IPsec VPN on Debian 9 (stretch)

    Waste few hours to configure L2TP VPN on Debian. To reduce Googling time when I need to do it again.

  • 製作啤酒,其之一


  • Python 3.2 convert raw string to string

    It's a stupid way but I don't found any possible method currently:
    u = r"\u9038"
  • a method to unbrick HTC ONE S S3( villec2 ) with third party recovery & rom flashed

    After waste two days, finally got villec2 restore.
    This method is for those who bricked HTC ONE S S3( villec2 ) with third party recovery & rom(like twrp & CM ) flashed:

    1. find your IMG recovery( like PJ40IMG_VILLEC2_U_ICS_40_HTCCN_CHS_1.11.1400.140_Radio_16.17.20.02U_16.07.20.18_M_release_279226_signed.zip , not OTA ) and CID must equal to your device's CID,( IMG's CID in android-info.txt and you could find yours in fastboot oem readcid );
    2. rename it like PJ40IMG.zip(first segment in *.zip )
    3. unzip boot_signed.img & recovery_signed.img in *.zip , flash them use fastboot( fastboot flash recovery recovery_signed.img & fastboot flash boot boot_signed.img ), and erase cache;
    4. make sure your device was relocked;
    5. reboot to RUU( use fastboot oem rebootRUU );
    6. fastboot flash zip <Your_zip_file_name>.zip
    7. after flash was done ,reboot device
    8. now your device may unbricked.

    ps: It seems that villec2 sell in China have 4 buttons( 3 in other country? ), it maybe a possible reason that many official OTA / nonofficial ROMs doesn't support this device.