Who needs all those paid certificate providers while we have such a brilliant project as Letsencrypt? It allows a domain owner to obtain a valid certificate for his domain in a matter of seconds without the boring stuff like generating CSR, making DNS verification records or even passing documents to the certificate issuer center. However, paid certificates most often have an expiration time of a year. And free Letsencrypt certificates live only for a couple of months. But it's definitely not a huge problem if there is a way to automate the renewal process. And there it is.

The 2017 year was good for me. It's the second year in a line where I fulfilled all my new year resolutions, which is inspiring. That's why I decided to write a bit about it. The year totally earned it :)

The wedding

The Wedding

I'm a married man now. I have such a beautiful wife! (and still can't fully believe that). But I don't see any changes inside me: I think I married her in my mind long before that, but it's great to have a real ceremony and to eat a real cake! :) The day before the wedding I fell from my bike and got a severe knee injury. I'll never forget dancing the waltz all in bandages like a mummy, with terrible pain and only one leg working fine, but it was worth all the efforts.


This year was great for trips too.


I was in Prague, meeting my new colleagues and drinking an enormous amount of Czech beer with them. Night Prague view from the high point was stunningly beautiful, but meeting such great people alive was far much an incredible experience.


I visited the USA the second time; we made a colossal car journey with my wife and good friends through a variety of national parks and forests. Nature was fantastic and very mind refreshing. Never thought I would see my wallpaper view with my own eyes :) Americans did a great job preserving all these great riches from destruction. Also visited my dear friends Vasily and Emily in their new home in Colorado. Keep prospering, guys! (and visit us in Moscow one day!)


We made a winter trip to Italy, riding Segways all around the Rome, eating pizza and walking along the picturesque Tiber river. We made a one day raid to Napoli, visiting Pompei.



Despite the knee injury in August, I reached my sports goal: 10 squats with 150 kg barbell on my shoulders, precisely at the final training of the year. I need to set a new goal asap :) do you have any ideas?

Work and home

Home Office

In February we moved into a new shiny apartment. It's such a fantastic thing to have more than one room in a flat. I finally was able to make a home office from the smaller room, where I can work without any distractions on my projects. It's also the first year I'm working as individual entrepreneur and entirely remote.

Books were hard to get at a time when I was a kid. They were expensive and, moreover, there was a complete lack of them. Many people owned no books at all, and some other copied them manually (by hand). But there always were a lot of books in our family, and it was shocking to me back then — to see no books at all in a room.

Not all of the books from our family collection were good. Most of them were pretty cheap detectives and other silly novels from barely known authors. The only thing they were good at is the creation of the warm relationships between me and the book species. But among this mess, there were a lot of hidden treasures.

Once I spotted that my father left the book he was reading at that time, on the table. I, for some reasons, thought that I'm not allowed to read or even touch adult books as I was a nothing but the little child. No one was near, and I dared to take it and read it, secretly. It was «Lord Valentine's Castle» by Robert Silverberg.

To my astonishment, it was not too different by its nature from what I've read before. It was way better than all these child books, so I fell in love with it from the first pages. I was reading this book secretly for a long time as I wasn't alone most of the times and not every day I was even aware of the location of this book.

I think that at some point my secret love affair with this book was spotted by my father. He said nothing about it, so I'm not sure if that was the trigger. But sometime after that, he offered me another book from his collection of science fiction to read. It was the «Deathworld» by Harry Harrison.

From that time I created a personal ritual for reading. Every evening, I take a fruit or two, go to bed, take a book and read it for an hour or two. That was the time I first met Heinlein, Simak, Asimov, Zelazny, Sheckley and other cool guys I owe so much for my very own personality, consciousness and the way I see the world now.

Managing the state of an application with libraries like `redux` is awesome. It provides a really easy way to write simple and testable code for state transitions. You only need to decide on a structure of the desired state and write a corresponding pure function.

There is no doubt that a reducer could look super simple in the cases like the following one:

Our main task as developers is to keep all reducers as simple as possible. Simple reducer is easily understandable and it's not a big deal to write a couple of helpful tests for it. But the state grows bigger and becomes more and more complex as we add more cool features to our apps. We need a technique to hide this complexity somewhere.

Every reducer is just a common pure function. No magic at all. Therefore it's possible to write such a reducer function which will take a set of other reducers on its input to produce their results in a combination of some sort. Let's look at a few examples:

Combine a set of reducers into a map of properties

Let's assume that our app needs two different counters at the same time. It would be great to code something like that (with magic `combineReducers` function):

And it's exactly what is possible with the standard `combineReducers` function from `redux` library. But be aware that as we use the same `counter` reducer for counter1 and counter2, they react the same way and counter's values will be the same too.

Combine a set of reducers into an indexed storage

Let's imagine that we want a couple of such state structures. We must add an `id` parameter into the action to be able to determine which one of the states we want to change.

Let the power of pure functions be with you.

Letsencrypt is an excellent service for obtaining totally free security encryption certificates. Fortunately, it also has a marvelous client named Certbot. Let's install it.

Install Certbot

In the most recent versions of Ubuntu (16.04 and newer), it's possible to install Certbot automatically using native operating system repositories. It's preferable: you'll get a global executable and a package update management out of a box. Just type the following command, and you're in business:

$ apt-get install certbot

If it's not an option for any reason, you can always check out the Github repository manually. In that case, you should choose an installation directory and create a global symlink by yourself.

$ git clone https://github.com/certbot/certbot

Generate certificates manually

To generate a certificate we need to confirm that we have control over the domain. The standard practice is to launch a Letsencrypt process on ports 80 or 443. As we can't start anything on the Cloudfront distribution or s3 servers itself, we need to use a manual validation. Let's assume that our app is running on the my-awesome-cloudfront-app.com address. Run the following command:

