Openstatus www.openstatus.dev

πŸš€ Add railway (#1421)

* 🌐

* 🌐

* πŸ”₯

* πŸ”₯

* ci: apply automated fixes

* 🌐

* πŸš€

* πŸ”₯

* πŸ”₯

* πŸ”₯

* ci: apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

authored by

Thibault Le Ouay
autofix-ci[bot]
and committed by
GitHub
0935d8dc d14bafb7

+355 -1
+33
apps/dashboard/src/data/regions.ts
··· 283 283 continent: "North America", 284 284 provider: "koyeb", 285 285 }, 286 + { 287 + code: "railway_us-west2", 288 + location: "California, USA", 289 + flag: "πŸ‡ΊπŸ‡Έ", 290 + continent: "North America", 291 + provider: "railway", 292 + }, 293 + { 294 + code: "railway_us-east4-eqdc4a", 295 + location: "Virginia, USA", 296 + flag: "πŸ‡ΊπŸ‡Έ", 297 + continent: "North America", 298 + provider: "railway", 299 + }, 300 + { 301 + code: "railway_europe-west4-drams3a", 302 + location: "Amsterdam, Netherlands", 303 + flag: "πŸ‡³πŸ‡±", 304 + continent: "Europe", 305 + provider: "railway", 306 + }, 307 + { 308 + code: "railway_asia-southeast1-eqsg3a", 309 + location: "Singapore, Singapore", 310 + flag: "πŸ‡ΈπŸ‡¬", 311 + continent: "Asia", 312 + provider: "railway", 313 + }, 286 314 ] as const; 287 315 288 316 export type Region = (typeof regions)[number]["code"]; ··· 342 370 koyeb_sfo: "hsl(0 0% 45.1%)", 343 371 koyeb_tyo: "hsl(0 0% 45.1%)", 344 372 koyeb_was: "hsl(0 0% 45.1%)", 373 + 374 + "railway_asia-southeast1-eqsg3a": "hsl(0 0% 45.1%)", 375 + "railway_europe-west4-drams3a": "hsl(0 0% 45.1%)", 376 + "railway_us-east4-eqdc4a": "hsl(0 0% 45.1%)", 377 + "railway_us-west2": "hsl(0 0% 45.1%)", 345 378 } satisfies Record<Region, string>;
+19
apps/railway-proxy/Dockerfile
··· 1 + FROM golang:1.25-alpine 2 + 3 + # Set the working directory 4 + WORKDIR /app 5 + 6 + # Copy go.mod and go.sum files (if they exist) 7 + COPY go.mod ./ 8 + 9 + # Copy the source code 10 + COPY . . 11 + 12 + # Build the application 13 + RUN go build -o main . 14 + 15 + # Expose the port your app runs on 16 + EXPOSE 8080 17 + 18 + # Run the application 19 + CMD ["./main"]
+43
apps/railway-proxy/go.mod
··· 1 + module github.com/openstatushq/openstatus/apps/railway-proxy 2 + 3 + go 1.25.1 4 + 5 + require ( 6 + github.com/gin-gonic/gin v1.11.0 7 + github.com/rs/zerolog v1.34.0 8 + ) 9 + 10 + require ( 11 + github.com/bytedance/sonic v1.14.0 // indirect 12 + github.com/bytedance/sonic/loader v0.3.0 // indirect 13 + github.com/cloudwego/base64x v0.1.6 // indirect 14 + github.com/gabriel-vasile/mimetype v1.4.8 // indirect 15 + github.com/gin-contrib/sse v1.1.0 // indirect 16 + github.com/go-playground/locales v0.14.1 // indirect 17 + github.com/go-playground/universal-translator v0.18.1 // indirect 18 + github.com/go-playground/validator/v10 v10.27.0 // indirect 19 + github.com/goccy/go-json v0.10.2 // indirect 20 + github.com/goccy/go-yaml v1.18.0 // indirect 21 + github.com/json-iterator/go v1.1.12 // indirect 22 + github.com/klauspost/cpuid/v2 v2.3.0 // indirect 23 + github.com/leodido/go-urn v1.4.0 // indirect 24 + github.com/mattn/go-colorable v0.1.13 // indirect 25 + github.com/mattn/go-isatty v0.0.20 // indirect 26 + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 27 + github.com/modern-go/reflect2 v1.0.2 // indirect 28 + github.com/pelletier/go-toml/v2 v2.2.4 // indirect 29 + github.com/quic-go/qpack v0.5.1 // indirect 30 + github.com/quic-go/quic-go v0.54.0 // indirect 31 + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 32 + github.com/ugorji/go/codec v1.3.0 // indirect 33 + go.uber.org/mock v0.5.0 // indirect 34 + golang.org/x/arch v0.20.0 // indirect 35 + golang.org/x/crypto v0.40.0 // indirect 36 + golang.org/x/mod v0.25.0 // indirect 37 + golang.org/x/net v0.42.0 // indirect 38 + golang.org/x/sync v0.16.0 // indirect 39 + golang.org/x/sys v0.35.0 // indirect 40 + golang.org/x/text v0.27.0 // indirect 41 + golang.org/x/tools v0.34.0 // indirect 42 + google.golang.org/protobuf v1.36.9 // indirect 43 + )
+100
apps/railway-proxy/go.sum
··· 1 + github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= 2 + github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= 3 + github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= 4 + github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= 5 + github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= 6 + github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= 7 + github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 8 + github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 9 + github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 10 + github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 11 + github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= 12 + github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= 13 + github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= 14 + github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= 15 + github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= 16 + github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= 17 + github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= 18 + github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 19 + github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 20 + github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 21 + github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 22 + github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 23 + github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= 24 + github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= 25 + github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= 26 + github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 27 + github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= 28 + github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= 29 + github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 30 + github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 31 + github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 32 + github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 33 + github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 34 + github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 35 + github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= 36 + github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= 37 + github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= 38 + github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 39 + github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 40 + github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 41 + github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 42 + github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 43 + github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 44 + github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 45 + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 46 + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 47 + github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 48 + github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 49 + github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= 50 + github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= 51 + github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 52 + github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 53 + github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 54 + github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= 55 + github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= 56 + github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= 57 + github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= 58 + github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= 59 + github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= 60 + github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= 61 + github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 62 + github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 63 + github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 64 + github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 65 + github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 66 + github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 67 + github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 68 + github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= 69 + github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 70 + github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 71 + github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 72 + github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= 73 + github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= 74 + go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= 75 + go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= 76 + golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= 77 + golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= 78 + golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= 79 + golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= 80 + golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= 81 + golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 82 + golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= 83 + golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= 84 + golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= 85 + golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 86 + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 87 + golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 88 + golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 89 + golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= 90 + golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 91 + golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= 92 + golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= 93 + golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= 94 + golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= 95 + google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= 96 + google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= 97 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 98 + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 99 + gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 100 + gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+97
apps/railway-proxy/main.go
··· 1 + package main 2 + 3 + import ( 4 + "context" 5 + "errors" 6 + "fmt" 7 + "net/http" 8 + "net/http/httputil" 9 + "net/url" 10 + "os" 11 + "os/signal" 12 + "syscall" 13 + 14 + "github.com/gin-gonic/gin" 15 + "github.com/rs/zerolog/log" 16 + ) 17 + 18 + func proxy(c *gin.Context) { 19 + 20 + var targetUrl string 21 + 22 + region := c.Request.Header.Get("railway-region") 23 + 24 + switch region { 25 + case "europe-west4-drams3a": 26 + targetUrl = "http://openstatus-checker-eu-west.railway.internal:8080" 27 + case "us-east4-eqdc4a": 28 + targetUrl = "http://openstatus-checker-us-east.railway.internal:8080" 29 + case "us-west2": 30 + targetUrl = "http://openstatus-checker-us-west.railway.internal:8080" 31 + case "asia-southeast1-eqsg3a": 32 + targetUrl = "http://checker-southeast-asia.railway.internal:8080" 33 + default: 34 + fmt.Println("No region") 35 + } 36 + remote, err := url.Parse(targetUrl) 37 + if err != nil { 38 + panic(err) 39 + } 40 + 41 + proxy := httputil.NewSingleHostReverseProxy(remote) 42 + 43 + c.Request.Host = remote.Host 44 + 45 + proxy.ServeHTTP(c.Writer, c.Request) 46 + } 47 + 48 + func main() { 49 + ctx, cancel := context.WithCancel(context.Background()) 50 + defer cancel() 51 + done := make(chan os.Signal, 1) 52 + signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) 53 + 54 + go func() { 55 + <-done 56 + cancel() 57 + }() 58 + 59 + cloudProvider := env("CLOUD_PROVIDER", "railway") 60 + region := env("RAILWAY_REPLICA_REGION", env("REGION", "local")) 61 + router := gin.New() 62 + 63 + //Create a catchall route 64 + router.NoRoute(proxy) 65 + 66 + router.GET("/healthz", func(c *gin.Context) { 67 + c.JSON(http.StatusOK, gin.H{"message": "pong", "region": region, "provider": cloudProvider}) 68 + }) 69 + 70 + httpServer := &http.Server{ 71 + Addr: fmt.Sprintf("0.0.0.0:%s", env("PORT", "8080")), 72 + Handler: router, 73 + } 74 + 75 + go func() { 76 + if err := httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { 77 + log.Ctx(ctx).Error().Err(err).Msg("failed to start http server") 78 + cancel() 79 + } 80 + }() 81 + 82 + <-ctx.Done() 83 + if err := httpServer.Shutdown(ctx); err != nil { 84 + log.Ctx(ctx).Error().Err(err).Msg("failed to shutdown http server") 85 + 86 + return 87 + } 88 + 89 + } 90 + 91 + func env(key, fallback string) string { 92 + if value, ok := os.LookupEnv(key); ok { 93 + return value 94 + } 95 + 96 + return fallback 97 + }
+5
apps/web/src/app/api/checker/cron/_cron.ts
··· 224 224 if (regionInfo.provider === "koyeb") { 225 225 regionHeader = { "X-KOYEB-REGION-OVERRIDE": region.replace("koyeb_", "") }; 226 226 } 227 + if (regionInfo.provider === "railway") { 228 + regionHeader = { "railway-region": region.replace("railway_", "") }; 229 + } 227 230 const newTask: google.cloud.tasks.v2beta3.ITask = { 228 231 httpRequest: { 229 232 headers: { ··· 255 258 return `https://openstatus-checker.fly.dev/checker/${row.jobType}?monitor_id=${row.id}`; 256 259 case "koyeb": 257 260 return `https://openstatus-checker.koyeb.app/checker/${row.jobType}?monitor_id=${row.id}`; 261 + case "railway": 262 + return `https://railway-proxy-production-9cb1.up.railway.app/checker/${row.jobType}?monitor_id=${row.id}`; 258 263 259 264 default: 260 265 throw new Error("Invalid jobType");
+13
apps/web/src/components/monitor-charts/chart.tsx
··· 150 150 koyeb_sin: { label: "SIN (koyeb)", color: "hsl(0 0% 45.1%)" }, 151 151 koyeb_tyo: { label: "TYO (koyeb)", color: "hsl(0 0% 45.1%)" }, 152 152 koyeb_was: { label: "WAS (koyeb)", color: "hsl(0 0% 45.1%)" }, 153 + "railway_asia-southeast1-eqsg3a": { 154 + label: "asia-southeast1-eqsg3a (railway)", 155 + color: "hsl(0 0% 45.1%)", 156 + }, 157 + "railway_europe-west4-drams3a": { 158 + label: "europe-west4-drams3a (railway)", 159 + color: "hsl(0 0% 45.1%)", 160 + }, 161 + "railway_us-west2": { label: "us-west2 (railway)", color: "hsl(0 0% 45.1%)" }, 162 + "railway_us-east4-eqdc4a": { 163 + label: "us-east4-eqdc4a (railway)", 164 + color: "hsl(0 0% 45.1%)", 165 + }, 153 166 };
+4
apps/web/src/components/ping-response-analysis/utils.ts
··· 176 176 "X-KOYEB-REGION-OVERRIDE": region.replace("koyeb_", ""), 177 177 }; 178 178 break; 179 + case "railway": 180 + endpoint = `https://railway-proxy-production-9cb1.up.railway.app/ping/${region}`; 181 + regionHeader = { "railway-region": region.replace("railway_", "") }; 182 + break; 179 183 default: 180 184 break; 181 185 }
+13 -1
packages/db/src/schema/constants.ts
··· 47 47 "koyeb_sfo", 48 48 ] as const; 49 49 50 + export const railwayRegions = [ 51 + "railway_europe-west4-drams3a", 52 + "railway_us-east4-eqdc4a", 53 + "railway_asia-southeast1-eqsg3a", 54 + "railway_us-west2", 55 + ] as const; 56 + 50 57 export const freeFlyRegions = [ 51 58 "iad", 52 59 "ams", ··· 66 73 "other", 67 74 ] as const; 68 75 69 - export const monitorRegions = [...flyRegions, ...koyebRegions] as const; 76 + export const monitorRegions = [ 77 + ...flyRegions, 78 + ...koyebRegions, 79 + ...railwayRegions, 80 + ] as const; 81 + 70 82 export const monitorPeriodicitySchema = z.enum(monitorPeriodicity); 71 83 export const monitorRegionSchema = z.enum(monitorRegions); 72 84 export const monitorFlyRegionSchema = z.enum(flyRegions);
+28
packages/utils/index.ts
··· 444 444 continent: "North America", 445 445 provider: "koyeb", 446 446 }, 447 + "railway_us-west2": { 448 + code: "railway_us-west2", 449 + location: "California, USA", 450 + flag: "πŸ‡ΊπŸ‡Έ", 451 + continent: "North America", 452 + provider: "railway", 453 + }, 454 + "railway_us-east4-eqdc4a": { 455 + code: "railway_us-east4-eqdc4a", 456 + location: "Virginia, USA", 457 + flag: "πŸ‡ΊπŸ‡Έ", 458 + continent: "North America", 459 + provider: "railway", 460 + }, 461 + "railway_europe-west4-drams3a": { 462 + code: "railway_europe-west4-drams3a", 463 + location: "Amsterdam, Netherlands", 464 + flag: "πŸ‡³πŸ‡±", 465 + continent: "Europe", 466 + provider: "railway", 467 + }, 468 + "railway_asia-southeast1-eqsg3a": { 469 + code: "railway_asia-southeast1-eqsg3a", 470 + location: "Singapore, Singapore", 471 + flag: "πŸ‡ΈπŸ‡¬", 472 + continent: "Asia", 473 + provider: "railway", 474 + }, 447 475 } as const; 448 476 449 477 // const r = t.flatMap((u) => u[1].continent);