Setup a self-hosted privacy-focused encrypted note-keeping solution
Starting from the developments at Apple about introducing privacy features like making it harder for Facebook advertisers to track user's locations, 2020 wasn't a good year for Facebook . A lot of business owners ranging from small businesses who make apparels to commercial giants like Amazon make use of Facebook's advertising to boost sales and help them in gaining insights from analytics through Facebook or other third-party businesses (like Cambridge Analytica) that rely heavily on data gathered through platforms like Facebook or just Facebook or it's platforms like Instagram.
Somehow, WhatsApp was never exclusively a part of this whole system. (Really?)
UNTIL NOW! Recently, users have start seeing the below prompt on WhatsApp:
To challenge all of the above issues, Facebook recently took the decision to enable data sharing between itself and WhatsApp starting from 8th February 2020. The real kicker is: You can choose to give the control for Services that will ask for permissions on your device (like Location) including the data generated and its sharing to Facebook's platform OR you can choose to: NOT USING WHATSAPP anymore! Freaking out?
Now, it is practically impossible to convince everyone (Think how hard it will be, to convince our Grandparents to stop using WhatsApp, let alone Millennials or Gen-Z).
But one thing in our control is: Controlling the data that we share on WhatsApp!
A lot of folks use WhatsApp to store notes, even passwords and secret keys to their cryptocurrency wallets! So, in this tutorial, we will have a look at setting up a privacy-oriented self-hosted note keeping solution with encryption using Standard Notes.
Update: Standard Notes has updated its self-hosting stack completely which makes the use of the below (now legacy) system obsolete. Please find their steps here.
Standard Notes is an open source and completely encrypted solution that ensures you have control on your data: You can setup a Sync Server that will help sync notes stored between your different devices. (Apps available on: Mac, iOS, Android, Windows and Linux) This will make sure that notes stored on your device's storage are synced through your server.
For this tutorial, we will be setting up a sync server with 1-core CPU, 1GB RAM and 50GB Storage running Ubuntu 20.4 LTS.
Follow the below steps:
Step 1: Install Ruby 2.6.6 with RVM and other gems (dependencies):
sudo apt update
sudo apt upgrade
sudo apt install gnupg2
gpg2 --keyserver hkp://keys.gnupg.net --recv-keys \\409B6B1796C275462A1703113804BB82D39DC0E3 \\7D2BAF1CF37B13E2069D6956105BD0E739499BDB
cd /tmp
curl -sSL https://get.rvm.io -o rvm.sh
sudo cat /tmp/rvm.sh | sudo bash -s stable --rails
source /home/sammy/.rvm/scripts/rvm
rvm install ruby-2.6.6
rvm use ruby-2.6.6
gem install rails -v 5.2.0
gem install bundler
gem install rubygems-update
update_rubygems
Step 2: Install MySQL 5.7 (This step can be skipped if you have access to a remote server with MySQL 5.7):
wget https://dev.mysql.com/get/mysql-apt-config_0.8.12-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.12-1_all.deb
sudo apt-get update
sudo apt install -f mysql-client=5.7.32-1ubuntu18.04 mysql-community-server=5.7.32-1ubuntu18.04 mysql-server=5.7.32-1ubuntu18.04
Setup MySQL user and database:
sudo mysql -u root -p
<Click Enter as there no default root password after installation>
Use the below SQL commands to setup a database and user:
create database standard_notes_db;
<Replace localhost below 2 queries to the server's IP on which this sync server is being setup>
CREATE USER 'std_notes_user'@'localhost' IDENTIFIED BY 'yourpasswordhere';
GRANT ALL PRIVILEGES ON standard_notes_db.* TO 'std_notes_user'@'localhost';
flush privileges;
exit;
Step 3: Setup Standard Notes Sync Repository:
git clone --branch master https://github.com/standardnotes/syncing-server.git
cd syncing-server/
openssl rand -hex 64
<Copy the key generated for the last two lines of .env file>
vim .env
Click on "i" key to start inserting, Copy the following to the above opened .env file and after editing click on "Esc" key, type :w, hit Enter and finally type :q & hit Enter!
# Rails Settings
EXPOSED_PORT=3000
# change this to "production" for production use, otherwise the access token time is very short and forces re-login
RAILS_ENV=development
RAILS_LOG_TO_STDOUT=false
RAILS_LOG_LEVEL=info # "debug" | "info" | "warn" | "error" | "fatal"
ACTIVE_JOB_QUEUE_ADAPTER=async
# Database Settings - Use Remote MySQL 5.7 Setup if using Remote Server
DB_PORT=3306
DB_HOST=127.0.0.1
DB_DATABASE=standard_notes_db
DB_USERNAME=std_notes_user
# Please change this!
DB_PASSWORD=changeme123
DB_POOL_SIZE=30
DB_WAIT_TIMEOUT=180
# Secrets
# Use: "bundle exec rake secret" or "openssl rand -hex 64"
# To generate required secret key base below
SECRET_KEY_BASE=changeme123
PSEUDO_KEY_PARAMS_KEY=changeme456
Step 4: Install Standard Notes Sync Server:
bundle install
bundle exec rails db:create db:migrate
Run the following command to check if the above installation is working:
bundle exec rails server
Step 5: After successfully completing above steps, now the job is to setup the above server as a daemon process:
This is also where things get a little bit tricky: Normally, we can expand the rails server command up by -d for it to run as a daemon process, however, it does not seem to work in this setting. Lucky us, we have a workaround:
screen rails s
Now, press CTRL + A + D and you will end up back on your Command Prompt.
Step 6 [Optional]: Setup Nginx and open up ports 80, 443 and 3000 (the port on which sync server is running on):
sudo apt install nginx
sudo systemctl enable nginx
sudo systemctl start nginx
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -j ACCEPT
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 3000 -j ACCEPT
sudo netfilter-persistent save
And Voila, your sync server should be up now and you can test it out at:
curl http://localhost:3000
In case this is not working, feel free to comment on this blog post and I'll try to help out!
[Optional]
We can also setup this sync server instance as a domain/subdomain along with SSL configuration using the below post:
[Bonus]
Want to use a server with aforementioned configuration and don't want to pay for it...EVER?
Follow the below post to obtain forever free servers from Oracle Cloud:

Use the above tutorial and #controlyourdata !
Cheers!