Eric Guo's blog.cloud-mes.com

Hoping writing JS, Ruby & Rails and Go article, but fallback to DevOps note

2023 年的部门小结与 2024 年的计划

Permalink

2023 年马上要结束了,一眨眼 8 个月又过去了,参照2023 年的工作小结与计划的内容,先复盘一下 8 个月前的判断:

世界线

之前不看好阿里,现在回过头看没想到阿里会那么差,连市值也被只有其人数 1/10 的拼多多超过。之前判断鸿蒙失败了,这两天看到了急召鸿蒙开发工程师年薪 160 万的新闻,咋一看好像是鸿蒙非常红火,但其实我觉得只是在炒作,首先一个新兴客户端的年薪不可能那么高,其次如果真的鸿蒙生态起来了,必然开发者数量非常多,也开不了那么高,只能说明大家的眼睛是雪亮的,几乎没啥开发者在搞鸿蒙开发。当然这个肯定是主观判断,客观的也有,跨平台的 Taro 有一个 RFC,只有标题,没有内容,和其他类似的 RFC 提案相比较,我只能说我会持续关注。

经济方面,国内的房地产业大规模熄火已经导致了行业不景气,降本增效天天念就对了,就是得注意一下发言,别像阿里一样,搞成降本增笑。

今年最最火的还是 AI,也是唯一增长的领域。

IT 技术发展预测

语言

计算机语言的隔阂几乎被 GPT 4 完全打破了,一般的算法之类的,只要贴一种语言的表达,让 GPT 4 转化成另外一种语言,几乎都是可用的。甚至直接用人类语言编程也已经不是梦想,我在工作中也已经经常使用,但是这里有个问题,就是人类语言本身还是充满歧义,所以在需要精确表达的时候,还是发现应该用计算机语言。

数据库

本来以为 MySQL 和 PostgreSQL 是平分秋色的,现在看来 PG 已经远远的超过 MySQL,因为人工智能需要向量数据库等新的数据库形式,而这个现在只有 pgvector 是相对成熟和免费的,总的来看 PG 的插件体系太强了,甚至产生了PGXN这样的扩展插件管理工具,为了人工智能,现在只选 PG 就对了。

跨平台

Java 高版本 Oracle 开始收版权费了,dotNET 6 开始就完全跨平台了,WASM 也成为了 Web 的第二运行时(第一还是 JS),跨平台已经不是一个话题了,以后也不会再提。

Web 平台

作为平台之上的平台,Web 目前还是普通应用分发的第一选择。现在普通应用和生产力应用的区分更加模糊,比如现在的轻量看图已经是一种普通应用了。

Serverless、DevOps,运维自动化

随着国内阿里和滴滴的两次史诗级故障,Serverless 被证明只是找不到 Server 去修,而不是不会出错,而且每次故障都是人为的,所以运维自动化是必须的,DevOps 现在也扩展为 DevSecOps,以强调安全。

数据平台/中台

数据集中是对的,数据库是重要的,但是数据平台或者中台可能只是个 PPT 概念而已。

人工智能

GPT 4 出道半年了,基本可以确定现在的软件架构,最上面完全可以新加一层人工智能层,这一层将包含以下功能:

  • 无法写出程序的判断任务
  • 理解用户输入的自然语言意图和心情
  • 模拟人类的思考判断并执行

如何将这些任务所需要的数据送入这层,如何判断这层运算的结果,如果提取这些结果到执行层,这些都将是未来的核心任务。

但无论如何,人工智能需求是真的大,大到了连大的数据中心也一卡难求,所以大多数人都接受了 API 调用方式,而不是通常企业软件的 self-hosting,自部署。但从长期看,随着各种人工智能加速运算卡的普及已经用了公开的所有数据,所以当以后算力或者模型都不是瓶颈以后,数据将成为唯一的区分人工智能强弱的变量。

部门完成的工作小结

部门目前维护了22 个系统,今年新做的比较大的项目是 PLM 项目管理平台,PP 人员考核,PPT 协作,还有 SD 生图。合作商平台材料文本库和 Cybros 商务智能平台也在今年改动了很多。今年还做了不少临时性的需求,比如爬取侵犯我们官网的利用我们官网数据的网站,数据留痕便于起诉等。