$ certbot-auto certonly --manual -d my-awesome-cloudfront-app.com

The Certbot wizard will ask you to create the file with particular content. Create it and place at the required path. Wait a few minutes after that to ensure the CloudFront cache is updated (if necessary) or verification may fail. It looks like we've got our certificates.

Apply certificates to the CloudFront distribution

We'll use the AWS CLI tool to upload the certificates to Cloudfront. Let's begin and upload one:

$ aws iam upload-server-certificate --server-certificate-name certificate_name --certificate-body file:///etc/letsencrypt/live/my-awesome-cloudfront-app.com/cert.pem --private-key file:///etc/letsencrypt/live/my-awesome-cloudfront-app.com/privkey.pem --certificate-chain file:///etc/letsencrypt/live/my-awesome-cloudfront-app.com/chain.pem --path /cloudfront/	

A few things you may need to know about the last command:

  • The name must be unique — you can't have multiple certificates with the same name. And you can't just use the same name to replace the existing one.
  • Don't be afraid of the strange file:/// windows-like prefix. It's for Linux.
  • The /etc/letsencrypt/live/my-awesome-cloudfront-app.com/ directory will always be a symlink to a directory with your latest certificates for the domain. The previous ones will not go anywhere — you can locate them in the /etc/letsencrypt/archive subdirectory.
  • The particular `path` argument is necessary to make Cloudfront aware of you certificates. You can upload them to any path, but you simply will not find them in the web console of Cloudfront.

If you've made a mistake or you just want to delete an obsolete certificate, use the following command:

aws iam delete-server-certificate --server-certificate-name certificate_name`

Enjoy your secure web!

Why yet another one tutorial?

A single-page application (SPA) is a web application or web site that fits on a single web page with the goal of providing a more fluid user experience similar to a desktop application.

I've been thinking of a complete tutorial on writing SPA in modern JavaScript for a long time. «There are a lot of such lessons» — you can say and be 100% right. But most of them have a very confusing part for newcomers: the horrific amount of buzzwords! The days when you were able to write the simplest «Hello World» program in just a few lines of code are long gone. Now you should know good enough answers to many important questions before you could even start coding.


Браузеры всегда были очень инертной средой для исполнения наших программ. Даже когда язык JavaScript ещё не развивался так быстро как сейчас, браузеры уже не успевали за ним. Годами на троне сидел какой-нибудь хтонический монстр вроде IE6 и заставлял с ним считаться каждого. Нам пришлось на долгое время забыть об использовании чистых языковых конструкций и научиться доверять очередной библиотеке, знающей разницу между браузерами и их версиями. Появились армии разработчиков, неплохо знающих jQuery, но как огня боящихся самого языка JavaScript. В то же время, дела со стилями в чем-то были еще хуже. Несмотря на появление множества новых свойств, сам формат не получил вообще никаких значимых улучшений и, в сыром виде, даже сейчас едва ли может быть удобен кому-либо.

Конечно, со временем, ситуация начала исправляться: поддержка JavaScript стала лучше, появились полифиллы для устаревших браузеров, компиляторы CSS и, наконец, транспайлеры в ES6. Но, к сожалению, это всё не доступно из коробки каждому, это удовольствие нужно настраивать разработчику и не всем из нас ясно как же это сделать. На первый взгляд всё кажется намного сложнее, чем дела обстоят на самом деле. Кажется, что если у вас нет специального сервера для сборки, CI, CD, какого-нибудь хитрого сборщика, то не стоит и пытаться что-то сделать. Но, на самом деле, это и не требуется.

I have never been really good at writing. I won some rewards in my childhood. I wrote some shitty verses in my youth. None of those achievements really were significant for the universe around me. It was all like a silly child play with the symbols I barely know. Move one back and another forward, make a stanza, make another one, make them a little bit more shiny. I experienced that well-known fear of a blank page. And I experienced that recursive «oh, I can do this paragraph better» annoying thing too. But I love writing, I really do. I have dreamt about writing a book all my life long just like my grandfather had dreamt before me. That’s why I have decided to write my thoughts in English: to master my slack skills with practice that makes me happy.

We are what we do and what we think about. The oceans of information we swim in are unstable in our epoch. Their coast and bottom are changing their shapes every second with new memes rising and fighting each other to the bloody death. The key point is that those ideas are battling mostly in English. Native speakers are lucky in some way: they don’t need to do anything to be in the middle of that storm and to see every glimpse of new fancy ideas worth knowing about.

Not that I say that other languages are not good. They are wonderful, all of them. But they act in this battle as smidge waves in the far away bays. And what I am interested in as a contemporary engineer and transhumanist is this battle itself. I want to be in the vanguard of this mess crushing metaphoric skulls with my own great axe of knowledge and will.

And then again I asked myself a question: «Do I really want to battle ooze and slime in memetic swamps of my native language? Do I really want to waste my life for that dolorous purpose?»

So here I am now.

Как правило, наибольшего успеха добивается тот, кто располагает лучшей информацией
Бенджамин Дизраэли

Лишь совсем простые приложения могут обойтись без файла конфигурации. У остальных всегда найдется, что хранить в конфиге: настройки окружения, настройки логики, часто меняющиеся фрагменты текста, etc. Словом, вопроса «что хранить в конфигурации» обычно не возникает: кандидатов достаточно. А вот вопрос «как хранить конфигурацию» возникает часто и еще чаще решается не самыми оптимальными способами. В этой статье я хотел бы рассмотреть варианты хранения конфигурации приложения, их плюсы и минусы.