Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .env.docker-lightweight.example
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ NODE_ENV=production
# [REQUIRED] Public URL for the application
NEXT_PUBLIC_URL=http://localhost:3002

# Self-hosted checker and workflows routing.
UPSTASH_REDIS_REST_URL=http://redis-http:80
UPSTASH_REDIS_REST_TOKEN=replace-with-a-long-random-secret
CHECKER_BASE_URL=http://checker:8080
CHECKER_REGION=ams
WORKFLOWS_BASE_URL=http://workflows:3000
OPENSTATUS_WORKFLOWS_URL=http://workflows:3000
OPENSTATUS_INGEST_URL=http://server:3000



# DEVELOPMENT & TESTING
Expand Down
26 changes: 12 additions & 14 deletions .env.docker.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ DATABASE_AUTH_TOKEN=

# REDIS & QUEUE
# ============================================================================
# Redis (optional) - for caching
UPSTASH_REDIS_REST_URL=http://localhost:6379
UPSTASH_REDIS_REST_TOKEN=placeholder
# Self-hosted Redis REST shim used by workflows/dashboard/server.
UPSTASH_REDIS_REST_URL=http://redis-http:80
UPSTASH_REDIS_REST_TOKEN=replace-with-a-long-random-secret

# QStash (optional - for background jobs)
QSTASH_CURRENT_SIGNING_KEY=
Expand Down Expand Up @@ -62,15 +62,7 @@ AUTH_GITHUB_SECRET=
AUTH_GOOGLE_ID=
AUTH_GOOGLE_SECRET=

# GOOGLE CLOUD
# ============================================================================
# Google Cloud Platform (optional - for scheduled tasks)
GCP_PROJECT_ID=your-value
GCP_LOCATION=your-value
GCP_CLIENT_EMAIL=your-value
GCP_PRIVATE_KEY=your-value

# Cron secret for scheduled jobs
# Cron secret for scheduled jobs and checker callbacks.
CRON_SECRET=your-random-cron-secret

# API KEYS
Expand Down Expand Up @@ -133,11 +125,17 @@ NODE_ENV=production
# [REQUIRED] Public URL for the application
NEXT_PUBLIC_URL=http://localhost:3002

# Self-hosted checker and workflows routing.
CHECKER_BASE_URL=http://checker:8080
CHECKER_REGION=ams
WORKFLOWS_BASE_URL=http://workflows:3000

# Screenshot service (optional)
SCREENSHOT_SERVICE_URL=

# External services
OPENSTATUS_INGEST_URL=https://openstatus-private-location.fly.dev
# Private-location and checker callbacks stay on the internal Docker network.
OPENSTATUS_WORKFLOWS_URL=http://workflows:3000
OPENSTATUS_INGEST_URL=http://server:3000

# DEVELOPMENT & TESTING
# ============================================================================
Expand Down
37 changes: 35 additions & 2 deletions apps/checker/checker/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"strings"

Expand All @@ -27,10 +28,42 @@ type UpdateData struct {
}

func UpdateStatus(ctx context.Context, updateData UpdateData) error {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cloudProvider := env("CLOUD_PROVIDER", "fly")

We should do something like this instead

url := "https://openstatus-workflows.fly.dev/updateStatus"
url := os.Getenv("OPENSTATUS_WORKFLOWS_URL")
if url == "" {
url = "https://openstatus-workflows.fly.dev"
}
url = strings.TrimRight(url, "/") + "/updateStatus"
basic := "Basic " + os.Getenv("CRON_SECRET")
payloadBuf := new(bytes.Buffer)

if os.Getenv("SELF_HOST") == "true" || os.Getenv("OPENSTATUS_WORKFLOWS_URL") != "" {
if err := json.NewEncoder(payloadBuf).Encode(updateData); err != nil {
log.Ctx(ctx).Error().Err(err).Msg("error while encoding update payload")
return err
}

req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, payloadBuf)
if err != nil {
log.Ctx(ctx).Error().Err(err).Msg("error while creating update request")
return err
}
req.Header.Set("Authorization", basic)
req.Header.Set("Content-Type", "application/json")

res, err := http.DefaultClient.Do(req)
if err != nil {
log.Ctx(ctx).Error().Err(err).Msg("error while posting update status directly")
return err
}
defer res.Body.Close()

if res.StatusCode < 200 || res.StatusCode >= 300 {
return fmt.Errorf("direct updateStatus failed with status %d", res.StatusCode)
}

return nil
}
Comment on lines 37 to +65

c := os.Getenv("GCP_PRIVATE_KEY")
c = strings.ReplaceAll(c, "\\n", "\n")
opts := &auth.Options2LO{
Expand Down
15 changes: 15 additions & 0 deletions apps/server/src/libs/checker/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import {
transformHeaders,
} from "@openstatus/utils";

function isSelfHost() {
return process.env.SELF_HOST === "true";
}

function getCheckerBaseUrl() {
return (process.env.CHECKER_BASE_URL || "http://checker:8080").replace(
/\/$/,
"",
);
}

export function getCheckerPayload(
monitor: z.infer<typeof selectMonitorSchema>,
status: z.infer<typeof selectMonitorSchema>["status"],
Expand Down Expand Up @@ -72,6 +83,10 @@ export function getCheckerUrl(
data: false,
},
): string {
if (isSelfHost()) {
return `${getCheckerBaseUrl()}/checker/${monitor.jobType}?monitor_id=${monitor.id}&trigger=${opts.trigger}&data=${opts.data}`;
}

switch (monitor.jobType) {
case "http":
return `https://openstatus-checker.fly.dev/checker/http?monitor_id=${monitor.id}&trigger=${opts.trigger}&data=${opts.data}`;
Expand Down
27 changes: 25 additions & 2 deletions apps/server/src/routes/v1/check/http/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@ import {
ResponseSchema,
} from "./schema";

function isSelfHost() {
return process.env.SELF_HOST === "true";
}

function getCheckerBaseUrl() {
return (process.env.CHECKER_BASE_URL || "http://checker:8080").replace(
/\/$/,
"",
);
}

function getCheckerRegion(region: string) {
if (!isSelfHost()) {
return region;
}

return process.env.CHECKER_REGION || "ams";
}

const postRoute = createRoute({
method: "post",
tags: ["check"],
Expand Down Expand Up @@ -69,11 +88,15 @@ export function registerHTTPPostCheck(api: typeof checkApi) {
for (let count = 0; count < input.runCount; count++) {
const currentFetch = [];
for (const region of input.regions) {
const r = fetch(`https://openstatus-checker.fly.dev/ping/${region}`, {
const targetRegion = getCheckerRegion(region);
const targetUrl = isSelfHost()
? `${getCheckerBaseUrl()}/ping/${targetRegion}`
: `https://openstatus-checker.fly.dev/ping/${targetRegion}`;
const r = fetch(targetUrl, {
headers: {
Authorization: `Basic ${env.CRON_SECRET}`,
"Content-Type": "application/json",
"fly-prefer-region": region,
...(isSelfHost() ? {} : { "fly-prefer-region": targetRegion }),
},
method: "POST",
body: JSON.stringify({
Expand Down
Loading