比对之前的计划,在 API 互通上也做了好几个案例,特别是 PLM 这边和 DDS 还有会议预定系统的互联互通,迪峰和嘉鹏的合作值得肯定。用户体验方面,今年应该是最难的一年,因为人工智能的浪潮还没有卷到用户层,所以用户现在对 UI 的界面和交互停留在了历史最高点,等明年随着大规模的人工智能能力部署,人类用户应该没那么多闲情逸致吹毛求疵 UI 了,毕竟人工智能可不会嫌软件 UI 差而不用,相反,我们开发还可以将更多的经历投入到让人工智能代替人类用户的事物上。

2024 年的计划

完成开发至少两个人工智能应用

目前肯定能完成的是智能问答,数据现成,代码可控,只要接人工智能模型即可,这个跑通以后,后续天问搜索,材料库搜索都可以用类似的技术重做。

保证系统平稳运行

随着人员和硬件投入的进一步降低,要尽量避免出现类似阿里和滴滴这样的系统崩溃案例,平时的备份和维护还是要做好

引入安全审查和漏洞检测机制

随着人员和硬件投入的进一步降低,越来越多的项目将处于长期停止开发状态,要避免泛微或者 IE 11 造成的大规模安全事件,还是要从源头抓起,找出软件内使用组件的漏洞并修补是一个很好的切入点。

强调团队合作

随着人员和硬件投入的进一步降低,越来越少的人将维护越来越多的系统,原则上要鼓励扩展已有的系统满足需求或者系统相互调用满足需求,尽量避免再开发新的系统。

Resolving macOS Ventura Failed to Install Npm Package Sharp After Brew Upgrade Vips to 8.15.0_1

Permalink

sharp is a dependency module for Next.js. However, I encountered an installation error on my MacOS Ventura, as shown below:

