Ваш застосунок працює. Ви запустили dev-сервер, відкрили http://localhost:3000, і він робить те, що має. Потім хтось просить посилання, і з'ясовується, що URL на вашому екрані нічого не означає ні для кого, крім вас.
Є три способи дати localhost-застосунку публічний URL без VPS, плюс один швидший варіант, коли співрозмовник у вашій локальній мережі, і вибір між ними — це не питання інструмента. Це питання того, як довго застосунок має залишатися доступним і чи може він працювати десь, окрім вашого ноутбука. Нижче — кожен шлях, команда, яка дає URL, і саме те, що змусить цей URL перестати працювати.
TL;DR
- Комусь у вашому Wi-Fi треба це побачити: прив'яжіть dev-сервер до всіх мережевих інтерфейсів і повідомте свою LAN-IP. Готово за секунди, помирає тієї миті, коли гість залишає вашу мережу.
- Потрібне посилання, яке будь-хто відкриє протягом наступної години: запустіть тунель (
cloudflared, ngrok, localtunnel, localhost.run). Публічний HTTPS-URL приблизно за хвилину, жодних змін на роутері, і він помирає разом із процесом, який його запустив. - Він має працювати, поки ноутбук закритий: відправте застосунок на безкоштовний тариф хостингу. Це відв'язує застосунок від ноутбука і вводить нові правила: банківські картки, комерційне використання і те, чи переживуть ваші дані перезапуск.
- Вашому застосунку не потрібен серверний код у момент запиту: зберіть його і викладіть статичний результат на статичний хостинг. Він може залишатися онлайн без вашого ноутбука, і там немає процесу застосунку, який треба будити, поки обліковий запис і ліміти хостингу це дозволяють.
- Одне значення за замовчуванням, про яке варто знати:
next devтаpython -m http.serverуже слухають усі мережеві інтерфейси без жодних прапорців. Якщо ви вважали, що ваш dev-сервер видно лише на вашому ноутбуці, це не так.
Який шлях підходить вашому застосунку
Три з цих чотирьох шляхів дають застосунку публічний URL в інтернеті; перший сягає лише вашої мережі, що робить його водночас найшвидшим і найобмеженішим. Відсортуйте їх за тим, як довго має жити URL, і вибір майже зробить себе сам.
| Шлях | Час до отримання URL | Скільки живе | Що його вбиває | Для кого |
|---|---|---|---|---|
| Одна мережа | Секунди | Поки ви обоє в мережі | Гість переходить в інший Wi-Fi | Колега за сусіднім столом або ваш власний телефон |
| Тунель | Близько хвилини | Поки працює процес | Закрити ноутбук, убити термінал, впертися в ліміти тарифу | Демо, показ клієнту, тест вебхука |
| Безкоштовний тариф хостингу | Від 10 до 30 хвилин | Безстроково, з умовами | Присипляння, ефемерна файлова система або умови тарифу | Те, що має відповідати, поки ви спите |
| Статична збірка | Від 10 до 20 хвилин | Безстроково | Потреба в серверному коді в момент запиту | Застосунки, які можна повністю згенерувати під час збірки або виконувати на клієнті |
Які рядки вам доступні, залежить від трьох речей, які можна перевірити у власному проєкті:
- Чи потрібен застосунку ваш серверний код у момент запиту? Маршрут Flask або FastAPI, ендпоінт у
server.jsабо будь-яка серверна логіка, залежна від запиту, потребує серверного хостингу. Серверний код на етапі збірки не виключає статичне розгортання автоматично: Server Components у Next.js можуть виконуватися під часnext build, а статичніGETRoute Handlers можна пререндерити. Якщо кожен запит під час роботи можна віддати як статичні файли або надіслати напряму з браузера в зовнішній API, статичний шлях досі відкритий. - Чи читає або пише він файл, який треба зберігати? Файл бази даних (
.db,.sqlite), тека завантажень, JSON-файл, який він редагує. Якщо так, перевірте модель зберігання хостингу перед розгортанням. Безкоштовні вебсервіси Render і безкоштовні інстанси Koyeb використовують ефемерне локальне сховище, а Vercel Functions працюють із файловою системою лише для читання і тимчасовим простором/tmp. Тримайте постійний стан у надійному томі, базі даних або об'єктному сховищі, а не розраховуйте, що локальний диск застосунку вціліє. - Чи потрібен йому секрет під час роботи? Ключ у файлі
.envпрацює без змін на перших двох шляхах, бо застосунок досі запущений на вашій машині. На двох інших ви вводите його заново в налаштуваннях середовища провайдера, і його не має бути в репозиторії, який ви пушите.
Поділіться у своїй мережі
next dev уже слухає всі мережеві інтерфейси вашої машини (саме це й означає 0.0.0.0 , коли ви його бачите), і те саме робить python -m http.server. Жодному з них не потрібен прапорець, тож dev-сервер, який у вас запущений просто зараз, найімовірніше, вже доступний із телефона в тому ж Wi-Fi.
Next.js описує -H як спосіб змінити це ім'я хоста, зі значенням за замовчуванням 0.0.0.0, а документація Python каже, що модуль прив'язується до всіх інтерфейсів , якщо не передати --bind 127.0.0.1. Це робить такий спосіб найшвидшим, щоб поділитися localhost-застосунком: без облікового запису, без встановлення, без розгортання. Іншим популярним dev-серверам треба сказати про це явно.
# Already listening on all interfaces. Nothing to add.
next dev
python -m http.server 8000
streamlit run app.py
# Needs the flag.
npm run dev -- --host # Vite
flask run --host=0.0.0.0
uvicorn main:app --host 0.0.0.0 # FastAPI
Документація Vite: server.host за замовчуванням дорівнює localhost, а також приймає --host у командному рядку або server.host: '0.0.0.0' у файлі конфігурації. Uvicorn за замовчуванням використовує 127.0.0.1, що покриває й FastAPI, оскільки саме він його запускає. Streamlit залишає server.address незаданим, а його довідник із конфігурації зазначає, що його задання обмежує доступ лише цією адресою: не задано — отже без обмежень.
Далі потрібна адреса, яку ви повідомите. Це власна IP вашої машини в локальній мережі, а не localhost:
# macOS
ipconfig getifaddr en0
# Linux
hostname -I
# Windows (PowerShell)
ipconfig | findstr IPv4
Дайте гостю http://<that-address>:3000 , і він усередині. Підступ у формі всього шляху: ця адреса нічого не означає за межами вашої мережі. Щойно гість опиниться в іншому Wi-Fi, у мобільній мережі або вдома, посилання для нього мертве.
Примітка: якщо команда відпрацьовує нормально, а інший пристрій усе одно не може підключитися, майже завжди винен фаєрвол ОС, а не команда. Документація Apple щодо фаєрвола каже, що macOS показує попередження для застосунку, якому ви ще не дали дозвіл, і відхиляє з'єднання, доки ви не ухвалите рішення. Windows натомість питає, який мережевий профіль застосувати, і тримає окремі правила для приватних і загальнодоступних мереж. У домашній або офісній мережі обирайте «Приватна». Ніколи не обирайте «Загальнодоступна».
Сховайте його за тунель
Тунель — це невелика програма, яка працює поруч із вашим застосунком і дає йому публічну HTTPS-адресу. Одна команда дає безкоштовний тунель до localhost приблизно за хвилину, і варто одразу знати, що URL помирає тієї миті, коли завершується ця команда:
cloudflared tunnel --url http://localhost:3000
На роутері нічого не змінюється через напрямок, у якому йде з'єднання. Ваша машина відкриває вихідне з'єднання до граничного вузла провайдера, того ж типу, що ваш браузер відкриває для завантаження будь-якої сторінки, а провайдер тримає його відкритим і проштовхує вхідні запити назад по ньому. Вхідні порти з вашого боку залишаються закритими, тому це працює в готельному Wi-Fi, через точку доступу телефона і на домашньому підключенні, роутер якого ви не контролюєте.
Примітка: останній випадок заслуговує на шістдесятисекундну перевірку, перш ніж розглядати прокидання портів. Відкрийте сторінку стану роутера, знайдіть WAN-IP, яку він показує, і порівняйте її з вашою справжньою публічною IP із будь-якого сервісу «яка в мене IP». Якщо WAN-IP лежить усередині
100.64.0.0/10, імовірна причина — CGNAT. Якщо WAN-IP і публічна IP просто різняться, значить, вище по ланцюжку є ще один шар NAT, але це може бути як CGNAT, так і звичайний подвійний NAT. У будь-якому разі прокидання портів лише на цьому роутері може не вистачити. Цей діапазон зарезервований RFC 6598 як спільний адресний простір, і саме за нього вас ставить провайдер, коли в нього закінчуються адреси.
Варіанти різняться здебільшого тим, чого вони вимагають від вас насамперед.
Швидкі тунелі Cloudflare — це команда вище: без облікового запису, без домену, випадковий піддомен на trycloudflare.com . Cloudflare обмежує їх 200 одночасними запитами, понад це повертаючи 429, не підтримує Server-Sent Events і в тій самій документації каже, що безкоштовні тунелі призначені для тестування й розробки, а не для розгортання продакшен-сайту.
ngrok спершу вимагає реєстрації, а потім ngrok http 3000. Поточний безкоштовний тариф дає 5 $ разового включеного використання, яке не оновлюється щомісяця, до 3 онлайн-ендпоінтів, 1 ГБ трафіку, 20 000 HTTP/S-запитів і проміжну сторінку з попередженням, через яку гостю треба клікнути. Ви також отримуєте безкоштовний автоматично виданий домен для розробки, про який ngrok оголосив у 2023 році , щоб закрити давню скаргу на URL, що змінювався при кожному перезапуску.
localtunnel не потребує ні реєстрації, ні встановлення, крім npx: npx localtunnel --port 3000. Ви отримуєте випадковий піддомен, і README прямо каже, що --subdomain запитує ім'я, але не гарантує його.
localhost.run нічого не встановлює, бо використовує SSH-клієнт, який уже є у вашій ОС: ssh -R 80:localhost:3000 localhost.run. У документації зазначено, що завантажувати нічого не потрібно і що для безкоштовних доменів не треба створювати обліковий запис.
VS Code має це в панелі Ports, зручно, якщо ви й так живете в редакторі. Потрібен вхід через GitHub або Microsoft, а значення за замовчуванням вас підведе: прокинутий порт є приватним, тобто гостя попросять увійти з вашим обліковим записом, доки ви не перемкнете порт у публічний. (Нормально для колеги. Марно для клієнта, який просто хоче клікнути по посиланню.)
Tailscale Funnel теж це вміє, з двома обмеженнями, які зазвичай і вирішують справу: URL може жити лише на домені вашого tailnet, і він може слухати лише порти 443, 8443 і 10000.
Що б ви не обрали, чітко розумійте, що саме ви роздали. З публічним тунелем без контролю доступу все, що віддає dev-сервер, доступне будь-кому, хто має цей URL, включно з маршрутами, на які ви ніколи не посилалися, і будь-яким налагоджувальним інтерфейсом, який ви залишили ввімкненим. Нормально для п'ятнадцятихвилинного демо. Значно гірше для URL, вставленого в публічний Discord.
Закінчення терміну застає зненацька, бо виглядає так, ніби застосунок зламався. Більшість швидких шляхів тут досі залежать від тунельного ПЗ на вашому ноутбуці: зупиніть cloudflared, ngrok, localtunnel або SSH-сесію localhost.run — і прокидання припиниться. Tailscale Funnel — виняток, якщо запустити його з --bg: тоді конфігурація Funnel далі працює у фоні та відновлюється після перезавантаження. Жоден із них не зможе віддавати ваш локальний застосунок, поки сам ноутбук офлайн. Тунель можна тримати запущеним днями, і він працюватиме рівно доти, доки не закриється кришка або ви не впретеся в ліміт запитів.
Тунель — правильний інструмент для демо і неправильний для хостингу: його аптайм дорівнює аптайму вашого ноутбука.
Нехай застосунок покине вашу машину
Це перший шлях, на якому ваш ноутбук перестає бути опорою, і перший, де умови важливіші за інструменти. Закінчує все тут не таймер. Це присипляння, скидання файлової системи або тариф, який вирішив, що ваш застосунок — не те, що він хоче бачити на безкоштовному інстансі.
Варіанти нижче — від постійних безкоштовних тарифів до коротких пробних періодів. Одні можуть тримати застосунок онлайн безстроково в межах своїх лімітів; інші зупиняються після фіксованого пробного періоду або вимагають платний обліковий запис за обчислення. Перевірте правила оплати, сну і зберігання перед розгортанням.
Умови безкоштовних тарифів нижче звірено зі сторінками цін або документації кожного провайдера 7 вересня 2026 року.
| Поставщик | Комерційне використання? | Чи переживають дані перезапуск? | Підступ |
|---|---|---|---|
| Netlify | Дозволено | Так, з Netlify Blobs або Database | Картка для старту не потрібна; якщо витратити всі місячні кредити тарифу Free, проєкти ставляться на паузу до наступного розрахункового періоду, якщо не перейти на платний тариф |
| Render | Не зазначено | Втрачаються при перезапуску | Картка для старту не потрібна; засинає після 15 хвилин простою; безкоштовний Postgres спливає через 30 днів після створення |
| Cloudflare Pages / Workers | Не зазначено | Так, з KV, D1, R2 або Durable Objects | 500 збірок Pages на місяць; безкоштовний Workers обмежений 100 000 запитами на день |
| Vercel | Не на Hobby | Втрачаються при перезапуску | Hobby лише для особистого використання; файлова система функцій доступна лише для читання |
| GitHub Pages | Заборонено | Лише статичний результат | Жодного онлайн-бізнесу, e-commerce чи комерційного SaaS; таймаут розгортання 10 хвилин |
| PythonAnywhere | Не зазначено | Так | Безкоштовні облікові записи сягають лише білого списку зовнішніх хостів; безкоштовний вебзастосунок спливає через місяць , якщо його не продовжити |
| Fly.io | Не зазначено | Так, з Fly Volume | Постійного безкоштовного тарифу немає: 2 машино-години або 7 днів; пробні Machines автоматично зупиняються через 5 хвилин роботи, а пробний період включає 20 ГБ сховища на томах; після завершення пробного періоду застосунки зупиняються, доки ви не додасте картку |
| Koyeb | Не зазначено | Немає постійного локального сховища | Потрібна картка; Koyeb робить і скасовує предавторизацію на 29 $, але під час реєстрації за замовчуванням обрано Pro, і його пропорційна вартість списується, якщо не перемкнутися на Starter |
| Hugging Face Spaces | Не зазначено | Втрачаються при перезапуску | Static Spaces безкоштовні; Gradio і Docker загалом вимагають платного тарифу, але відповідні безкоштовні особисті облікові записи можуть розміщувати до двох Gradio Spaces на ZeroGPU |
| Railway | Не зазначено | Так, якщо застосунок використовує включений том на 0,5 ГБ | 30-денний пробний період із разовим кредитом 5 $, потім тариф Free за 0 $ з 1 $ кредиту на ресурси на місяць; картка не потрібна |
«Не вказано» означає, що власні сторінки провайдера не відповідають на це питання для безкоштовного тарифу. Вважайте це невідомим, а не «так» чи «ні».
Три з цих рядків заслуговують на окремий погляд перед стартом. У Fly.io немає постійного безкоштовного тарифу: пробний період закінчується через 2 машино-години або 7 днів. У Koyeb є безкоштовний інстанс, але процес реєстрації та оплати потребує уваги перед розгортанням. Hugging Face залишає Static Spaces безкоштовними, тоді як нові Gradio- і Docker-Spaces вимагають платного облікового запису, за винятком обмеженого винятку ZeroGPU. Railway більше не місце в цьому списку попереджень: після 30-денного пробного періоду з 5 $ кредиту він тепер переходить на тариф Free за 0 $ з 1 $ кредиту на ресурси на місяць.
Далі постає питання даних — саме тут робочий застосунок непомітно перетворюється на зламаний. Безкоштовні вебсервіси Render працюють на ефемерній файловій системі, і документація каже прямо: усе, що туди записано, включно із завантаженими зображеннями та локальними базами SQLite, втрачається при кожному повторному розгортанні, перезапуску та присиплянні. Функції Vercel працюють на файловій системі лише для читання з одним лише тимчасовим робочим простором, тож файл SQLite, який пише ваш застосунок, там теж не в безпеці. Якщо застосунок зберігає стан у файлі, перенесіть його в надійне сховище: керовану базу даних, об'єктне сховище або постійний том там, де платформа його пропонує.
Присипляння варто відчути до того, як ви на щось підпишетеся. На безкоштовному тарифі Render 15 хвилин простою відправляють сервіс спати, а наступний запит будить його приблизно за хвилину, показуючи сторінку завантаження тому, хто клікнув по вашому посиланню. Для портфоліо — знизати плечима. Для клієнта, який відкриває посилання під час дзвінка, — шістдесят дуже поганих секунд.
У PythonAnywhere пастка тонша. Присипляння через простій немає, але безкоштовний вебзастосунок спливає через місяць і зупиняється, якщо не клікнути по посиланню продовження, яке PythonAnywhere надсилає на пошту, а безкоштовні облікові записи отримують обмежений вихідний доступ до інтернету і сягають лише білого списку зовнішніх хостів. Застосунок, який викликає API поза цим списком, стоїть собі повністю онлайн і провалює кожен запит до цього недозволеного API (жахливо налагоджувати, бо ніде нічого не виглядає таким, що впало).
Випустіть його як статичний сайт
Якщо ніщо з того, що робить застосунок, не вимагає серверного коду в момент запиту, статичний хостинг тут найближчий до «налаштував і забув»: він може залишатися онлайн без вашого ноутбука, і там немає процесу застосунку, який чекає на пробудження. Обліковий запис і ліміти хостингу досі діють. Придатних застосунків більше, ніж здається, тому на перше з тих трьох питань варто відповісти до того, як вирішувати, що вам потрібен серверний хостинг.
Правило вужче, ніж «чи є в нього бекенд». Застосунок підходить, якщо кожен його запит іде або до ваших статичних файлів, або напряму з браузера в чужий API. Звертатися до Supabase чи публічного API з браузера нормально, з одним застереженням: ключ у коді браузера — це ключ, який ви опублікували. Двері зачиняє потреба виконувати ваш власний код на сервері при кожному запиті.
Якщо підходить, схема коротка:
npm run build # Vite writes to dist/, a Next.js static export writes to out/
Потім розгорніть результат збірки на статичному хостингу. Cloudflare Pages, Netlify і Vercel уміють збирати з підключеного репозиторію. GitHub Pages може публікувати статичні файли з гілки або використовувати GitHub Actions, щоб запустити збірку вашого фреймворку й розгорнути згенерований результат.
У GitHub Pages обмеження досить жорсткі, щоб враховувати їх від самого початку. Лише статика, один користувацький або організаційний сайт на обліковий запис, і умови використання, де сказано, що це не безкоштовний хостинг для бізнесу, e-commerce-сайту чи комерційного SaaS. Якщо застосунок прийматиме платежі, це виключає його ще до початку.
У цього шляху немає закінчення процесу застосунку. Він далі працює, поки обліковий запис хостингу активний і в межах лімітів, і перестає підходити, щойно застосунку потрібна серверна робота в момент запиту.
Де закінчуються безкоштовні шляхи
Безкоштовні шляхи ламаються в різних місцях, а не всі одразу. Статичний хостинг уже вирішує питання аптайму ноутбука і дає стабільний URL провайдера. Безкоштовний хостинг застосунків може те саме, а деякі тепер включають постійне сховище. VPS починає мати сенс, коли вимоги накопичуються: ваш власний серверний процес має залишатися онлайн, потрібне передбачуване постійне сховище, а правила ресурсів чи використання безкоштовного тарифу більше не підходять.
Цей поріг варто поважати. Одне демо — не привід купувати сервер, як і статичний проєкт із низьким трафіком. Залишайтеся на тунелі для короткого шерингу, на статичному хостингу — поки застосунок справді статичний, і на безкоштовному хостингу застосунків — поки його ліміти відповідають тому, що ви запускаєте.
Переходьте на VPS, коли вам потрібен постійно працюючий сервер під вашим контролем і ви готові взяти на себе супутню експлуатаційну роботу. Наш Linux VPS — один із варіантів, і порівнянний VPS в іншого провайдера впорається з тим самим завданням. Підбирайте сервер під застосунок, а не розраховуйте, що вистачить найменшого тарифу.
Розробляйте на Linux VPS з root-доступом, NVMe та потужністю AMD EPYC.
Переглянути тарифи LinuxПісля цього змінюються дві речі. Робочий процес розгортання «push у git», який давав платформний хостинг, більше не автоматичний. Його можна відтворити за допомогою self-hosted PaaS на кшталт Coolify або Dokkuабо побудувати власний CI/CD-шлях, і в будь-якому разі оновлення та обслуговування тепер на вас.
Друга зміна: на машині живе не лише застосунок. Вона з радістю запускатиме Code Server і Claude Code , якщо ви волієте, щоб там жив і ваш редактор, що є або приємним бонусом, або цілими новими вихідними — залежить від вас.
Часті запитання
Чому мій публічний URL перестав працювати після того, як я закрив ноутбук?
Бо тунель був прив'язаний до процесу, який його створив, а не до застосунку. Закриття ноутбука або завершення термінала зупиняє цей процес, публічний URL помирає, а із застосунком усе гаразд. Перезапуск тунелю дає новий URL, якщо тільки інструмент не видає вам зарезервований домен. Якщо посилання має пережити сон ноутбука, застосунок має покинути вашу машину.
Чи потрібне доменне ім'я, щоб вивести локальний застосунок на публічний URL?
Ні, майже в усіх випадках. Швидкий тунель Cloudflare, виданий ngrok домен для розробки, localtunnel, localhost.run і безкоштовні тарифи хостингу вище безкоштовно видають вам піддомен на своєму домені. Виняток — іменований тунель Cloudflare, якому потрібен домен, уже доданий у Cloudflare DNS.
Чи може хтось з іншої Wi-Fi-мережі відкрити мою локальну IP-адресу?
Ні. Адреса на кшталт 192.168.1.42 вказує на той пристрій, якому вона дісталася в мережі, до якої ви зараз підключені, а в будь-якій іншій мережі це інший пристрій або взагалі нічого. Будь-кому поза вашим Wi-Fi потрібен тунель, безкоштовний тариф хостингу або статичний хостинг.
Що з цього працює, якщо в застосунку є вхід і база даних?
Шляхи «одна мережа» і «тунель» працюють без змін, бо застосунок досі запущений на вашій машині. Статичне розгортання теж може працювати, якщо запити входу й бази даних ідуть напряму з браузера до розміщеного сервісу і для жодного запиту не треба виконувати приватний серверний код. Якщо вашому власному коду автентифікації або бази даних потрібен сервер у момент запиту, використовуйте серверний хостинг. На безкоштовному хостингу застосунків тримайте постійні дані в надійному сховищі, а не розраховуйте, що локальна файлова система застосунку вціліє.

Обговорення
Коментарі
Увійдіть, щоб долучитися до обговорення.