Tuan Anh

container nerd. k8s || GTFO

Setting up SSL certificate with Deis

Now that Let’s Encrypt offers free SSL, there is no reason not to use it to secure your apps. Setting up Deis to use SSL is easy too.

I haven’t yet figured it out how to renew the cert automatically. Last I checked, they (Deis) doesn’t support this yet. They may be integrated into deis-router in near future.


Search airport by city name

I recently came across a case where I have an airport list (my data), city list (input data) and I have to map them.

The thing is not all the airport and city have similar name. They can be very different like Vieux Fort city and Hewanorra International Airport (UVF). I need to come up with a small service that take city name as input and output their possible nearby airports.

What I did was

  • I use Google Maps Reverse Geocoding API to find the city’s longitude and latitude and cache it. Since Google Maps has a limit of 10 requests per second and 2,500 request daily. Without caching it, my app would crash within seconds. I used redis here.

  • Since this is one time thing, I will try to use the free tier of Google Maps API if possible without having to pay. I might take a look at using proxy for removing that free tier cap.

  • I will have to find distance between that input city and all the airports. Doing this would be super slow so you would want to consider all the city in that country only.

Few things to note here:

  • redis is awesome cache solution. Since I already use redis for caching, and it can do geo proximity calculation, I wonder why not.

  • Google Maps API is not very reliable. Occasionally, you will see many dumb data which played havoc to my service. Hence I’m only using this as last resort if I can’t map using other method.


How to install Discourse without Docker

I purchased a dead cheap VPS for 5$ a month which come with 2GB of memory, 80GB disk space and quite decent CPU. The downside is they uses a very old kernel (2.6.32-042stab108.8 to be specific) while the official Discourse installation guide use Docker which require a more recent one (3.x).

Docker sure makes it easy to install Discourse but it’s the only reason that newer kernel is required. After a quick research, I found this Ansible playbook. It looks well-maintained (last commit was Dec 2015).

It doesn’t work right out of the box for me but after some debugging, I was able to install Discourse just fine. There are few things to note though.

  • On default Ubuntu installation, Apache will use port 80, making nginx fails to start. You will have to stop/uninstall Apache2 in advance (sudo apt-get remove apache2)

  • On some VPS providers, IPv6 is not enabled so you will also need to tweak nginx configuration to bind to IPv4 only.

  • If locale is not set, the script will fail as well. This command localedef -v -c -i en_US -f UTF-8 en_US.UTF-8 fixes it.

Installing plugins

discourse is the default username if you use the above playbook. Replace it if needed.

cd /var/www/discouse/plugins
# git clone the plugin you want to install
sudo /home/discourse/.rbenv/shims/bundle exec rake db:migrate /var/www/discourse RAILS_ENV=production
sudo /home/discourse/.rbenv/shims/bundle exec rake assets:precompile /var/www/discourse RAILS_ENV=production
sudo systemctl reload discourse-unicorn.service

Bonus: btw, Let’s Encrypt offers free SSL. Setting it up is really easy too.


A look back at 2015

I kicked off 2015 with lots of anxiety. I reconnect with my best friend from secondary school (then; wife now). For the first time in years, I really wanted to move back to Vietnam.

Early in 2015, I went back to Thailand after Tet holiday, start looking around for a job in Vietnam or any job that accept remote workers to smooth the transition. I found one later in May-June. They only require me to work in Thailand for awhile (1 month) so that I can get accustom with how they work there.

me and my wife

Got married to a beautiful girl who also happens to be my best friend from secondary school.

me and my wife

Bought a beautiful Pomeranian. Named her Min.

my dog

My family and me during Tet 2016.

Grow a little garden on the balcony

2015 had been good to me and perhaps my most important year of my life. I’m looking forward to 2016 with many goals in mind. The difference is now I got my wife to back me up 👫.


MariaDB Raises $9M More, Michael Howard Named New CEO, Monty Widenius CTO

Michael “Monty” Widenius, the man who originally created MySQL and MariaDB, is now joining the startup as CTO.

This is better than the funding round news.

link bài gốc

Chuyện tiền nong

ngồi lẩm nhẩm: mình đi làm mấy năm, nhìn lại thấy tài chính rối tung, tài sản thì chả có gì; cơ hội thì bỏ qua 1 đống.

thôi thì bây giờ học cũng chưa quá muộn.

tránh mang nợ

nói chung có thì xài, không có thì đừng có vay nợ để xài. xài thẻ debit cũng có nhiều cái hay lắm. hết tiền rồi mà muốn mua món gì đó thì phải ra ngân hàng deposit hoặc chuyển khoản từ ngân hàng khác sang. rất mất thời gian. cái này là vật cản lớn lắm nha.

nhiều lúc mình tính mua món gì mà ngại chuyển tiền. tính ngủ 1 giấc rồi đi mua thì lại chẳng còn hứng mua xài tiền nữa. nếu mà như vậy thì thực sự bạn không cần món đó, chỉ là muốn thôi.

lỡ mang nợ rồi!?