error /Users/guochunzhong/git/sso/changelog/node_modules/sharp: Command failed.
Exit code: 1
Command: (node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)
Arguments:
Directory: /Users/guochunzhong/git/sso/changelog/node_modules/sharp
Output:
sharp: Detected globally-installed libvips v8.15.0
sharp: Building from source via node-gyp
gyp info it worked if it ends with ok
gyp info using node-gyp@10.0.1
gyp info using node@18.18.2 | darwin | arm64
gyp info find Python using Python version 3.11.6 found at "/opt/homebrew/opt/python@3.11/bin/python3.11"
gyp info spawn /opt/homebrew/opt/python@3.11/bin/python3.11
gyp info spawn args [
gyp info spawn args '/opt/homebrew/lib/node_modules/node-gyp/gyp/gyp_main.py',
gyp info spawn args 'binding.gyp',
gyp info spawn args '-f',
gyp info spawn args 'make',
gyp info spawn args '-I',
gyp info spawn args '/Users/guochunzhong/git/sso/changelog/node_modules/sharp/build/config.gypi',
gyp info spawn args '-I',
gyp info spawn args '/opt/homebrew/lib/node_modules/node-gyp/addon.gypi',
gyp info spawn args '-I',
gyp info spawn args '/Users/guochunzhong/Library/Caches/node-gyp/18.18.2/include/node/common.gypi',
gyp info spawn args '-Dlibrary=shared_library',
gyp info spawn args '-Dvisibility=default',
gyp info spawn args '-Dnode_root_dir=/Users/guochunzhong/Library/Caches/node-gyp/18.18.2',
gyp info spawn args '-Dnode_gyp_dir=/opt/homebrew/lib/node_modules/node-gyp',
gyp info spawn args '-Dnode_lib_file=/Users/guochunzhong/Library/Caches/node-gyp/18.18.2/<(target_arch)/node.lib',
gyp info spawn args '-Dmodule_root_dir=/Users/guochunzhong/git/sso/changelog/node_modules/sharp',
gyp info spawn args '-Dnode_engine=v8',
gyp info spawn args '--depth=.',
gyp info spawn args '--no-parallel',
gyp info spawn args '--generator-output',
gyp info spawn args 'build',
gyp info spawn args '-Goutput_dir=.'
gyp info spawn args ]
Package libarchive was not found in the pkg-config search path.
Perhaps you should add the directory containing `libarchive.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libarchive', required by 'vips', not found
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
CC(target) Release/obj.target/nothing/../node-addon-api/nothing.o
LIBTOOL-STATIC Release/nothing.a
warning: /Library/Developer/CommandLineTools/usr/bin/libtool: archive library: Release/nothing.a the table of contents is empty (no object file members in the library define global symbols)
TOUCH Release/obj.target/libvips-cpp.stamp
CXX(target) Release/obj.target/sharp-darwin-arm64v8/src/common.o
../src/common.cc:13:10: fatal error: 'vips/vips8' file not found
#include <vips/vips8>
^~~~~~~~~~~~
1 error generated.
make: *** [Release/obj.target/sharp-darwin-arm64v8/src/common.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack at ChildProcess.<anonymous> (/opt/homebrew/lib/node_modules/node-gyp/lib/build.js:209:23)
gyp ERR! System Darwin 22.6.0
gyp ERR! command "/opt/homebrew/Cellar/node@18/18.18.2/bin/node" "/opt/homebrew/bin/node-gyp" "rebuild"
gyp ERR! cwd /Users/guochunzhong/git/sso/changelog/node_modules/sharp
gyp ERR! node -v v18.18.2
gyp ERR! node-gyp -v v10.0.1
gyp ERR! not ok
info Visit https://yarnpkg.com/en/docs/cli/upgrade for documentation about this command.

This issue can be resolved by executing the following command: export PKG_CONFIG_PATH=/opt/homebrew/Cellar/libarchive/3.7.2/lib/pkgconfig:/opt/homebrew/Cellar/vips/8.15.0_1/lib/pkgconfig

This solution was suggested by GPT-4!

A Open Letter Written by Parent at Students and Farmers Party

Permalink

女儿你好,

转眼你都学农了,爸爸记得小时候爸爸要到高中才学的农,可能现在的学农教育提前了吧?爸爸记得小时候,学农的时候,抬头望星空,满天的星星,周围全是蛙声,而现在爸爸也是老眼昏花看不清星空了,而现在你周边蛙声也肯定少了吧?不要误会!爸爸并不是说现在不好,只是世界真的在发生变化,我们一代代中国人也要适应变化。另外爸爸其实很羡慕你现在的时代,科学昌明,生产力发达。

爷爷在爸爸五年级的时候,肯定想不到爸爸最终会以电脑编程为职业,因为电脑进入百姓家是在1995年以后,以此类推,爸爸多半也想不到你最终会以何种技能为职业,也许是人工智能?但是人工智能以目前的观点看并不需要人类参与具体过程,只需要人类最终决定是否采纳它的建议或者结果啊,所以你们现在学习的东西未来到底有没有用,真的很令人担心啊!不要误会!爸爸并不是说你现在应该停止学习,而是想告诉你,世界变化的很快,知识更新的也很快。

无论如何,你现在可以抬头,仰望一下星空。(此处暂停5秒) 我们现在可以肯定仰望星空这个动作肯定是贯穿了整个人类历史的,一代代的人,从打猎烤火吃了这顿没下顿,到学会耕种喂饱自己,到工业革命解放自己体力,到现在信息革命释放自己的脑力。历史已经证明,仰望星空进而引发的好奇探索才有未来,过去大清那样的闭关锁国,闷头耕田,固步自封是没有出路的。不要误会!爸爸并不是建议你现在就退出学农,立刻回家,而是想告诉你,农业搞好了才能搞工业,工业搞好了才有信息产业,其实是无法跳过前面一个步骤直接进入下一个阶段的,我们中国面临的人工智能芯片断供就是中国过去20年自作聪明跳过了芯片研发生产的后果。

不要误会!信的结尾爸爸并不想和你们刚刚学过的少年中国说里那样,给只有5年纪的你提出不切实际的要求,爸爸此刻只是激励自己,好好写好这封信,这信是你妈妈手写的,爸爸电脑上手打的,没有任何人工智能的参与,爸爸猜测这在今后的人工智能时代将是一种奢侈,人工智能时代已经到来,网上你看到的垃圾将越来越多,珍惜现在学校的课程、同学和老师吧。团结起来,爸爸猜测你们共同的敌人应该是已经被开发出,而且越来越不受控制的人工智能。

祝你学农愉快,晚上尽量早点睡。

爸爸 - 过纯中

A Programmer Productivity Measure Method - Code Commit (Chinese)

Permalink

对代码递交数量进行度量的思考

评价程序员工作的度量有哪些?

程序员的工作量评估天然就困难,虽然现在程序员的工作随着各种框架的越来越成熟,越来越接近于搬砖,但是无可否认的是程序员还是一个重度思考的行业,一个优秀的程序员,肯定能够又快又好,代码又少,速度又快的完成工作,但是现实没有那么理想,作为管理者其实是很难对程序员的工作进行检查的,很多公司因此采用了粗暴的方式,只考虑程序员的上班时长,拼命加班,这显然是不好的,所以本文提出了一种对程序员工作的代码递交数量进行考核的方法,它肯定不完美,但至少也是一个方式,所以写了本文进行探讨。

基于上班时长的度量

程序员每天耕地码字,一天12个小时,996,最后不到40岁就身体不行了,提前退休。这就是近10年互联网黄金年代(2012~2022)的常态。从程序员角度看,第一批这样做的人已经财务自由了,所以这个方式显然是不错的,但是由于互联网进入了白银时代,甚至AI自动时代,所以这个方式不可持续。天天996的结果往往是开发效率的降低,一群年轻程序员上班摸鱼,看上去公司灯火通明,但是效率并没有提高。

随着程序员的总体平均年龄增大,越来越多的程序员也难以996,所以提倡上班时长作为唯一度量,会导致损失一部分优秀大龄程序员,所以急需一种补充的度量方式。

基于代码行数的度量

Bill Gates 曾经说过,按照代码行数评价软件就像按照重量评价飞机,它固然是一个指标,但是绝对不是一个好的指标。一系列的实践也表明,片面追求代码行数反而会导致开发的软件质量的下降。

基于递交数量的度量

递交数量的问题会比代码行数好一点,毕竟当你一个个递交点进去的时候,一些明显毫无意义的递交就暴露了,递交需要写递交目的,一个盲目的递交绝对是无法通过同行评审的,所以更加客观一点。开源软件的实践也表明,基于Pull Request和Merge Request的同行审议评审递交制度有利于软件的质量提高。

基于用户评价的度量

用户满意,用户是上帝是对的。但用户作为一个群体,是内在不同的,有的人腼腆,有的人没耐心,有的人还喜欢动不动就以苹果原生软件的标准要求其他没有那么多开发预算的软件。而且由于程序员开发系统的不同,实际上无法用同一批用户对各个系统分别打分,或者说如果这样的打分存在,就是变成业务价值的度量了。

基于业务价值的度量

这是我能想到的最客观评价,也是黄金时代互联网对程序员的最好回馈,很多程序员通过拿互联网公司的股票期权,几年后抛售股票期权达到了财务自由。但业务价值是需要市场评价的,而且评价的速度较为缓慢,难以作为一种短期的评价指标使用。公司内部开发软件等一系列软件并没有简单方式评估业务价值。

针对递交数量的度量的应对

所以综上,基于递交数量的评价再加上上班时长度量,笔者认为可以较为合理的评价程序员的工作量,所以接下来就针对这个评价政策,谈谈程序员如何应对。

如何拆出尽量多的度量

既然数量重要,当然要尽量拆一点出来,所幸的是,这也是也是好的开发习惯。

重构递交

在软件开发中,程序员看起来改的是代码,但是我们都知道,代码其实是一棵抽象语法树,通过函数调用让程序的执行流再一棵棵树中穿梭。所以软件开发中,调整代码的结构实际上是一种重要工作,在新加一个功能的时候,往往代码中是没有地方放这个新功能的,这时候就需要调整代码的结构,所以显然代码结构的调整,也就是重构,完全可以作为一次递交。

数据库的schema架构更改递交

应用开发本质上再操作数据库,所以任何开发工作开始前,肯定要对数据库做一定的更改,这也完全可以作为独立的递交。

实际功能的递交

实际新功能的UI,功能推荐在一起递交,但是UI的结构调整其实也可以作为独立递交,这样拆出来以后,新功能就有两次递交了。

实际功能的异常处理

新功能显然还要考虑各种边界条件,各种约束,发生各种异常的处理,这部分也能作为单独的递交。

Bug修正的递交

这部分递交要慎重,如果Bug修正的递交过多,只能说明程序员的水平较差,但是显然我们没有任何理由将这些递交放弃,修bug显然可以作为一次递交。

一些Typo和Style修正

这部分递交最好还是一次性的,reviewer的智商都是在线的,先打错几个字,几个空格,然后再修正,这种行为太low了,还是要尊重程序员彼此的智商,这类递交要完全避免。

如何避免长时间的单行递交的度量

除了刷递交,长时间的单行递交是很亏的,尤其是你工作了一周,只有一行修正递交的情况下,所以我们可以尽量讲修正这行的思路写在一个PR的message中,通过记录自己的思考过程,检查系统的数据细节罗列来体现工作量,要相信code reviewer的智商。

如何避免无法用代码递交体现的工作

一些运维工作的确无法体现在代码中,所以我们尽量要写出免运维,也就是用户不需要培训或者咨询相关人士,就能使用的软件。

常见问题

下班前需要递交吗?

尽量按照上面的原子单元方式递交,不过如果你一天都在查bug,那就写点message,如果你在探索新的API用法,就写点message,在gitlab的activity 中,这些动作一样会被记录的。

一行行的递交这个主意如何?

我个人的感觉,这个主意很差。我建议不要做傻事,也不要假定别人是傻瓜。当然如果你很擅长当傻瓜,那也许可以尝试,并将对方拖入自己的擅长领域打败他。

Install TimescaleDB on Rocky Linux 9.2 With Postgresql 15

Permalink

Largely following the official installation guide.

Disable SELinux

vi /etc/selinux/config

Disable firewall

firewall-cmd --zone=public --add-port=5432/tcp
firewall-cmd --permanent --zone=public --add-port=5432/tcp
firewall-cmd --reload
systemctl restart firewalld

Allow Remote Addresses

vi /var/lib/pgsql/15/data/postgresql.conf
listen_address = "*"

Create user and DB

sudo su - postgres
createuser mspv --pwprompt
psql
ALTER ROLE mspv LOGIN;
CREATE DATABASE mspv_db WITH ENCODING='UTF8' OWNER=mspv;
logout
vi /var/lib/pgsql/15/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
host mspv_db mspv 0.0.0.0/0 scram-sha-256

Install Open Project V13 in a New Rocky Linux 9.2

Permalink

I already install a shared open project instance half year ago, but this time I will install a dedicate OP (Open Project) server.

Disable SELinux

vi /etc/selinux/config

Install htop and atop

sudo dnf update
sudo dnf install epel-release
sudo dnf install htop
sudo dnf install atop

Install nginx

sudo dnf install nginx

Install node.js v18

Using nodesource distribution

sudo yum install https://rpm.nodesource.com/pub_18.x/nodistro/repo/nodesource-release-nodistro-1.noarch.rpm -y
curl -k https://deb.nodesource.com/gpgkey/nodesource.gpg.key -o nodesource.gpg.key
update-crypto-policies --set LEGACY
sudo rpm --import nodesource.gpg.key
sudo yum install nodejs -y
yum groupinstall 'Development Tools'

Install postgresql

Following DO manual

dnf module list postgresql
sudo dnf module enable postgresql:15
sudo dnf install postgresql-server postgresql-devel glibc-all-langpacks
sudo dnf install postgresql-contrib # pg_trgm btree_gist require by open project
sudo postgresql-setup --initdb
sudo systemctl start postgresql
sudo systemctl enable postgresql
sudo -i -u postgres
psql

Setup open_project user account

adduser open_project
cd /etc/sudoers.d/
echo "open_project ALL=(ALL) NOPASSWD:ALL" > 30-open_project-user
sudo su - open_project
mkdir .ssh
chmod 700 .ssh
vi .ssh/authorized_keys # and paste your public key
chmod 600 .ssh/authorized_keys

Install rbenv and ruby-build

whoami # should run as a open_project
git clone https://git.thape.com.cn/rails/rbenv.git .rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
~/.rbenv/bin/rbenv init # also edit ~/.bash_profile
# As an rbenv plugin
mkdir -p "$(rbenv root)"/plugins
git clone https://git.thape.com.cn/rails/ruby-build.git "$(rbenv root)"/plugins/ruby-build
git clone https://git.thape.com.cn/rails/rbenv-china-mirror.git "$(rbenv root)"/plugins/rbenv-china-mirror

Install Ruby 3.2.3

Ruby 3.2.3 need Rust to build JIT.

dnf config-manager --enable crb
dnf install libyaml-devel
yum install -y rust
rbenv install -l
rbenv install 3.2.3
rbenv global 3.2.3
rbenv shell 3.2.3
echo "gem: --no-document" > ~/.gemrc
gem update --system

Prepare the capistrano deploy folder

whoami # should run as a open_project
cd /var/www
sudo mkdir open_project
sudo chown open_project:open_project open_project/

Create postgresql db user and import DB

sudo su - postgres
createuser open_project
psql
ALTER ROLE open_project LOGIN;
CREATE DATABASE open_project_prod WITH ENCODING='UTF8' OWNER=open_project;
logout
psql -d open_project_prod -f open_project_db.sql
sudo su - open_project
psql -d open_project_prod
CREATE EXTENSION IF NOT EXISTS btree_gist;

Using mirror when deploy

Run in the release rails root folder

bundle config mirror.https://rubygems.org https://gems.ruby-china.com

Setting the open project settings

/etc/environment
OPENPROJECT_EDITION=bim
OPENPROJECT_APP__TITLE=天华项目全生命周期管理
OPENPROJECT_APP__SHORT__TITLE=PLM
OPENPROJECT_HOST__NAME=plm-staging.thape.com.cn
OPENPROJECT_EMAIL__DELIVERY__METHOD="smtp"
OPENPROJECT_SMTP__ADDRESS="smtp.thape.com.cn"
OPENPROJECT_SMTP__PORT="25"
OPENPROJECT_SMTP__DOMAIN="thape.com.cn"
OPENPROJECT_SMTP__AUTHENTICATION="login"
OPENPROJECT_SMTP__USER__NAME="plm"
OPENPROJECT_SMTP__PASSWORD=""
OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO="true"
OPENPROJECT_SMTP__OPENSSL__VERIFY__MODE="none"
OPENPROJECT_ENTERPRISE__TRIAL__CREATION__HOST="https://www.google-analytics.com"
GRUF_OP_SERVER="172.17.1.1:10009"
WX_TEMPLATE_ID=""
WX_WORK_PACKAGE_DETAIL="https://plm.thape.com.cn/work_packages/:id"
MP_QRCODE_ABS_PATH="/var/www/open_project/shared/public/static/mp_qrcode.jpg"
LOGO_ABS_PATH="/var/www/open_project/shared/public/static/logo_plm.png"
CSP_FRAME_SRC="https://ith-workspace.thape.com.cn"
CSP_CONNECT_SRC="https://analytics.thape.com.cn"
WECHAT_AUTH_JWT_SECERT=""
WECHAT_AUTH_ITH_URL="/ith/wechat/ppm/login"
/etc/systemd/system/puma_plm.service
[Unit]
Description=Puma HTTP Server for open_project (staging)
After=syslog.target network.target
[Service]
Type=simple
WatchdogSec=10
User=open_project
EnvironmentFile=/etc/environment
WorkingDirectory=/var/www/open_project/current
ExecStart=/home/open_project/.rbenv/bin/rbenv exec bundle exec puma -e production
ExecReload=/bin/kill -SIGUSR1 $MAINPID
# if we crash, restart
RestartSec=10
Restart=on-failure
StandardOutput=append:/var/www/open_project/shared/log/puma.log
StandardError=append:/var/www/open_project/shared/log/puma.log
SyslogIdentifier=puma_plm
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
bundle exec rake openproject:plugins:register_frontend
bundle exec rake i18n:js:export
bundle exec rake db:seed
sudo journalctl -u puma_plm # check system log and fix errors
sudo systemctl start puma_plm

Copy Nginx configuration and disable firewall

cp /var/www/open_project/current/config/nginx/production.conf /etc/nginx/conf.d/puma_plm.conf
systemctl restart nginx
firewall-cmd --zone=public --add-service=https
firewall-cmd --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
systemctl restart firewalld

Setup a SFTP Service in Ubuntu 20.04 Server

Permalink

Creating a New User

sudo adduser sammyfiles # using the default

Restricting Access to the home directory only

/etc/ssh/sshd_config
Match User sammyfiles
ForceCommand internal-sftp
PasswordAuthentication yes
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no

Verifying the Configuration

systemctl restart sshd
ssh sammyfiles@your_server_ip # should failed
sftp sammyfiles@your_server_ip # should success

More detail see this link

Setting up Nginx to do stream proxy

Because the SFTP server is in the internal network, only port 1027 is available on the Internet.

yum install nginx-mod-stream
firewall-cmd --list-all
firewall-cmd --add-port=1027/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all
systemctl restart filewalld

The stream block should be located with the http block side by side.

/etc/nginx/nginx.conf
stream {
upstream jtyhlinkthape_proxy {
server 172.17.1.38:22;
}
server {
listen 1027;
proxy_timeout 30s;
proxy_pass jtyhlinkthape_proxy;
}
}

Deploy Wechat Pay Site to Tianyi Cloud Ubuntu 20.04.6

Permalink

Prepare server

Create new user

adduser pp_vendor
sudo su - pp_vendor
mkdir .ssh
chmod 700 .ssh
vi .ssh/authorized_keys # and paste your public key
chmod 600 .ssh/authorized_keys

Enable new user as sudo

sudo su -
cd /etc/sudoers.d/
echo "pp_vendor ALL=(ALL) NOPASSWD:ALL" > 85-pp_vendor-user

Install Rust

sudo apt install rustc
rustc --version # here is rustc 1.66.1

Install rbenv and Ruby 3.2.2

sudo apt-get install libyaml-dev
sudo apt install rbenv
sudo su - pp_vendor
mkdir -p "$(rbenv root)"/plugins
git clone https://git.thape.com.cn/rails/ruby-build.git "$(rbenv root)"/plugins/ruby-build
git clone https://git.thape.com.cn/rails/rbenv-china-mirror.git "$(rbenv root)"/plugins/rbenv-china-mirror
rbenv install 3.2.2
rbenv global 3.2.2
echo "gem: --no-document" > ~/.gemrc
eval "$(rbenv init -)" >> ~/.bash_profile # or past the `rbenv init -`
rbenv shell 3.2.2

Install Node.js 18 and Yarn

curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install gcc g++ make
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install yarn

Do deploy

Link rbenv to make capistrano works

mkdir -p ~/.rbenv/bin
cd ~/.rbenv/bin
ln -s /usr/bin/rbenv rbenv
rbenv global 3.2.2
rbenv versions
gem update --system

create deploy folder

cd /var/www
sudo mkdir pp_vendor
sudo chown pp_vendor:pp_vendor pp_vendor/
echo "machine git.thape.com.cn login Eric-Guo password token_of_personal" >> ~/.netrc
cd ~
bundle config mirror.https://rubygems.org https://gems.ruby-china.com
sudo apt install libpq-dev

Create postgresql db user and import DB

sudo su - postgres
createuser pp_vendor
psql
ALTER ROLE pp_vendor LOGIN;
CREATE DATABASE wechat_starter WITH ENCODING='UTF8' OWNER=pp_vendor;
logout
vi /etc/postgresql/12/main/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
local wechat_starter pp_vendor peer

and restart postgresql systemctl restart postgresql

In the local machine

git clone https://github.com/Eric-Guo/wechat-starter.git
bundle exec cap production deploy

My 2023 Monthly Subscription Review List

Permalink

Like the year before here is my current subscription, the first number is RMB per month.

  1. (42) iCloud 200GB + 200GB
  2. (15) Apple Music
  3. (25) Dragonruby Pro (annual 42 USD)
  4. (38) bandwagon host (month 33 USD)
  5. (6) Adblock Pro (annual 70 RMB)
  6. (6) MarginNote 3 OCR (annual 68 RMB)
  7. (32) Rubymine (annual 53 USD)
  8. (6) blog domain (annual 10 USD)
  9. (1.5) 香哈菜谱 (annual 18 RMB)
  10. (49) AWS hosting (3 Year 206 USD, month 1.35 USD)
  11. (16.8) Meituan biking
  12. (43) Google Workspace Business Starter (month 6 USD)
  13. (7.5) Colorful Cloud weather app. (yearly 90 RMB)
  14. (115) Cursor.sh AI editor. (yearly 192 USD)
  15. (8.2) Ivory for Mastondon. (yearly 98 RMB)
  16. (8) IndieWeb.Social Backer. (monthly 1.5 SGD)

So totally 419 RMB per month have to pay, in previous year is 282 RMB, so 48% higher compare with year 2022.