🤖 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`.
224 lines
10 KiB
Plaintext
224 lines
10 KiB
Plaintext
---
|
||
title: 'Руководство по развёртыванию Joplin Web'
|
||
description: 'Развёртывание Joplin Server и веб-приложения с нуля'
|
||
createdDate: 2026-03-20
|
||
tags: ['self-hosting', 'guides', 'joplin']
|
||
---
|
||
|
||
В этом руководстве разберём, как развернуть приватную инфраструктуру для заметок на базе Joplin Server и веб-клиента.
|
||
|
||
## Почему я выбрал Joplin?
|
||
|
||
Я давно пользуюсь Joplin как основным приложением для заметок. Вот почему я выбрал именно его:
|
||
|
||
- **Local-First**: заметки хранятся локально на устройстве. Доступ к ним мгновенный, а данные остаются под полным контролем даже без интернета.
|
||
- **Формат Markdown**: все заметки сохраняются в Markdown, поэтому их легко экспортировать, импортировать или перенести на другую платформу.
|
||
- **Удобный обмен**: заметками можно делиться через веб для совместной работы или публичного доступа.
|
||
- **Резервное копирование**: в Joplin встроены надёжные механизмы бэкапа, поэтому за сохранность данных можно не беспокоиться.
|
||
|
||
Мне не хватало лишь одного — возможности быстро открыть или записать заметку без доступа к основным устройствам (например, с рабочего компьютера). Решение — собственный (self-hosted) веб-клиент.
|
||
|
||
## Обзор технологического стека
|
||
|
||
1. **Joplin Server**: сервер синхронизации. Отвечает за протокол обмена данными, учётные записи и синхронизацию заметок между устройствами.
|
||
2. **Postgres**: база данных. Обеспечивает высокую производительность и стабильность в рабочей среде.
|
||
3. **Joplin Web App**: браузерный клиент, собранный из исходного кода мобильного приложения Joplin с помощью React Native for Web.
|
||
|
||
## 1. Стек развёртывания
|
||
|
||
Конфигурация универсальна, использует **Docker Volumes** и содержит минимум параметров для развёртывания полного стека.
|
||
|
||
### Основной docker-compose.yml
|
||
|
||
В этом compose-файле собрана минимальная конфигурация для запуска Joplin Server и веб-приложения. Предполагается, что вы умеете настраивать обратный прокси-сервер или у вас уже развёрнут Joplin Server.
|
||
|
||
```yaml
|
||
x-environment: &shared-environment
|
||
TZ: 'Europe/Moscow'
|
||
POSTGRES_DB: 'joplin'
|
||
POSTGRES_USER: ${SHARED_USERNAME?:error}
|
||
POSTGRES_PASSWORD: ${SHARED_PASSWORD?:error}
|
||
|
||
services:
|
||
postgres:
|
||
image: postgres:16
|
||
container_name: joplin-postgres
|
||
volumes:
|
||
- postgres_data:/var/lib/postgresql/data
|
||
environment:
|
||
<<: *shared-environment
|
||
restart: unless-stopped
|
||
|
||
server:
|
||
image: joplin/server:3.5.2
|
||
container_name: joplin-server
|
||
depends_on:
|
||
- postgres
|
||
environment:
|
||
<<: *shared-environment
|
||
APP_PORT: 22300
|
||
APP_BASE_URL: 'https://example.com'
|
||
DB_CLIENT: 'pg'
|
||
POSTGRES_HOST: 'joplin-postgres'
|
||
POSTGRES_PORT: 5432
|
||
POSTGRES_DATABASE: 'joplin'
|
||
ports:
|
||
- '22300:22300'
|
||
restart: unless-stopped
|
||
|
||
app:
|
||
build:
|
||
context: ./app
|
||
args:
|
||
- GIT_TAG=v3.5.13
|
||
container_name: joplin-app
|
||
environment:
|
||
<<: *shared-environment
|
||
ports:
|
||
- '8080:8080'
|
||
restart: unless-stopped
|
||
|
||
volumes:
|
||
postgres_data:
|
||
```
|
||
|
||
### Dockerfile
|
||
|
||
Создайте директорию `app` и поместите в неё `Dockerfile` для сборки веб-клиента. Собираем собственный образ, потому что разработчики Joplin пока не выпускают официальный контейнер.
|
||
|
||
В сети встречаются сторонние образы, но собрать собственный надёжнее и проще:
|
||
|
||
```dockerfile
|
||
# Stage 1: Build
|
||
FROM node:20-bookworm-slim AS builder
|
||
|
||
ARG GIT_TAG=v3.5.13
|
||
|
||
# Install build dependencies for Joplin monorepo
|
||
RUN apt-get update && apt-get install -y \
|
||
git python3 build-essential rsync \
|
||
&& rm -rf /var/lib/apt/lists/*
|
||
|
||
WORKDIR /app
|
||
|
||
# Configure regional mirror and timeout for reliability
|
||
RUN corepack enable && \
|
||
yarn config set registry https://registry.npmmirror.com
|
||
|
||
# Clone specific tag
|
||
RUN git clone --depth 1 --branch ${GIT_TAG} https://github.com/laurent22/joplin.git .
|
||
|
||
# Install dependencies and build the web distribution
|
||
RUN yarn install --network-timeout 1000000
|
||
RUN cd packages/app-mobile/ && yarn web
|
||
|
||
# Stage 2: Production Server
|
||
FROM nginx:alpine
|
||
|
||
# Remove default assets
|
||
RUN rm -rf /usr/share/nginx/html/*
|
||
|
||
# Copy built app and custom nginx config
|
||
COPY --from=builder /app/packages/app-mobile/web/dist /usr/share/nginx/html/app
|
||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||
|
||
EXPOSE 8080
|
||
CMD ["nginx", "-g", "daemon off;"]
|
||
```
|
||
|
||
### Конфигурация Nginx
|
||
|
||
Поместите `nginx.conf` рядом с `Dockerfile` в директорию `app`. Joplin Web — это SPA (Single Page Application): маршрутизация выполняется внутри браузера, поэтому клиент можно развернуть по любому пути, не конфликтующему с сервером синхронизации, например `/app`.
|
||
|
||
> Это базовая конфигурация: предполагается, что TLS и защиту периметра берёт на себя обратный прокси. При необходимости правила Nginx можно дополнить.
|
||
|
||
```nginx
|
||
server {
|
||
listen 8080;
|
||
server_name _;
|
||
|
||
root /usr/share/nginx/html;
|
||
index index.html;
|
||
|
||
# Gzip-сжатие для производительности
|
||
gzip on;
|
||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||
gzip_min_length 1000;
|
||
|
||
# SPA-роутинг: возврат к index.html, если файл не найден
|
||
location /app/ {
|
||
try_files $uri $uri/ /app/index.html;
|
||
}
|
||
|
||
# Кэширование статических ресурсов
|
||
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2?|eot|ttf|svg|webmanifest)$ {
|
||
expires 6M;
|
||
access_log off;
|
||
add_header Cache-Control "public, max-age=15552000, immutable";
|
||
}
|
||
}
|
||
```
|
||
|
||
## 2. Конфигурация
|
||
|
||
Создайте файл `.env` рядом с `docker-compose.yml`. **Обязательно сгенерируйте надёжный пароль перед запуском.**
|
||
|
||
```bash
|
||
# --- Учетные данные базы данных ---
|
||
SHARED_USERNAME=joplin
|
||
SHARED_PASSWORD=generate_this_with_openssl
|
||
```
|
||
|
||
### Генерация секретов
|
||
|
||
Сгенерируйте пароль с помощью `openssl`:
|
||
|
||
```bash
|
||
# Генерация SHARED_PASSWORD
|
||
openssl rand -hex 32
|
||
```
|
||
|
||
## 3. Развёртывание
|
||
|
||
Запустите контейнеры:
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
## 4. Начальная настройка сервера
|
||
|
||
Перед настройкой веб-клиента инициализируйте Joplin Server по [официальной инструкции](https://github.com/laurent22/joplin/blob/dev/packages/server/README.md): создайте учётную запись администратора и проверьте, что базовая синхронизация работает через десктопное или мобильное приложение.
|
||
|
||
## 5. Демонстрация и настройка веб-приложения
|
||
|
||
После запуска откройте веб-клиент по адресу `https://example.com/app/`.
|
||
|
||
### О веб-приложении
|
||
|
||

|
||
|
||
Это интерфейс мобильного приложения Joplin, скомпилированный для браузера. Данные сохраняются в LocalStorage: приложение работает по принципу local-first, поэтому при первом входе потребуется время, чтобы скачать заметки с сервера.
|
||
|
||
Главная польза интерфейса — возможность просматривать и редактировать заметки прямо из браузера на любом устройстве без установки клиента.
|
||
|
||
> Разработчики заявляют гарантированную работу только в Chrome из-за требований к Web API, но клиент стабильно работает и в Firefox.
|
||
|
||
### Настройка аутентификации
|
||
|
||
Чтобы подключиться к своему серверу Joplin, откройте **Settings > Synchronization** и укажите параметры подключения:
|
||
|
||
- **Sync Target**: Joplin Server
|
||
- **Joplin Server URL**: `https://example.com`
|
||
- **Joplin Server Email**: `your-email@example.com` (созданный на предыдущем шаге)
|
||
- **Joplin Server Password**: `your-password`
|
||
|
||

|
||
|
||
Теперь синхронизированные заметки доступны прямо в браузере.
|
||
|
||
## Ресурсы
|
||
|
||
- [Joplin GitHub](https://github.com/laurent22/joplin)
|
||
- [Joplin Server README](https://github.com/laurent22/joplin/blob/dev/packages/server/README.md)
|