Owning Your Data: Self-hosting Standard Notes at Home
This article is about self-hosting Standard Notes in your home network. Standard Notes is a free, open-source, and completely encrypted notes app which can be self-hosted anywhere. Alternatively, they also offer both free and paid PaaS solutions for hosting content on their servers. This post deals with hosting Standard Notes at home on a Synology NAS running on DSM 7.2. Alternatively, it can also be hosted on Raspberry Pi, Portainer, or any Linux server similarly. As my router sits behind a primary router which does not allow port forwarding, Cloudflare tunnel will be used to connect to the NAS as a reverse proxy. Alternatively, if your server is connected to a primary router, port forwarding can be used to connect via the Internet. However, opening up ports on a router should only be done if there are proper firewall rules in place. Also, Cloudflare traffic is end-to-end encrypted by default throughout the Cloudflare tunnel, so you need not manually setup HTTPS encryption.
Prerequisites
Standard Notes will be running as a Docker container on the NAS. In order to run Docker containers on DS 7.2, Docker and/or Container Manager
needs to be installed. Also, we will be using Docker-compose
to run Standard Notes and its dependencies. It needs to be manually installed (if not already available) and run via CLI. For this, it is necessary to open up port 22 in the NAS to allow ssh connections.
Domain registration
Domain registration can be done via Cloudflare or if you already have an existing domain name, it can either be transferred to Cloudflare or it can also be connected to the Cloudflare tunnel by adding CNAME
or Alias
records to your existing domain. If you're not going to use a Zero-Trust Tunnel, then you are free to use any domain provider.
Cloudflare Zero-Trust Tunnel
Cloudflare tunnels need to be configured to connect to the NAS via the internet. You can create a tunnel by navigating to Cloudflare's Zero trust dashboard and create a new tunnel under Access ⇾ Tunnels. You will then receive a token with which you can connect your client. Take a note of this token and keep this tab open until our client connector has been connected to the tunnel successfully.
Configuration
In order to map volumes, create the following folder structure in your NAS file system.
volume1 /
├── homes/
│ ├── your_username/
│ │ ├── standard_notes/
│ │ │ ├── logs/
│ │ │ ├── uploads/
│ │ │ ├── data/
│ │ │ │ ├── mysql/
│ │ │ │ ├── import/
│ │ │ │ └── redis/
Then login to the server via SSH and navigate to the standard_notes
directory.
ssh [email protected]
cd standard_notes
Create a .env
file in this working directory and copy the default values from Standard Notes docs.
touch .env
curl https://raw.githubusercontent.com/standardnotes/server/main/.env.sample > .env
The default .env file should be as follows.
######
# DB #
######
DB_HOST=db
DB_PORT=3306
DB_USERNAME=std_notes_user
DB_PASSWORD=changeme123
DB_DATABASE=standard_notes_db
DB_TYPE=mysql
#########
# CACHE #
#########
REDIS_PORT=6379
REDIS_HOST=cache
CACHE_TYPE=redis
########
# KEYS #
########
AUTH_JWT_SECRET=
AUTH_SERVER_ENCRYPTION_SERVER_KEY=
VALET_TOKEN_SECRET=
Open your .env
file and make sure the values for the variables in the KEYS
section are properly set. You can run the following command in order to generate a key value for each of the required environment variable.
openssl rand -hex 32
Copy the LocalStack bootstrap script and place it in your working directory. Ensure the file has executable permissions.
curl https://raw.githubusercontent.com/standardnotes/server/main/docker/localstack_bootstrap.sh > localstack_bootstrap.sh
chmod +x localstack_bootstrap.sh
Copy the docker-compose.example.yml file
to a file called docker-compose.yml
in the working folder.
curl https://raw.githubusercontent.com/standardnotes/server/main/docker-compose.example.yml > docker-compose.yml
You can customize the server port in services/ports
in the docker-compose.yml
file, if you have other services running in the default port 3000.
Next, change the default database password. Generate a secure random string and replace this string in the DB_PASSWORD
field in .env
file and in MYSQL_ROOT_PASSWORD
and MYSQL_PASSWORD
fields in docker-compose.yml
file.
If you want to use Cloudflare zero trust tunnels, add the following service to your docker-compose.yml
file.
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflare-tunnel-for-standard-notes
restart: always
command: tunnel --no-autoupdate run
environment:
- TUNNEL_TOKEN=cloudflare-tunnel-token-noted-above
Enter the TUNNEL_TOKEN
value noted previously.
The final docker-compose.yml
file should be as follows.
services:
server:
image: standardnotes/server
env_file: .env
container_name: server_self_hosted
restart: unless-stopped
ports:
- 3000:3000
- 3125:3104
volumes:
- ./logs:/var/lib/server/logs
- ./uploads:/opt/bundled/files/packages/files/dist/uploads
networks:
- standardnotes_self_hosted
localstack:
image: localstack/localstack:1.3
container_name: localstack_self_hosted
expose:
- 4566
restart: unless-stopped
environment:
- SERVICES=sns,sqs
- HOSTNAME_EXTERNAL=localstack
- LS_LOG=warn
volumes:
- ./localstack_bootstrap.sh:/etc/localstack/init/ready.d/localstack_bootstrap.sh
networks:
- standardnotes_self_hosted
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflare-tunnel-for-standard-notes
restart: always
command: tunnel --no-autoupdate run
environment:
- TUNNEL_TOKEN=cloudflare-tunnel-token-noted-above
db:
image: mysql:8
container_name: db_self_hosted
environment:
- MYSQL_DATABASE=standard_notes_db
- MYSQL_USER=std_notes_user
- MYSQL_ROOT_PASSWORD=enter_changed_password
- MYSQL_PASSWORD=enter_changed_password
expose:
- 3306
restart: unless-stopped
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
volumes:
- ./data/mysql:/var/lib/mysql
- ./data/import:/docker-entrypoint-initdb.d
networks:
- standardnotes_self_hosted
cache:
image: redis:6.0-alpine
container_name: cache_self_hosted
volumes:
- ./data/redis/:/data
expose:
- 6379
restart: unless-stopped
networks:
- standardnotes_self_hosted
networks:
standardnotes_self_hosted:
name: standardnotes_self_hosted
To spin up all the services in this environment, run the following docker-compose
command.
sudo docker-compose pull && sudo docker-compose up -d
It will take a moment for the infrastructure to spin up. Deploying the YAML file will also start up the Cloudflare tunnel. Navigate to Cloudflare tunnel page to see the status of the connector. Once the connection is established, you can configure where to route the traffic to. Select Public hostname
as yourdomain.com and enter Service
as http://192.168.xxx.xxx:3000
. You can also host it in a custom subdomain, depending on your preference.
You can monitor deployment logs using the following command.
tail -f logs/*.log
If you encounter issues, check the error logs: tail -f logs/*.err
.
After the infrastructure is up and running, you can check it's available by visiting https://<subdomain or www>.<your-domain-name>.<TLD>
in your browser.
Using your new server
Download the Standard Notes app or visit https://app.standardnotes.com/ to create an account in your self-hosted server and start using it. Note that if you are an existing Standard Notes user using the default PaaS solution and want to migrate to the self-hosted server, you cannot use your existing account. You will need to re-register on your new server. You can export backup of your existing notes from your old account and import them in the new account easily. This will import all your existing notes and plugins too.
To create a new account in the new server, click on the account menu, choose Advanced options
and enter the address of your new server in Custom sync server
. Then, register for a new account and begin using your private new secure Standard Notes server! Note that it is very easy to forget that you need to specify your Custom Sync server
via the Advanced options
dropdown while creating a new account or logging in via your mobile or desktop application. Otherwise, it will try to log you in using Standard Note's default PaaS server, where your account is obviously not registered. Therefore, always remember to specify your Custom Sync Server
while logging in.
After successful installation and setup of Standard Notes, you may disable ssh access on Synology NAS again, to enhance protection.
All your notes are now safely stored in your home under your full control and not in an unknown server elsewhere managed by someone else.
Happy Hacking!