fix: cyrillic fonts, dev certs, page head, and ru-text typography (#67)

🤖 PR generated for branch `fix/cyrillic-fonts-dev-certs-and-page-head`.

### Changes Summary
- **Fonts**: Add Cyrillic glyph subsets for Lato, EB Garamond, and Fira
Code.
- **Dev**: Support remote Root CA and encrypted dev CA key in
`.env.dev`.
- **UI & Kits**: Add size variant to `Breadcrumbs` component and enlarge
`PageHead` breadcrumbs with tuned collapse scroll threshold.
- **ESLint**: Add `no-hanging-particles` i18n & markdown typography rule
with auto-fixer.
- **Content & i18n**: Apply `ru-text` editorial and typography polish
(em dashes, number ranges, «ё» restoration, non-breaking spaces) across
`services/www` and `services/docs`.
This commit is contained in:
deytenit authored and GitHub committed 2026-10-25 15:21:09 +03:00
1 parent c6487dc258
commit b3638f4d63
111 files changed
+2350 -1512

No files matched your search

@@ -1,36 +1,36 @@
---
title: 'Joplin Web Deployment Guide'
description: 'Joplin Server & Web App deployment from scratch'
description: 'Joplin Server & Web App deployment from scratch'
createdDate: 2026-03-20
tags: ['self-hosting', 'guides', 'joplin']
---
This guide describes how to deploy a private note-taking infrastructure using the Joplin Server and its web client.
This guide describes how to deploy a private note-taking infrastructure using the Joplin Server and its web client.
## Why I Chose Joplin?
I have been using Joplin for a long time, and it has become my primary note-taking tool. There are several reasons why I chose it over other alternatives:
I have been using Joplin for a long time, and it has become my primary note-taking tool. There are several reasons why I chose it over other alternatives:
- **Local-First**: Notes are stored locally on your device, ensuring fast access and full ownership (especially when the internet is inaccessible).
- **Markdown Format**: Joplin uses Markdown for all notes, making it incredibly easy to export, import, or move your data to another platform if needed.
- **Easy Sharing**: The ability to share notes via the web makes collaboration or public sharing straightforward.
- **Backups**: Joplin provides robust backup options, giving me peace of mind that my data is safe.
- **Local-First**: Notes are stored locally on your device, ensuring fast access and full ownership (especially when the internet is inaccessible).
- **Markdown Format**: Joplin uses Markdown for all notes, making it incredibly easy to export, import, or move your data to another platform if needed.
- **Easy Sharing**: The ability to share notes via the web makes collaboration or public sharing straightforward.
- **Backups**: Joplin provides robust backup options, giving me peace of mind that my data is safe.
One thing that was missing for me was the ability to quickly add or view notes when I don't have access to my primary devices (for example, at work). This article provides the solution: a self-hosted web client.
One thing that was missing for me was the ability to quickly add or view notes when I don't have access to my primary devices (for example, at work). This article provides the solution: a self-hosted web client.
## Technical Stack Overview
1. **Joplin Server**: The synchronization server. It handles the Joplin sync protocol, account logic, and note synchronization across devices.
2. **Postgres**: The database. Essential for production performance.
3. **Joplin Web App**: A browser-based client built from the Joplin mobile app source code using React Native for Web.
1. **Joplin Server**: The synchronization server. It handles the Joplin sync protocol, account logic, and note synchronization across devices.
2. **Postgres**: The database. Essential for production performance.
3. **Joplin Web App**: A browser-based client built from the Joplin mobile app source code using React Native for Web.
## 1. The Deployment Stack
## 1. The Deployment Stack
This configuration is generic, uses **Docker Volumes**, and provides a minimal setup for deploying the full stack.
This configuration is generic, uses **Docker Volumes**, and provides a minimal setup for deploying the full stack.
### Main docker-compose.yml
This compose file is a minimal configuration to run the Joplin Server and the web app. It assumes you understand how to set up a reverse proxy, or better yet, already have your own Joplin setup.
This compose file is a minimal configuration to run the Joplin Server and the web app. It assumes you understand how to set up a reverse proxy, or better yet, already have your own Joplin setup.
```yaml
x-environment: &shared-environment
@@ -84,9 +84,9 @@ volumes:
### Dockerfile
Create an `app` directory and place this `Dockerfile` inside it to build the web client. We build our own image since the original authors don't provide one.
Create an `app` directory and place this `Dockerfile` inside it to build the web client. We build our own image since the original authors don't provide one.
While there are repositories with pre-built images, it's easy enough to just create our own.
While there are repositories with pre-built images, it's easy enough to just create our own.
```dockerfile
# Stage 1: Build
@@ -128,9 +128,9 @@ CMD ["nginx", "-g", "daemon off;"]
### Nginx configuration
Place this `nginx.conf` alongside the `Dockerfile` in the `app` directory. Joplin is an SPA, meaning it doesn't matter where it's deployed since all navigation is handled internally without location dependency. So it's alright to just deploy it on a path that doesn't overlap with the main server, such as `/app`.
Place this `nginx.conf` alongside the `Dockerfile` in the `app` directory. Joplin is an SPA, meaning it doesn't matter where it's deployed since all navigation is handled internally without location dependency. So it's alright to just deploy it on a path that doesn't overlap with the main server, such as `/app`.
> This is a pretty minimal configuration; it assumes your reverse proxy is good enough to cover all questionable items, but you can expand it as you like.
> This is a pretty minimal configuration; it assumes your reverse proxy is good enough to cover all questionable items, but you can expand it as you like.
```nginx
server {
@@ -161,7 +161,7 @@ server {
## 2. Configuration
Create a `.env` file in the same directory as your `docker-compose.yml`. **Do not skip the secret generation step below.**
Create a `.env` file in the same directory as your `docker-compose.yml`. **Do not skip the secret generation step below.**
```bash
# --- Database Credentials ---
@@ -171,7 +171,7 @@ SHARED_PASSWORD=generate_this_with_openssl
### Generating Secrets
Use `openssl` to easily generate secure, random strings for your `.env` entries:
Use `openssl` to easily generate secure, random strings for your `.env` entries:
```bash
# Generate SHARED_PASSWORD
@@ -180,7 +180,7 @@ openssl rand -hex 32
## 3. Deployment
Start your stack by running the following command:
Start your stack by running the following command:
```bash
docker compose up -d --build
@@ -188,33 +188,33 @@ docker compose up -d --build
## 4. Initial Server Setup
Before configuring the web app, you must initialize your Joplin Server:
Before configuring the web app, you must initialize your Joplin Server:
Follow the official guide: [Joplin Server README](https://github.com/laurent22/joplin/blob/dev/packages/server/README.md)
Follow the official guide: [Joplin Server README](https://github.com/laurent22/joplin/blob/dev/packages/server/README.md)
Essentially, you need to ensure that basic synchronization via the app is functional.
Essentially, you need to ensure that basic synchronization via the app is functional.
## 5. Web App Showcase & Setup
Once the web app is running at `https://example.com/app/`, you will be greeted by it.
Once the web app is running at `https://example.com/app/`, you will be greeted by it.
### About the Web App
### About the Web App
![Joplin Web App Interface](https://static.ermnvldmr.com/www/articles/2026/joplin-web-deployment-guide/joplin-web-interface.webp)
It is basically the same mobile Joplin app, but in-browser. It leverages the LocalStorage API for data handling. Everything is still local-first, so after logging in, it will take some time to synchronize all remote notes.
It is basically the same mobile Joplin app, but in-browser. It leverages the LocalStorage API for data handling. Everything is still local-first, so after logging in, it will take some time to synchronize all remote notes.
But most importantly: _The Joplin web interface allows you to view and edit your notes directly from the browser._
But most importantly: _The Joplin web interface allows you to view and edit your notes directly from the browser._
> It is said that it's only guaranteed to work on Chrome due to the required API compatibility; however, I have had great success with Firefox as well. Browsers are catching up quickly.
> It is said that it's only guaranteed to work on Chrome due to the required API compatibility; however, I have had great success with Firefox as well. Browsers are catching up quickly.
### Authentication Setup
To connect to your self-hosted Joplin Server, go to **Settings > Synchronization** and configure the following parameters:
To connect to your self-hosted Joplin Server, go to **Settings > Synchronization** and configure the following parameters:
- **Sync Target**: Joplin Server
- **Joplin Server URL**: `https://example.com`
- **Joplin Server Email**: `your-email@example.com` (the one you just created/configured)
- **Joplin Server Email**: `your-email@example.com` (the one you just created/configured)
- **Joplin Server Password**: `your-password`
![Joplin Web App Setup](https://static.ermnvldmr.com/www/articles/2026/joplin-web-deployment-guide/joplin-web-setup.webp)