# OmniRoute Fly.io Deployment Guide (Bahasa Indonesia) 🌐 **Languages:** 🇺🇸 [English](../../../../ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇹 [am](../../../am/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../../ar/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇦🇿 [az](../../../az/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../../bg/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇩 [bn](../../../bn/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇦 [bs](../../../bs/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../../cs/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../../da/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../../de/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇬🇷 [el](../../../el/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../../es/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇪 [et](../../../et/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇷 [fa](../../../fa/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../../fi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../../fr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇪 [ga](../../../ga/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [gu](../../../gu/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [ha](../../../ha/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../../he/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../../hi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇷 [hr](../../../hr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../../hu/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇦🇲 [hy](../../../hy/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [ig](../../../ig/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../../it/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../../ja/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇬🇪 [ka](../../../ka/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇭 [km](../../../km/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [kn](../../../kn/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../../ko/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇹 [lt](../../../lt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇻 [lv](../../../lv/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [ml](../../../ml/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [mr](../../../mr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../../ms/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇹 [mt](../../../mt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇲 [my](../../../my/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇵 [ne](../../../ne/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../../nl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../../no/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [or](../../../or/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [pa](../../../pa/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../../phi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../../pl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../../pt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../../ro/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../../ru/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇰 [si](../../../si/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../../sk/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇮 [sl](../../../sl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇸 [sr](../../../sr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../../sv/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇪 [sw](../../../sw/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [ta](../../../ta/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [te](../../../te/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../../th/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../../tr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇰 [ur](../../../ur/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇿 [uz](../../../uz/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../../vi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [yo](../../../yo/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) --- Dokumen ini menjelaskan proses deployment OmniRoute yang sebenarnya di Fly.io, yang mencakup dua skenario: - Melakukan deployment proyek saat ini ke Fly.io untuk pertama kali - Mempublikasikan pembaruan kode berikutnya - Proyek baru yang mengikuti alur kerja deployment yang sama Panduan ini didasarkan pada konfigurasi yang telah diverifikasi dan berfungsi untuk proyek saat ini. Nama aplikasinya adalah `omniroute`. --- ## 1. Tujuan Deployment - Platform: Fly.io - Metode deployment: Publikasi langsung menggunakan `flyctl` lokal - Runtime: Menggunakan `Dockerfile` dan `fly.toml` yang sudah ada di repositori - Persistensi data: Fly Volume dipasang ke `/data` - URL akses: `https://omniroute.fly.dev/` --- ## 2. Konfigurasi Utama Proyek Saat Ini `fly.toml` di repositori saat ini telah dikonfirmasi berisi item-item utama berikut: ```toml app = 'omniroute' primary_region = 'sin' [[mounts]] source = 'data' destination = '/data' [processes] app = 'node run-standalone.mjs' [http_service] internal_port = 20128 [env] TZ = "Asia/Shanghai" HOST = "0.0.0.0" HOSTNAME = "0.0.0.0" BIND = "0.0.0.0" ``` Catatan: - `app = 'omniroute'` menentukan aplikasi Fly yang menjadi target deployment - `destination = '/data'` menentukan direktori pemasangan volume persisten - Proyek ini harus menetapkan `DATA_DIR=/data`; jika tidak, database dan kunci akan ditulis ke direktori sementara kontainer --- ## 3. Prasyarat ### 3.1 Menginstal Fly CLI Windows PowerShell: ```powershell pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex" ``` Jika skrip instalasi gagal di lingkungan Anda, Anda juga dapat mengunduh binary `flyctl` secara manual dan menambahkannya ke `PATH`. ### 3.2 Masuk ke Akun Fly Anda ```powershell flyctl auth login ``` ### 3.3 Memverifikasi Status Login ```powershell flyctl auth whoami flyctl version ``` --- ## 4. Deployment Pertama Proyek Saat Ini ### 4.1 Kloning Kode dan Masuk ke Direktori ```powershell git clone https://github.com/diegosouzapw/OmniRoute.git cd OmniRoute ``` ### 4.2 Konfirmasikan Nama Aplikasi Buka `fly.toml` dan verifikasi baris berikut: ```toml app = 'omniroute' ``` Jika Anda melakukan deployment ke aplikasi baru milik Anda sendiri, Anda dapat mengubahnya menjadi nama yang unik secara global, misalnya: ```toml app = 'omniroute-yourname' ``` Catatan: - Pastikan aplikasi yang Anda lihat di konsol sesuai dengan nilai `app` di `fly.toml` - Jika sebelumnya Anda menggunakan nama yang berbeda, seperti `oroute`, jangan tertukar dengan `omniroute` ### 4.3 Buat Aplikasi Jika aplikasi belum ada: ```powershell flyctl apps create omniroute ``` Jika Anda mengubah nama aplikasi, ganti `omniroute` dengan nama yang Anda pilih. ### 4.4 Deployment Pertama ```powershell flyctl deploy ``` --- ## 5. Parameter Wajib Proyek ini merekomendasikan untuk mengonfigurasi setidaknya parameter berikut di Fly.io. ### 5.1 Parameter yang Telah Diverifikasi Parameter berikut telah digunakan dalam deployment aktual pada aplikasi `omniroute` saat ini: - `API_KEY_SECRET` - `DATA_DIR` - `JWT_SECRET` - `MACHINE_ID_SALT` - `NEXT_PUBLIC_BASE_URL` - `OMNIROUTE_WS_BRIDGE_SECRET` (diwajibkan dalam produksi — digunakan untuk autentikasi bridge WebSocket) - `STORAGE_ENCRYPTION_KEY` ### 5.2 Tentang `INITIAL_PASSWORD` Proyek saat ini tidak menetapkan `INITIAL_PASSWORD` karena deployment ini tidak memerlukannya. Jika tidak ditetapkan: - Log startup akan menunjukkan bahwa kata sandi default adalah `CHANGEME` - Anda harus mengubah kata sandi login di pengaturan sistem sesegera mungkin setelah deployment Jika Anda ingin menginisialisasi kata sandi backend tanpa interaksi, Anda dapat menambahkannya nanti: - `INITIAL_PASSWORD` --- ## 6. Parameter yang Direkomendasikan ### 6.1 Konfigurasi Rahasia Variabel berikut direkomendasikan untuk Fly Secrets: | Variabel | Rekomendasi | Deskripsi | | ---------------------------- | ----------------------- | ---------------------------------------------------------- | | `API_KEY_SECRET` | Wajib | Digunakan untuk pembuatan dan validasi API Key | | `JWT_SECRET` | Wajib | Digunakan untuk sesi login dan penandatanganan JWT | | `OMNIROUTE_WS_BRIDGE_SECRET` | Wajib dalam produksi | Rahasia autentikasi bridge WebSocket | | `STORAGE_ENCRYPTION_KEY` | Sangat direkomendasikan | Mengenkripsi informasi koneksi sensitif saat disimpan | | `MACHINE_ID_SALT` | Direkomendasikan | Menghasilkan pengidentifikasi mesin yang stabil | | `INITIAL_PASSWORD` | Opsional | Menetapkan kata sandi backend awal saat deployment pertama | | Kredensial privat OAuth/API | Sesuai kebutuhan | Konfigurasi autentikasi platform eksternal | ### 6.2 Nilai yang Direkomendasikan untuk Proyek Saat Ini | Variabel | Nilai yang Direkomendasikan | | ---------------------- | --------------------------- | | `DATA_DIR` | `/data` | | `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` | Catatan: - `DATA_DIR=/data` sangat penting dan harus sesuai dengan titik mount Fly Volume - `NEXT_PUBLIC_BASE_URL` digunakan oleh scheduler, callback frontend, dan skenario serupa ### 6.3 Konfigurasi URL Callback OAuth Jika Anda perlu mengaktifkan penyedia berbasis OAuth (misalnya Antigravity, Gemini, Cursor) pada deployment Fly.io, pastikan dua hal berikut: 1. **Tetapkan `NEXT_PUBLIC_BASE_URL` ke domain HTTPS publik Anda** ```powershell flyctl secrets set NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev -a omniroute ``` Jika Anda menggunakan domain kustom, ganti dengan domain yang sesuai (misalnya `https://omniroute.yourdomain.com`). 2. **Konfigurasikan URL callback pada konsol penyedia** Semua penyedia OAuth menggunakan satu path callback yang sama, yaitu `/callback` — TIDAK ada rute callback per penyedia: ```text /callback ``` Sebagai contoh, baik untuk Gemini, Antigravity, Cursor, maupun GitLab Duo: - `https://omniroute.fly.dev/callback` Jika `NEXT_PUBLIC_BASE_URL` tidak cocok dengan URL callback yang terdaftar pada penyedia, alur OAuth akan gagal pada langkah pengalihan browser. --- ## 7. Penyiapan Rahasia dengan Satu Perintah Perintah berikut menghasilkan nilai acak yang aman dan menuliskan semua parameter yang diperlukan untuk proyek saat ini ke Fly Secrets dalam satu langkah. Catatan: - Tidak menyertakan `INITIAL_PASSWORD` - Ditujukan untuk proyek `omniroute` saat ini ```powershell $apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $storageKey = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $wsBridgeSecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() flyctl secrets set ` API_KEY_SECRET=$apiKeySecret ` JWT_SECRET=$jwtSecret ` MACHINE_ID_SALT=$machineIdSalt ` STORAGE_ENCRYPTION_KEY=$storageKey ` OMNIROUTE_WS_BRIDGE_SECRET=$wsBridgeSecret ` DATA_DIR=/data ` NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev ` -a omniroute ``` Pada Linux / macOS, Anda juga dapat menggunakan `openssl rand -hex 32`: ```bash flyctl secrets set OMNIROUTE_WS_BRIDGE_SECRET=$(openssl rand -hex 32) -a omniroute ``` Catatan: - `OMNIROUTE_WS_BRIDGE_SECRET` wajib dalam produksi; jika tidak tersedia, handshake bridge WebSocket akan gagal Jika Anda juga ingin menetapkan kata sandi awal: ```powershell flyctl secrets set INITIAL_PASSWORD=your-strong-password -a omniroute ``` --- ## 8. Melihat Parameter Saat Ini ```powershell flyctl secrets list -a omniroute ``` Jika halaman `Secrets` di konsol tidak menampilkan variabel yang diharapkan, periksa: - Bahwa Anda sedang melihat aplikasi `omniroute` - Bahwa nilai `app` di `fly.toml` sesuai dengan aplikasi di konsol --- ## 9. Pembaruan dan Rilis Berikutnya Setelah pembaruan kode, proses rilis dapat dilakukan dengan mudah: ```powershell git pull flyctl deploy ``` Jika Anda hanya perlu memperbarui parameter tanpa mengubah kode: ```powershell flyctl secrets set KEY=value -a omniroute ``` Fly akan secara otomatis melakukan pembaruan mesin secara bertahap. ### 9.1 Melacak Pembaruan Repositori Upstream Sambil Mempertahankan `fly.toml` Milik Fork Anda Jika repositori saat ini merupakan sebuah fork dan Anda ingin menyinkronkan pembaruan dari upstream `https://github.com/diegosouzapw/OmniRoute`, ikuti alur kerja di bawah ini. Pertama, verifikasi remote Anda: ```powershell git remote -v ``` Anda setidaknya akan melihat: - `origin` yang mengarah ke fork Anda sendiri - `upstream` yang mengarah ke repositori asli Jika `upstream` belum dikonfigurasi, tambahkan: ```powershell git remote add upstream https://github.com/diegosouzapw/OmniRoute.git ``` Sebelum menyinkronkan dengan upstream, ambil commit dan tag terbaru: ```powershell git fetch upstream --tags ``` Periksa versi saat ini dan tag upstream: ```powershell git describe --tags --always git show --no-patch --oneline v3.4.7 ``` > Catatan: Versi proyek saat ini adalah `v3.8.0`. Referensi `v3.4.7` di bawah ini dipertahankan hanya sebagai contoh historis. Untuk rilis aktual, gunakan `:latest` atau tag versi saat ini (misalnya `:v3.8.0`). Jika Anda ingin menggabungkan `main` upstream terbaru sambil secara paksa mempertahankan `fly.toml` milik fork Anda, ikuti alur kerja ini: ```powershell git merge upstream/main git checkout HEAD~1 -- fly.toml git add -- fly.toml git commit -m "chore(deploy): keep fork fly.toml" git push origin main ``` Catatan: - `git merge upstream/main` menyinkronkan kode terbaru dari repositori asli - `git checkout HEAD~1 -- fly.toml` memulihkan `fly.toml` milik fork Anda dari kondisi sebelum penggabungan - Jika upstream tidak mengubah `fly.toml`, langkah ini tidak akan menimbulkan perbedaan apa pun - Jika upstream mengubah `fly.toml`, langkah ini memastikan nama aplikasi Fly, pemasangan volume, region, dan konfigurasi deployment khusus fork lainnya tidak ditimpa Jika Anda ingin menyelaraskan dengan tag rilis tertentu (misalnya `v3.4.7`), verifikasi terlebih dahulu bahwa tag tersebut sudah disertakan dalam `upstream/main`: ```powershell git merge-base --is-ancestor v3.4.7 upstream/main ``` Hasil yang berhasil berarti `upstream/main` sudah berisi versi tersebut; Anda cukup menggabungkan `upstream/main`. ### 9.2 Urutan Rilis Standar Setelah Menyinkronkan Upstream Setelah menyinkronkan dengan repositori asli, ikuti urutan rilis yang direkomendasikan berikut: 1. `git fetch upstream --tags` 2. `git merge upstream/main` 3. Pulihkan `fly.toml` milik fork 4. `git push origin main` 5. `flyctl deploy` 6. `flyctl status -a omniroute` 7. `flyctl logs --no-tail -a omniroute` Ini adalah alur kerja aktual yang digunakan saat meningkatkan proyek saat ini ke `v3.4.7` (contoh tersebut merujuk pada versi historis; versi aktual saat ini adalah `v3.8.0`). --- ## 10. Pemeriksaan Setelah Deployment ### 10.1 Periksa Status Aplikasi ```powershell flyctl status -a omniroute ``` ### 10.2 Lihat Log Startup ```powershell flyctl logs --no-tail -a omniroute ``` ### 10.3 Verifikasi Aksesibilitas Situs ```powershell try { (Invoke-WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).StatusCode } catch { if ($_.Exception.Response) { $_.Exception.Response.StatusCode.value__ } else { throw } } ``` Nilai kembalian `200` menunjukkan bahwa situs merespons secara normal. --- ## 11. Indikator Keberhasilan Setelah deployment berhasil, log seharusnya menampilkan konten yang serupa dengan: ```text [bootstrap] Secrets persisted to: /data/server.env [DB] SQLite database ready: /data/storage.sqlite ``` Kedua poin berikut sangat penting: - `/data/server.env` mengonfirmasi bahwa secret runtime ditulis ke volume persisten - `/data/storage.sqlite` mengonfirmasi bahwa basis data ditulis ke volume persisten Jika Anda melihat `/app/data/...`, berarti `DATA_DIR` salah dikonfigurasi dan harus segera diperbaiki. --- ## 12. Masalah Umum ### 12.1 Halaman `Secrets` Kosong Biasanya ada dua penyebab: - Anda belum menjalankan `flyctl secrets set` - Anda sedang melihat aplikasi yang berbeda (misalnya `oroute`, bukan `omniroute`) ### 12.2 `flyctl deploy` Melaporkan `app not found` Buat aplikasinya terlebih dahulu: ```powershell flyctl apps create omniroute ``` ### 12.3 Penguraian `fly.toml` Gagal Periksa hal-hal berikut: - Apakah ada karakter yang rusak dalam komentar - Apakah tanda kutip dan indentasi TOML sudah benar ### 12.4 Data Tidak Tersimpan Secara Persisten Verifikasi kedua hal berikut: - `fly.toml` berisi `destination = '/data'` - `DATA_DIR` diatur ke `/data` ### 12.5 Apakah Dapat Berjalan Tanpa `INITIAL_PASSWORD`? Ya, aplikasi dapat berjalan. Aplikasi akan menggunakan kata sandi default `CHANGEME`. Sebaiknya ubah kata sandi backend sesegera mungkin di lingkungan produksi. --- ## 13. Menggunakan Kembali untuk Proyek Baru Jika Anda men-deploy proyek baru dengan mengikuti dokumen ini, Anda hanya perlu mengubah item-item berikut: 1. Ubah nilai `app` di `fly.toml` 2. Ubah `NEXT_PUBLIC_BASE_URL` 3. Pertahankan `DATA_DIR=/data` 4. Buat ulang `API_KEY_SECRET`, `JWT_SECRET`, `MACHINE_ID_SALT`, dan `STORAGE_ENCRYPTION_KEY` 5. Setelah deployment pertama, verifikasi bahwa log ditulis ke `/data` Jangan gunakan kembali kunci dari proyek sebelumnya. --- ## 14. Daftar Periksa Rilis Minimal untuk Proyek Saat Ini Perintah yang paling umum digunakan untuk rilis berikutnya adalah: ```powershell flyctl auth whoami flyctl status -a omniroute flyctl secrets list -a omniroute flyctl deploy flyctl logs --no-tail -a omniroute ``` Untuk rilis normal, perintah utamanya cukup: ```powershell flyctl deploy ``` Untuk deployment pertama kali di lingkungan baru, langkah-langkah utamanya adalah: 1. `flyctl auth login` 2. `flyctl apps create omniroute` 3. `flyctl secrets set ... -a omniroute` 4. `flyctl deploy` 5. `flyctl logs --no-tail -a omniroute`