Усі статті
HTTPSmkcertlocal developmentlocalhost tunneling

HTTPS на localhost: mkcert проти тунелю, чесне порівняння

Два інструменти, одна задача: ваш dev-сервер має бути доступним через HTTPS. mkcert дає локально довірений TLS-сертифікат, тож https://localhost:3000 просто працює. Тунель дає публічний HTTPS-URL зі справжнім сертифікатом від справжнього CA. Вони не конкуренти — розв’язують різні задачі, — але люди постійно ставляться до них як до конкурентів.

Коротка відповідь

  • Потрібен HTTPS лише на власній машині, для власного браузера? Беріть mkcert.
  • Потрібно, щоб зовнішній сервіс (Stripe, GitHub, Auth0, телефон) дістався dev-сервера? Беріть тунель.
  • І те, і те? Запустіть обидва. Вони не конфліктують.

Це вся стаття в трьох пунктах. Решта — лише чому.

mkcert: локально довірені сертифікати за 30 секунд

mkcert встановлює локальний центр сертифікації у сховище довіри вашої ОС і випускає з нього сертифікати. Браузер бачить сертифікат як довірений, бо CA довірений. Жодних попереджень з’єднання не захищене, жодних прапорів --ignore-certificate-errors, жодної саморобної self-signed мороки.

# один раз на машину
mkcert -install

# один раз на проєкт
mkcert localhost 127.0.0.1

# тепер у вас localhost.pem і localhost-key.pem

Підключіть їх до dev-сервера (Vite, Next.js, Express, Django runserver_plus — усі підтримують TLS-аргументи), і у вас https://localhost:3000 зі справжнім сертифікатом.

Підступ: цьому CA довіряє лише ваша машина. Браузер колеги попередить. Телефон не довіриться без ручного встановлення кореня CA.

Тунель: справжній HTTPS, справжній публічний URL

localhost-тунель перенаправляє трафік із публічного HTTPS-URL на ваш локальний порт. Сертифікат випущений справжнім CA (Let's Encrypt тощо) і довірений кожним браузером на кожному пристрої.

npx portpreview 3000

Тунель виконує термінування TLS на хмарному шлюзі. Локальний сервер може лишатися на звичайному HTTP — публічний URL це HTTPS, і саме його торкається кожен зовнішній сервіс.

Пліч-о-пліч

ПотребаmkcertТунель
HTTPS у локальному браузеріТакТак (через публічний URL)
Тест service worker / secure cookie у браузеріТакТак
Зовнішній провайдер може вас дістатиНіТак
Телефон у руці може вас дістатиНі (без встановлення CA)Так
OAuth-провайдер приймає URLІноді (Google: так; багато: ні)Так
Stripe / GitHub / Twilio можуть слати вебхукНіТак
Час налаштування30 секунд на машинуОдна команда на сесію
Працює офлайнТакНі
Переживає режим польотуТакНі

Де люди помиляються

Намагаються використати mkcert для тестування вебхуків

Stripe не може довіряти локальному CA вашої машини. Байдуже, наскільки довіреним виглядає сертифікат у браузері, — Stripe в іншій мережі. Для будь-якого вхідного трафіку з публічного інтернету потрібен тунель.

Використовують тунель для сольного HTTPS лише в браузері

Якщо треба лише, щоб запрацювали service worker або встановилася secure cookie у власному браузері, mkcert швидший і працює офлайн. Не палить сесію тунелю на те, що розв’язує файл сертифіката.

Обирають один інструмент і проштовхують крізь нього інший кейс

Запускати обидва — нормально. Більшість нашого налаштування використовує mkcert для щоденної роботи з боку браузера й тунель, коли тестуємо вебхуки чи OAuth-колбеки. Вони співіснують у package.json без конфлікту.

А як щодо Caddy чи nginx?

Так, можна запустити Caddy з автоматичним HTTPS перед dev-сервером, і це теж працює — по суті це «mkcert із зайвими кроками й зворотним проксі». Для більшості локальної розробки mkcert простіший. Для складнішої маршрутизації з кількома локальними сервісами Caddy виправдовує себе.

Наше реальне налаштування

В одному репозиторії, де ми працюємо, є mkcert у dev-скрипті для HTTPS на боці localhost і окремий npm-скрипт tunnel, що запускає portpreview, коли комусь потрібні вебхуки чи тестування на мобільних. URL тунелю передається через env-змінну, тож OAuth redirect URI легко міняти. На під’єднання пішло 20 хвилин, і відтоді ми не думали про локальний TLS.

Про налаштування тунелю під OAuth див. як тестувати OAuth-колбеки локально. Щоб ділитися прев’ю з колегами чи дизайнерами — поділитися локальним dev-сервером. Приєднайтеся до списку очікування PortPreview заради тунельної частини цього налаштування.

Поширені запитання

Що використати для локального HTTPS — mkcert чи тунель?
Обидва, для різного. mkcert дає вашому браузеру довірений сертифікат на localhost і працює офлайн. Тунель дає публічний HTTPS-URL, доступний зовнішнім сервісам та іншим пристроям. Вони не конфліктують — більшість команд використовують обидва.
Чи впорається mkcert із тестуванням вебхуків від Stripe чи GitHub?
Ні. Сертифікати mkcert довірені лише на машині, де встановлено CA. Зовнішні провайдери вебхуків не можуть дістатися localhost, хай яким довіреним виглядає сертифікат у вашому браузері. Для будь-якого вхідного публічного трафіку використовуйте тунель.
Чи працює mkcert для OAuth-колбеків на localhost?
Деякі провайдери (Google, окремі dev-рівні Auth0) приймають localhost через HTTP або HTTPS для розробки. Багато — ні. mkcert дає HTTPS для тих, хто приймає; для суворих потрібен тунель із публічним HTTPS-URL.