bây giờ lỡ mang nợ rồi thì sao? có 2 cách trả nợ:

  1. trả cái nào lãi suất cao nhất trước. cách này là economical nhất vì số tiền phải trả cuối cùng là nhỏ nhất.

  2. trả cái nào nhỏ nhất. cái này là dựa về mặt tâm lý. dứt được 1 món nợ sẽ thoải mái tinh thần hơn nhiều và tạo thêm động lực. 1 dạng reward cá nhân.

kiếm đâu ra tiền để trả nợ?

cái này cũng có 2 cách:

  1. cày nhiều hơn.

  2. xài ít hơn.

dù có chọn cách nào thì cũng phải xài tiền khôn hơn 1 chút. xài ngu thì kiếm bao nhiêu cũng không đủ. lương tháng nào xài tháng đó hoặc còn xài lố (credit card) nữa thì thua.

làm giàu

cách đơn giản và an toàn nhất là bỏ vào 1 cuốn sổ tiết kiệm. giả dụ mỗi ngày bạn bỏ ra 100 nghìn, 10 năm sau bạn có 100k * 365 * 10 = 365 triệu. 30 năm sau là thành tỉ phú rồi.

một cách khác nữa là đầu tư vào cái gì đó. cái này mình cực ngu. một là do không có vốn (vì lỡ xài ngu như ở trên rồi), hai là không nhìn thấy cơ hội.

cách khác nữa là đầu tư vào bản thân. mua sách học, đăng kí các khóa học thêm, etc..


hehe nói vầy thui chứ mình không phải chuyên gia tài chính gì đâu, các bạn đừng có tin.

nếu làm được mấy cái này mình đã giàu rồi, ko phải ngồi đây viết lảm nhảm như vầy đâu haha.


Better MySQL pagination

Consider this

SELECT * from Bookings LIMIT 5000,10

versus this

SELECT * from Bookings
INNER JOIN (Select id FROM BOOKING LIMIT 5000,10) AS result USING (id)

My Bookings table has merely 6000 records yet the first query takes approx ~10 seconds which is outrageous. Luckily, we can optimize this using late lookups like in query 2.

In the second query, we select id from Bookings and then join the original table back. This will make each individual row lookup less efficient but the total number of lookups will be reduced by a lot.

Also, if you could pass more condition into the select, it will greatly improve the performance as well. So instead of making your paging url like this example.com/products?page=10, you can use example.com/products?page=10&last_seen=1023. From that, you can pass WHERE id > 1023 into the pagination query making the whole thing a lot faster.

Those are what I used for optimizing pagination. If you know any other, please let me know.

Peace out, everybody.


Qmail

qmail is a mail transfer agent (MTA) that runs on Unix. It was written, starting December 1995, by Daniel J. Bernstein (djb) as a more secure replacement for the popular Sendmail program.

Một chút background: vào khoảng những năm 80,90 của thế kỷ trước, các máy chủ email và dns thường sử dụng Sendmail và BIND9. Tuy nhiên, 2 phần mềm này có cực kì nhiều lỗi. djb viết ra qmail và djbdns để thay thế 2 phần mềm này và tuyên bố 2 phần mềm này là “bug-free”. Hai phần mềm này được chạy trên hàng triệu tên miền và cực kì ổn định. Lỗi đầu tiên của qmail được tìm thấy sau gần 1 thập kỉ đủ để nói lên sự ổn định của nó. Có lẽ trong lịch sử chưa có một lập trình viên nào đạt đến ngưỡng này.

Daniel Julius Bernstein (sometimes known simply as djb; born October 29, 1971) is a German-American mathematician, cryptologist, programmer, and professor of mathematics and computer science at the Eindhoven University of Technology and research professor at the University of Illinois at Chicago. He is the author of the computer software programs qmail, publicfile, and djbdns.

link bài gốc

Performance at Rest

TL;DR

Benchmarking frameworks is fucking stupid.

link bài gốc

Explicit over clever

I always prefer explicit over clever, hacky hack. Explicit make the code looks clearer, more maintainable and leaning toward a more predictable behavior (aka junior developers will be less likely to mess it up).

Take an example of this code where I have a folder called providers. This here below is the content of the index.js file which basically read all the files in that folder (except index.js), require them and then module.exports that. It seems simple enough right?

var fs = require('fs');
var path = require('path');
var basename = path.basename(module.filename);
var providers = {};
var extension = '.js';

fs
    .readdirSync(__dirname)
    .filter(function(file) {
        return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === extension);
    })
    .forEach(function(file) {
        var provider = require(path.join(__dirname, file));
        var key = makeKey(file,extension)
        providers[key] = provider;
    });

/* ... */

Now, take a look at this code where I explicitly require all the files in that folder (sounds exhausting right?)

let providers = {
    Auth: require('./auth'),
    User: require('./user'),
    Health: require('./health')
}
/* ... */
module.exports = providers

Now, say if you were a newly joined member of the project, which looks less intimidating to you? I’m not saying we can’t achieve both explicit and clever at the same time; but if I need to make a choice selecting one over another, I would always go with explicit.