Repository navigation
Expand file tree
/
Copy pathconfig.example.env
More file actions
1068 lines (953 loc) · 53.9 KB
/
Copy pathconfig.example.env
File metadata and controls
1068 lines (953 loc) · 53.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env bash
# Please change this to domain of the server where oneuptime is hosted on.
HOST=localhost
PROVISION_SSL=false
# OneUptime Port. This is the port where OneUptime will be hosted on.
ONEUPTIME_HTTP_PORT=80
# ==============================================
# SETTING UP TLS/SSL CERTIFICATES
# ==============================================
# OneUptime can automatically provision SSL certificates for the HOST when PROVISION_SSL=true.
# This requires port 80/443 to be reachable for Let's Encrypt validation and the HOST domain pointing to this server.
# If you prefer to terminate TLS on an external reverse proxy, leave PROVISION_SSL=false and manage certificates yourself.
# Either way, set HTTP_PROTOCOL=https once people reach OneUptime over HTTPS. Besides building https links, it keeps
# sign-in cookies on HTTPS and tells browsers to reach HOST over HTTPS only (Strict-Transport-Security).
# Keep HTTP_PROTOCOL=http only while OneUptime is served over plain HTTP.
HTTP_PROTOCOL=http
# How long, in seconds, a browser keeps to HTTPS for HOST once an HTTP_PROTOCOL=https install has told it to: one year.
# 0 makes browsers forget it at their next HTTPS visit. Set 0 a while before HOST has to answer over plain HTTP again.
HSTS_MAX_AGE_SECONDS=31536000
# Captcha configuration
CAPTCHA_ENABLED=false
CAPTCHA_SITE_KEY=
CAPTCHA_SECRET_KEY=
# Secrets - PLEASE CHANGE THESE. Please change these to something random. All of these can be different values.
ONEUPTIME_SECRET=please-change-this-to-random-value
REGISTER_PROBE_KEY=please-change-this-to-random-value
DATABASE_PASSWORD=please-change-this-to-random-value
CLICKHOUSE_PASSWORD=please-change-this-to-random-value
VALKEY_PASSWORD=please-change-this-to-random-value
ENCRYPTION_SECRET=please-change-this-to-random-value
GLOBAL_PROBE_1_KEY=probe-1-please-change-this-to-random-value
GLOBAL_PROBE_2_KEY=probe-2-please-change-this-to-random-value
# How many reverse proxies that YOU run sit in front of OneUptime and append to
# the X-Forwarded-For header. This decides which address OneUptime treats as the
# client for IP allowlists (status pages, public dashboards) and IP rate limits.
#
# X-Forwarded-For is a list that each proxy appends its peer to, so a caller can
# put anything they like at the front of it. Only the entries our own proxies
# wrote mean anything, and those are at the END of the list. This number says how
# far in from that end the real client sits.
#
# 1 is correct for a stock install: OneUptime ships its own nginx gateway and
# nothing else touches the header.
#
# Raise it if you put your own HTTP proxy in front. A CDN or WAF that appends to
# X-Forwarded-For (Cloudflare, an AWS ALB, your own nginx or ingress controller)
# makes this 2, and each further proxy adds one. Too low and every visitor looks
# like your proxy; too high and visitors can choose the address you see, which
# defeats the allowlists.
#
# With your own proxy, OneUptime's ports must be reachable only through it, or a
# visitor who reaches them directly chooses the address you see. When the proxy
# runs on this server, publish them on the loopback address only, for example
# ONEUPTIME_HTTP_PORT=127.0.0.1:8080 and STATUS_PAGE_HTTPS_PORT=127.0.0.1:8443.
#
# 0 ignores X-Forwarded-For entirely and uses the connecting address — set this
# only if OneUptime is exposed directly with no proxy at all.
TRUSTED_PROXY_HOPS=1
# Security emails - a password reset, a changed password, wrong two factor
# codes, a backup code used - say when, from which IP address and on which
# device and browser the request came. They also say roughly where ("Berlin,
# Germany") once you name the request headers your CDN or load balancer writes
# the visitor's location into. Empty, the default, names no place.
#
# Name only headers a proxy in front of OneUptime always writes itself,
# replacing whatever the visitor sent. Any other header is the visitor's own
# writing: whoever asks for someone's password reset could choose the place
# their email shows.
#
# Behind Cloudflare, turn on "Add visitor location headers" (Rules > Settings >
# Managed Transforms) and use cf-ipcountry, cf-region and cf-ipcity. Behind
# CloudFront, forward cloudfront-viewer-country,
# cloudfront-viewer-country-region-name and cloudfront-viewer-city to the
# origin. Behind Vercel: x-vercel-ip-country, x-vercel-ip-country-region and
# x-vercel-ip-city.
TRUSTED_GEO_COUNTRY_HEADER=
TRUSTED_GEO_REGION_HEADER=
TRUSTED_GEO_CITY_HEADER=
# People who reach OneUptime over IPv6 (an AAAA record) keep their own address
# only once IPv6 is on for OneUptime's Docker network: see "Visitor addresses"
# in the Docker Compose guide (https://oneuptime.com/docs/installation/docker-compose).
# If you are connecting Status Pages to custom domains, then this will be the port where the status page will be hosted on.
# This should be https port because oneuptime automatically generates ssl certs from lets encrypt.
STATUS_PAGE_HTTPS_PORT=443
# If you would like to attach status pages to custom domains use this setting.
# For example, lets say you would like the status page to be hosted on status.yourcompany.com, then
# 1. Create a A record in your DNS provider with the name "oneuptime.yourcompany.com" and value to Public IP of the server oneuptime is deployed on.
# 2. Set the STATUS_PAGE_CNAME_RECORD to "oneuptime.yourcompany.com"
# 3. Create CNAME record in your DNS provider with the name "status.yourcompany.com" and value "oneuptime.yourcompany.com"
STATUS_PAGE_CNAME_RECORD=oneuptime.yourcompany.com
# If you would like to attach public dashboards to custom domains use this setting.
# Works the same way as STATUS_PAGE_CNAME_RECORD but for dashboards.
# For example, if you want dashboard.yourcompany.com to show a public dashboard:
# 1. Set the DASHBOARD_CNAME_RECORD to "oneuptime.yourcompany.com"
# 2. Create CNAME record in your DNS provider with the name "dashboard.yourcompany.com" and value "oneuptime.yourcompany.com"
DASHBOARD_CNAME_RECORD=oneuptime.yourcompany.com
# Forms on custom domains (a form at report.yourcompany.com) use STATUS_PAGE_CNAME_RECORD
# above: one ingress serves every custom domain. Uncomment and set this only to give
# form domains a CNAME target of their own.
# FORM_CNAME_RECORD=oneuptime.yourcompany.com
# --------------------------------------------- #
# You can safely ignore anything below this line. Keep them as default to make things work.
# --------------------------------------------- #
# This supports test | production | development | ci.
# Development is used for local development. Test is used for insider / beta / staging builds. Production is used for production ready app. ci is for testing in the CI/CD.
ENVIRONMENT=production
# What image should we pull from docker hub. This only applies when the ENVIRONMENT is production or test
# The tag also picks the edition:
# release the Community Edition (Apache-2.0), SAML and OIDC
# single sign-on included.
# enterprise-release the Enterprise Edition: the same release plus the
# enterprise features (SCIM, audit logs, team
# compliance, instance health dashboards), licensed
# under the OneUptime Enterprise License (ee/LICENSE).
# Production use requires a OneUptime Enterprise
# subscription. An install without a license runs a
# 14-day trial, which is for evaluation only. After
# the trial (or 30 days after a license expires),
# SCIM and audit logging stop and enterprise
# configuration becomes read-only, until a license is
# activated. Single sign-on does not depend on the
# license, and core monitoring is never affected.
# Pinned versions work the same way: 13.1.0 and enterprise-13.1.0.
APP_TAG=release
# DEPRECATED: the image you pull (APP_TAG above) picks the edition, not this
# variable, and setting it never turns enterprise features on. The Enterprise
# image carries ONEUPTIME_EDITION=enterprise itself, so do not set
# ONEUPTIME_EDITION here. Keep this key for older configs, but know that true
# means "this install must run the Enterprise Edition":
# - On the Community image (APP_TAG=release) the App refuses to start with
# IS_ENTERPRISE_EDITION=true, instead of silently stopping SCIM
# provisioning and audit logging. Set APP_TAG=enterprise-release
# (or enterprise-<version>) to keep the Enterprise Edition, or set this to
# false to run the Community Edition.
# - While it is true, `npm run update` moves APP_TAG to the matching
# enterprise- tag (release -> enterprise-release) and prints what it did.
IS_ENTERPRISE_EDITION=false
# What is the name of the docker compose project. This is used to prefix the docker containers.
COMPOSE_PROJECT_NAME=oneuptime
# Clickhouse Settings
CLICKHOUSE_USER=default
CLICKHOUSE_DATABASE=oneuptime
CLICKHOUSE_HOST=clickhouse
CLICKHOUSE_PORT=8123
# Per-container ClickHouse connection pool ceilings. The ingest pool (used by
# the fan-in telemetry writer) inherits CLICKHOUSE_MAX_OPEN_CONNECTIONS when
# left empty.
CLICKHOUSE_MAX_OPEN_CONNECTIONS=100
CLICKHOUSE_INGEST_MAX_OPEN_CONNECTIONS=
# Postgres DB Settings.
DATABASE_PORT=5432
DATABASE_USERNAME=postgres
DATABASE_NAME=oneuptimedb
DATABASE_HOST=postgres
# Used to connect to managed postgres providers.
# Fill only what your provider needs.
DATABASE_SSL_REJECT_UNAUTHORIZED=false
DATABASE_SSL_CA=
DATABASE_SSL_KEY=
DATABASE_SSL_CERT=
# Cache / queue settings. The bundled container is Valkey (the BSD-licensed
# fork of Redis 7.2), and any Redis-protocol server works here -- point
# VALKEY_HOST at a managed Redis if you prefer.
#
# These were named REDIS_* until 13.0.0. The old names still work: the app
# falls back to them, the compose service still answers to the hostname `redis`,
# and `npm run update` will not overwrite them. Nothing to do on upgrade.
VALKEY_HOST=valkey
VALKEY_PORT=6379
VALKEY_DB=0
VALKEY_USERNAME=default
VALKEY_IP_FAMILY=
VALKEY_TLS_CA=
VALKEY_TLS_SENTINEL_MODE=false
# Hostnames. Usually does not need to change.
SERVER_APP_HOSTNAME=app
#Ports. Usually they don't need to change.
APP_PORT=3002
TEST_SERVER_PORT=3800
HOME_PORT=1444
# Plans
# This is in the format of PlanName,PlanIdFromBillingProvider,MonthlySubscriptionPlanAmountInUSD,YearlySubscriptionPlanAmountInUSD,Order,TrialPeriodInDays
# Enterprise plan will have -1 which means custom pricing.
SUBSCRIPTION_PLAN_BASIC=Basic,priceMonthlyId,priceYearlyId,0,0,1,0
SUBSCRIPTION_PLAN_GROWTH=Growth,priceMonthlyId,priceYearlyId,0,0,2,14
SUBSCRIPTION_PLAN_SCALE=Scale,priceMonthlyId,priceYearlyId,0,0,3,0
SUBSCRIPTION_PLAN_ENTERPRISE=Enterprise,priceMonthlyId,priceYearlyId,-1,-1,4,14
# The port docker-compose.yml publishes PostgreSQL on, on this server's
# loopback address only: backup.sh, restore.sh and psql on this server reach
# it there, and nothing else on the network can. Another program holds 5400?
# Set a free port here and run npm start: the backup and restore scripts
# follow it.
DATABASE_PUBLISHED_PORT=5400
# If you want to run the backup script, then you need to fill these values.
# An empty DATABASE_BACKUP_PORT is DATABASE_PUBLISHED_PORT.
DATABASE_BACKUP_DIRECTORY=/Backups
DATABASE_BACKUP_HOST=localhost
DATABASE_BACKUP_PORT=
DATABASE_BACKUP_NAME=oneuptimedb
DATABASE_BACKUP_USERNAME=postgres
DATABASE_BACKUP_PASSWORD=${DATABASE_PASSWORD}
# If you want to run the restore script, then you need to fill these values. host.docker.internal is this
# server itself: restore.sh maps it to the loopback address PostgreSQL is published on.
# An empty DATABASE_RESTORE_PORT is DATABASE_PUBLISHED_PORT.
DATABASE_RESTORE_HOST=host.docker.internal
DATABASE_RESTORE_DIRECTORY=/Backups
DATABASE_RESTORE_PORT=
DATABASE_RESTORE_NAME=oneuptimedb
DATABASE_RESTORE_USERNAME=postgres
DATABASE_RESTORE_PASSWORD=${DATABASE_PASSWORD}
DATABASE_RESTORE_FILENAME=db-31.backup
ANALYTICS_KEY=
ANALYTICS_HOST=
# Google Tag Manager. Only ever loaded when BILLING_ENABLED=true, so a
# self-hosted install never reaches googletagmanager.com regardless of this
# value. Set to false to keep the container off even on a billing-enabled
# deployment - which is what the end-to-end suite does, so its scripted
# registrations are not reported as real sign_up conversions.
GOOGLE_TAG_MANAGER_ENABLED=true
# Google Analytics Measurement Protocol API secret (OneUptime Cloud only).
# Created in Google Analytics under Admin > Data streams > the web stream >
# Measurement Protocol API secrets. With it, a free trial that converts into a
# payment reaches Google Analytics as a purchase, sent by the server because
# no browser is present when Stripe charges the card. Empty sends nothing, and
# so does GOOGLE_TAG_MANAGER_ENABLED=false.
# See Docs/analytics/marketing-event-webhooks.md.
GOOGLE_ANALYTICS_MEASUREMENT_PROTOCOL_API_SECRET=
# Where npm run generate-postgres-migration and npm run
# check-postgres-schema-drift reach PostgreSQL from this machine. An empty
# DATABASE_MIGRATIONS_PORT is DATABASE_PUBLISHED_PORT, where the stack
# publishes it.
DATABASE_MIGRATIONS_HOST=localhost
DATABASE_MIGRATIONS_PORT=
# Global Probes
# This is in the format of GLOBAL_PROBE_NAME=ProbeName,ProbeDescription,ProbeKey
GLOBAL_PROBE_1_NAME="Probe-1"
GLOBAL_PROBE_1_DESCRIPTION="Global probe to monitor oneuptime resources"
GLOBAL_PROBE_1_MONITORING_WORKERS=5
GLOBAL_PROBE_1_MONITOR_FETCH_LIMIT=10
# How many NetworkDevice SNMP walks this probe runs at once. Empty uses the
# probe default (25). Together with NETWORK_DEVICE_POLL_FETCH_LIMIT below this
# is what sets how fast a device fleet can be polled — see that entry.
GLOBAL_PROBE_1_NETWORK_DEVICE_POLL_CONCURRENCY=
# How many SNMP OIDs this probe asks for in one GET. Empty uses the probe
# default (20). Every configured OID used to go into a single UDP datagram, so
# a long health-OID list answered tooBig and the DEVICE was reported offline;
# lower this only for an agent with an unusually small maximum message size.
GLOBAL_PROBE_1_SNMP_GET_CHUNK_SIZE=
GLOBAL_PROBE_1_ONEUPTIME_URL=http://localhost
GLOBAL_PROBE_1_SYNTHETIC_MONITOR_SCRIPT_TIMEOUT_IN_MS=60000
GLOBAL_PROBE_1_SYNTHETIC_MONITOR_MAX_CONCURRENCY=4
GLOBAL_PROBE_1_SYNTHETIC_MONITOR_MAX_PROCESS_TREE_RSS_BYTES=1610612736
GLOBAL_PROBE_1_SYNTHETIC_MONITOR_MAX_DISK_BYTES=268435456
# Size of /dev/shm for this probe's container (Docker's default is 64MB). The
# synthetic runtime's browsers do not use it: Playwright starts Chromium with
# --disable-dev-shm-usage, so Chromium keeps its shared memory in the
# per-execution run directory under /tmp, and Firefox uses memfd.
GLOBAL_PROBE_1_SHM_SIZE=512m
GLOBAL_PROBE_1_CUSTOM_CODE_MONITOR_SCRIPT_TIMEOUT_IN_MS=60000
GLOBAL_PROBE_1_PORT=3874
# (Optional) Configure HTTP and HTTPS proxy URLs independently. The legacy
# GLOBAL_PROBE_1_PROXY_URL remains a fallback for both protocols.
GLOBAL_PROBE_1_HTTP_PROXY_URL=
GLOBAL_PROBE_1_HTTPS_PROXY_URL=
GLOBAL_PROBE_1_NO_PROXY=
GLOBAL_PROBE_1_PROXY_URL=
GLOBAL_PROBE_2_NAME="Probe-2"
GLOBAL_PROBE_2_DESCRIPTION="Global probe to monitor oneuptime resources"
GLOBAL_PROBE_2_MONITORING_WORKERS=5
GLOBAL_PROBE_2_MONITOR_FETCH_LIMIT=10
GLOBAL_PROBE_2_ONEUPTIME_URL=http://localhost
GLOBAL_PROBE_2_SYNTHETIC_MONITOR_SCRIPT_TIMEOUT_IN_MS=60000
GLOBAL_PROBE_2_SYNTHETIC_MONITOR_MAX_CONCURRENCY=4
GLOBAL_PROBE_2_SYNTHETIC_MONITOR_MAX_PROCESS_TREE_RSS_BYTES=1610612736
GLOBAL_PROBE_2_SYNTHETIC_MONITOR_MAX_DISK_BYTES=268435456
# Size of /dev/shm for this probe's container (Docker's default is 64MB). The
# synthetic runtime's browsers do not use it: Playwright starts Chromium with
# --disable-dev-shm-usage, so Chromium keeps its shared memory in the
# per-execution run directory under /tmp, and Firefox uses memfd.
GLOBAL_PROBE_2_SHM_SIZE=512m
GLOBAL_PROBE_2_CUSTOM_CODE_MONITOR_SCRIPT_TIMEOUT_IN_MS=60000
GLOBAL_PROBE_2_PORT=3875
# (Optional) Configure HTTP and HTTPS proxy URLs independently. The legacy
# GLOBAL_PROBE_2_PROXY_URL remains a fallback for both protocols.
GLOBAL_PROBE_2_HTTP_PROXY_URL=
GLOBAL_PROBE_2_HTTPS_PROXY_URL=
GLOBAL_PROBE_2_NO_PROXY=
GLOBAL_PROBE_2_PROXY_URL=
SMS_DEFAULT_COST_IN_CENTS=
CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE=
SMS_HIGH_RISK_COST_IN_CENTS=
WHATSAPP_TEXT_DEFAULT_COST_IN_CENTS=
CALL_HIGH_RISK_COST_IN_CENTS_PER_MINUTE=
# IS BILLING ENABLED for this installer.
BILLING_ENABLED=false
# Public and private key for billing provider, usually stripe.
BILLING_PUBLIC_KEY=
BILLING_PRIVATE_KEY=
# Webhook secret for verifying Stripe webhook events (for automatic invoice emails)
# Get this from Stripe Dashboard > Developers > Webhooks > Your endpoint > Signing secret
BILLING_WEBHOOK_SECRET=
# Average telemetry row sizes in bytes used to estimate usage when reporting to the billing provider.
AVERAGE_SPAN_ROW_SIZE_IN_BYTES=1024
AVERAGE_LOG_ROW_SIZE_IN_BYTES=1024
AVERAGE_METRIC_ROW_SIZE_IN_BYTES=1024
AVERAGE_EXCEPTION_ROW_SIZE_IN_BYTES=1024
# Use this when you want to disable incident creation.
DISABLE_AUTOMATIC_INCIDENT_CREATION=false
# Use this when you want to disable incident creation.
DISABLE_AUTOMATIC_ALERT_CREATION=false
# When set to true, OneUptime will reject all incoming telemetry ingestion
# (OpenTelemetry traces / metrics / logs / profiles over HTTP and gRPC,
# Fluentd logs, Syslog logs, and Pyroscope profiles). The ingestion endpoints
# stay reachable and return success quickly so clients don't retry, but no
# data is queued or persisted.
DISABLE_TELEMETRY_INGESTION=false
# Once a day this installation asks the GitHub API which OneUptime version is
# the latest release, and which security advisories OneUptime published, so
# master admins are told when an upgrade is available or a published advisory
# affects the version you run (and emailed once about each such advisory). The
# requests send nothing about your installation — not even the version you run;
# GitHub sees your public IP and a User-Agent naming OneUptime, as with any
# outbound HTTP request. See /docs/self-hosted/update-checks.
# Set to true to make no outbound call at all (air-gapped deployments can also
# leave it false — the failed request is logged and ignored).
DISABLE_UPDATE_CHECK=false
# Point the update check at an internal mirror instead of GitHub. The mirror
# must answer with GitHub's release shape (tag_name, html_url, published_at).
# Leave blank to use https://api.github.com/repos/OneUptime/oneuptime/releases/latest
LATEST_RELEASE_CHECK_URL=
# Point the security advisory check at an internal mirror instead of GitHub. The
# mirror must answer with GitHub's repository security advisory shape (ghsa_id,
# summary, severity, html_url, published_at, vulnerabilities with
# vulnerable_version_range and patched_versions).
# Leave blank to use https://api.github.com/repos/OneUptime/oneuptime/security-advisories
SECURITY_ADVISORIES_CHECK_URL=
# Once a day this installation tells oneuptime.com its URL and the OneUptime
# version it runs, so OneUptime knows which installations still run a release
# with a security issue and can reach the admins who registered them. Nothing
# about your users, projects or monitoring data is sent. Set to true to make no
# call at all (air-gapped deployments can also leave it false — the failed
# request is logged and ignored). With it true, the sign-up form no longer
# offers release emails from oneuptime.com either.
DISABLE_INSTANCE_CHECK_IN=false
# On-call calendar feeds let people subscribe Google Calendar / Outlook / Apple
# Calendar to their on-call shifts through a secret .ics URL
# (https://<host>/api/on-call-calendar/user/<token>/shifts.ics). Set to true
# to switch every feed URL off: clients get a 503 with Retry-After: 3600, keep
# the copy they already have and try again in an hour. Nothing is deleted.
DISABLE_ON_CALL_CALENDAR_FEED=false
# Rate limits for those feed URLs. The token+address counter is the budget one
# subscribed calendar gets; the address counter is the ceiling that survives a
# caller rotating tokens. Calendar clients poll about hourly (Apple every five
# minutes at most), so the defaults leave plenty of room for a whole team's
# clients behind one office address. Blank keeps the default. The limiter fails
# open when Valkey is unreachable.
ON_CALL_CALENDAR_FEED_RATE_LIMIT_WINDOW_SECONDS=60
ON_CALL_CALENDAR_FEED_RATE_LIMIT_PER_TOKEN_PER_WINDOW=60
ON_CALL_CALENDAR_FEED_RATE_LIMIT_PER_IP_PER_WINDOW=3000
# OAuth sign-in for the MCP server (https://<host>/mcp). An MCP client can
# connect by having a project member sign in to OneUptime and approve it,
# instead of being handed an API key. Set to true to switch that off: the
# authorization server under /mcp/oauth and its discovery documents stop being
# served and the MCP server accepts API keys only, as it did before. Nothing is
# deleted; clients that were connected work again when it is switched back.
DISABLE_MCP_OAUTH=false
# An MCP client may identify itself by an https URL that this server fetches
# to read the client's name and redirect URIs (a Client ID Metadata Document).
# That is an outbound request, so set this to true on an instance that cannot
# reach the internet: clients then register themselves with this server
# instead, which needs no outbound request.
DISABLE_MCP_OAUTH_CLIENT_ID_METADATA_DOCUMENTS=false
# Browser source maps, uploaded from CI so exception stack traces show original
# file names and line numbers instead of minified ones.
#
# Raise SOURCE_MAP_MAX_MAPS_PER_RELEASE if your build emits more .map files per
# release than the default holds -- route-level code splitting routinely emits
# hundreds. It is a storage-shape limit only: resolution is bounded by
# SOURCE_MAP_MAX_BYTES_PER_RESOLVE, so anything that fits the ceiling resolves.
#
# The two request-shaped limits can only be LOWERED. The multipart body is
# parsed before authentication, so the shared 50-file / 50 MiB ceilings are
# what an unauthenticated caller is held to; values above them are narrowed.
SOURCE_MAP_MAX_MAPS_PER_RELEASE=1000
SOURCE_MAP_MAX_FILES_PER_REQUEST=50
SOURCE_MAP_MAX_FILE_SIZE_BYTES=52428800
SOURCE_MAP_MAX_BYTES_PER_RESOLVE=536870912
SOURCE_MAP_RETENTION_DAYS=90
# Server-side OpenTelemetry exporter configuration. These values are available
# only to backend processes. They are never serialized into frontend env.js
# responses, so headers may contain a Server ingestion key or another secret.
OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT=
# You can set the env var to "x-oneuptime-token=<YOUR_ONEUPTIME_TELEMETRY_INGEST_TOKEN>"
OPENTELEMETRY_EXPORTER_OTLP_HEADERS=
# Record what OneUptime AI's own calls said - the system prompt, the messages,
# the tool calls and their results, and the answer - in the telemetry sent
# above, so the AI / LLM conversations of the project it goes to show them.
# Without it they show each call's model, tokens, cost and timing only. Off
# unless set to true. The prompts hold incident details, logs and Ask AI chats
# (otherwise private to the person who asked), so turn it on only when everyone
# who can read that project may read them.
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=false
# Optional browser RUM exporter configuration. Both values below are PUBLIC:
# every visitor can read them from /env.js. Use only a OneUptime Browser
# ingestion key configured with this deployment's exact origins. Browser keys
# are limited to browser ingest surfaces, checked against the Origin header and
# rate-limited. Never place a Server key or an arbitrary collector bearer token
# here. Leave both blank to disable browser RUM export.
PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT=
PUBLIC_OPENTELEMETRY_EXPORTER_OTLP_BROWSER_INGESTION_KEY=
# This can be one of ERROR, WARN, INFO, DEBUG
#
# Logs go to container stdout, to an in-memory recent-log buffer the master
# admin support bundle can read back, and to the OTLP exporter above when one
# is configured -- so anything logged lands in every log system you retain.
# Credentials are redacted centrally before they reach any of those, but DEBUG
# is verbose and its output is worth the same protection as the rest of your
# telemetry: keep it off unless you are troubleshooting, and treat retained
# DEBUG output as sensitive.
LOG_LEVEL=ERROR
# Thse env vars are for E2E tests
E2E_TEST_IS_USER_REGISTERED=false
E2E_TEST_REGISTERED_USER_EMAIL=
E2E_TEST_REGISTERED_USER_PASSWORD=
# If you want to run the E2E tests on a status page, then you need to fill in the URL.
E2E_TEST_STATUS_PAGE_URL=
# This URL will be called when the E2E tests fail. This should be a GET endpoint.
E2E_TESTS_FAILED_WEBHOOK_URL=
# This is the timeout for the workflow script in milliseconds.
# How long do we wait for "Scripts" (like Custom Code Components) running in workflow to complete.
WORKFLOW_SCRIPT_TIMEOUT_IN_MS=5000
# How long do we wait for entire workflow to complete.
WORKFLOW_TIMEOUT_IN_MS=120000
# Concurrency settings
# Max number of telemetry jobs processed concurrently by OpenTelemetry Ingest worker
TELEMETRY_CONCURRENCY=100
# How many NetworkDevices one probe is handed per fetch. A probe fetches once a
# minute, so this is the ceiling on how fast that probe's fleet can be polled,
# whatever the devices' own polling intervals say: 250 devices/minute clears a
# 1000-device fleet on a 5-minute interval. Empty uses the server default (250).
#
# Raise it together with the probe's own
# GLOBAL_PROBE_n_NETWORK_DEVICE_POLL_CONCURRENCY. Claiming a device advances its
# schedule whether or not the walk actually happens, so handing a probe more
# devices than it can walk inside a cycle skips them rather than polling them
# sooner. A "claimed a full batch" warning in the app log means this limit, not
# the devices' intervals, is setting the fleet's cadence.
NETWORK_DEVICE_POLL_FETCH_LIMIT=
# Fan-in telemetry writer (per container). Batches all telemetry ClickHouse
# inserts into a handful of large INSERTs so ingestion can scale without
# exploding ClickHouse insert concurrency. Defaults shown below match the code.
# Rows buffered per table before a flush is forced.
TELEMETRY_FANIN_MAX_BATCH_ROWS=100000
# Per-table override for session replay chunks. The batcher counts rows, not
# bytes, and a replay row carries the whole decompressed rrweb payload in one
# column, so the global 100000 above would attempt a multi-hundred-MB insert.
TELEMETRY_FANIN_MAX_BATCH_ROWS_SESSION_REPLAY=2000
# Longest a buffered row waits (in ms) before its table is flushed anyway.
TELEMETRY_FANIN_MAX_WAIT_MS=5000
# Max simultaneous ClickHouse INSERTs per container. Total insert concurrency
# across all containers should stay under ~60% of ClickHouse
# max_concurrent_queries.
TELEMETRY_FANIN_MAX_CONCURRENT_INSERTS=4
# Backpressure cap: ingestion jobs block once this many rows are queued.
TELEMETRY_FANIN_MAX_PENDING_ROWS=200000
# Retry budget for failed inserts: attempts + exponential backoff bounds (ms).
TELEMETRY_FANIN_RETRY_MAX_ATTEMPTS=6
TELEMETRY_FANIN_RETRY_BASE_DELAY_MS=250
TELEMETRY_FANIN_RETRY_MAX_DELAY_MS=10000
# Ack mode for telemetry ClickHouse inserts. Default false = fire-and-forget
# async inserts: ClickHouse acks once a batch is accepted into its
# async-insert buffer and owns flushing it (flush errors surface only in
# ClickHouse server logs; a crash between accept and flush loses that
# buffer). Set true to make acks wait for the durable flush — each waiting
# insert then holds a ClickHouse query slot until its buffer flushes.
TELEMETRY_WAIT_FOR_ASYNC_INSERT=false
# Dedicated telemetry-writer tier (advanced; normally left empty in compose —
# the Helm chart wires this via telemetryWriter.enabled). When set on a
# container that processes telemetry ingest, its fan-in writer ships batched
# ClickHouse inserts to this URL (cluster-key authenticated) instead of
# inserting directly, so ingestion containers scale without adding ClickHouse
# insert concurrency. The container SERVING that URL must NOT have this set.
# Example: TELEMETRY_WRITER_URL=http://telemetry-writer:3002
TELEMETRY_WRITER_URL=
# How long a shipped insert may take end-to-end (writer batching + retries).
# Keep 6 x this + backoff under the 10-minute telemetry job lock.
TELEMETRY_WRITER_REQUEST_TIMEOUT_MS=90000
# Split shipped batches whose JSON body would exceed this many bytes (stay
# under the 50 MB internal request-body limit; oversized posts are dropped).
TELEMETRY_WRITER_MAX_BODY_BYTES=30000000
# Writer-side admission cap: concurrently-served insert requests per
# container before shedding with 429 (callers retry with the same
# idempotent dedup token).
TELEMETRY_WRITER_MAX_INFLIGHT_REQUESTS=100
# Session replay ingest.
# Instance-level kill switch for accepting session replay chunks. Independent
# of the per-project and per-application toggles: set false to stop accepting
# recordings fleet-wide without a deploy.
SESSION_REPLAY_INGEST_ENABLED=true
# Whether this deployment offers session replay at all. TRUE by default.
#
# On a self-hosted install, set this to false unless you have also set a byte
# budget below. Plan gating is a no-op when BILLING_ENABLED=false, so nothing
# else stops 100% sampling at 90-day retention on a single ClickHouse node —
# and because replay is the fattest table, the capacity pruner would then start
# dropping partitions, potentially destroying the install's logs and traces to
# make room.
SESSION_REPLAY_ENABLED_BY_DEFAULT=true
# Ask every browser recorder this deployment serves to print its decisions to
# the console. OFF by default and it should stay that way in normal operation:
# the recorder runs on your customers' sites, in their end users' browsers.
#
# This is the switch of last resort, for an operator who needs to know why
# replay produces nothing on a page they do not own and cannot edit. The
# per-browser switches are usually the right ones instead —
# localStorage.setItem("oneuptime.sessionReplay.debug", "true"), or an
# ?oneuptime_debug=1 on the URL. Turn this on, collect one reload, turn it off.
#
# It changes no policy: not sampling, not masking, not consent. It only adds
# output. See /docs/rum/session-replay-troubleshooting.
SESSION_REPLAY_DEBUG=false
# Per-project chunk ceiling per minute, counted in Valkey so it holds across
# every app pod. Exceeding it answers 429 with Retry-After.
SESSION_REPLAY_MAX_CHUNKS_PER_PROJECT_PER_MINUTE=20000
# Per-project daily byte budget (default 1 GiB). This is the disk-protection
# control that works regardless of billing. Exceeding it answers 204 and tells
# live recorders to stand down for the rest of the day.
SESSION_REPLAY_MAX_BYTES_PER_PROJECT_PER_DAY=1073741824
# Chunks at or under this size ride inline in the queue job as base64 instead
# of being staged in Valkey. A typical chunk is ~7 KB, so this keeps ~99% of
# chunks out of Valkey entirely — which matters because compose runs Valkey
# with persistence off and no configured maxmemory.
SESSION_REPLAY_INLINE_STAGING_MAX_BYTES=65536
# Replay's share of the shared telemetry worker's concurrency slots, per pod.
# Caps a replay backlog so it cannot starve trace and log ingest.
SESSION_REPLAY_WORKER_CONCURRENCY=20
# The ONE request header whose country code replay ingest is allowed to trust,
# lowercased (cf-ipcountry behind Cloudflare, x-vercel-ip-country behind
# Vercel). Empty means no country is recorded at all, which is the default:
# nothing in the Nginx config strips these headers, so honouring one on a
# deployment that is not actually behind that CDN lets any client stamp
# arbitrary countries onto session rows.
SESSION_REPLAY_TRUSTED_GEO_HEADER=
# MQTT ingest for IoT devices. Devices connect over MQTT-over-WebSocket at
# ws(s)://<your-host>/mqtt (rides the normal HTTP/HTTPS ports), or over raw
# MQTT TCP on MQTT_INGEST_PORT inside the compose network. Set
# MQTT_INGEST_ENABLED=false to turn the listeners off.
MQTT_INGEST_ENABLED=true
MQTT_INGEST_PORT=1883
# Max number of jobs processed concurrently by Fluent Logs worker
FLUENT_LOGS_CONCURRENCY=100
# Max number of jobs processed concurrently by Worker service
WORKER_CONCURRENCY=100
# Max number of AI investigations one server runs at once. Servers that
# process queue jobs run them (see DISABLE_QUEUE_WORKERS below); more wait in
# the queue, incident and alert investigations first. Each one mostly waits
# on the model but holds its conversation in memory, so raise this together
# with the container's memory.
AI_INVESTIGATION_CONCURRENCY=10
# Role split (advanced, mainly for Kubernetes). When true, this process does
# NOT consume BullMQ queues — it only serves the API + ingest endpoints and
# enqueues jobs. A separate "worker" deployment (with DISABLE_QUEUE_WORKERS
# unset/false) then drains the queues, so heavy telemetry/background processing
# can't stall API requests. Default false: this process both serves the API and
# processes all background + telemetry jobs (single-container behavior).
DISABLE_QUEUE_WORKERS=false
# Whether ingress traffic - agents, collectors, probes, heartbeat senders -
# reaches this process. Leave it unset: the single App container does. Set it
# to false only on App replicas that run as dedicated workers with no ingress
# in front of them (the Helm chart's worker pods do), so they never record that
# OneUptime was receiving data. OneUptime uses that record to keep its own
# restarts and upgrades from counting as downtime of your hosts and monitors.
# RECEIVES_INGRESS_TRAFFIC=true
# Lets encrypt notification email. This email will be used when certs are about to expire
LETS_ENCRYPT_NOTIFICATION_EMAIL=
# Generate a private key via openssl, encode it to base64 and paste it here.
# Example: "LS0tLS....1cbg=="
LETS_ENCRYPT_ACCOUNT_KEY=
# This is the number of active monitors allowed in the free plan.
ALLOWED_ACTIVE_MONITOR_COUNT_IN_FREE_PLAN=10
# What Data Observability's watched tables cost. Only used with BILLING_ENABLED=true.
# A view is free, and so is any table of a database nobody is watching.
# Tables every project watches free.
WATCHED_TABLES_INCLUDED_PER_PROJECT=100
# What each table past those costs a month, in USD.
WATCHED_TABLE_PRICE_IN_USD=1
# Past this many tables, each further table costs WATCHED_TABLE_VOLUME_PRICE_IN_USD.
WATCHED_TABLE_VOLUME_THRESHOLD=1000
WATCHED_TABLE_VOLUME_PRICE_IN_USD=0.25
# The Stripe price watched tables bill against: metered, one cent a unit, aggregating
# usage as "last during period". OneUptime works out each month's cost from the rates
# above and reports it in cents. Leave it empty and nothing is charged: projects only
# see what their tables would cost.
WATCHED_TABLE_STRIPE_PRICE_ID=
# Outbound Webhook Egress Policy (self-hosted)
#
# By default OneUptime refuses to send any workflow request, project webhook,
# on-call user webhook or sandboxed HTTP call to a target that resolves into a
# private, loopback or link-local range. That is the right default, but it also
# blocks the ordinary self-hosted case of posting an alert to an internal
# Mattermost, Jira or ticketing system on 10.x / 192.168.x.
#
# Both settings below are OFF by default and both are instance-wide. They are
# the only gate: there is no per-project setting, so whatever they allow applies
# to every project on this instance. They cover the status page webhook
# subscribers a project's team adds, but never subscribers who sign up on a
# status page, because any visitor to a public status page can sign one up.
#
# Permit the private tier — RFC-1918, CGNAT, IPv6 unique-local and site-local.
# Loopback, link-local (169.254.169.254 lives there), multicast and reserved
# stay blocked; use the allowlist below if you truly need one of those.
ALLOW_PRIVATE_NETWORK_WEBHOOKS=false
#
# Comma-separated hosts and CIDRs that are allowed regardless of range —
# hostnames ("mattermost.internal"), wildcards ("*.svc.cluster.local"), IPs and
# CIDRs ("10.20.0.0/16", "fd00::/8"). A hostname listed here is trusted without
# a DNS check, which is the point: it is expected to resolve somewhere private.
# NEVER list 169.254.169.254 or a range containing it — on a cloud VM that
# hands every project member the instance's IAM credentials.
PRIVATE_NETWORK_WEBHOOK_ALLOWLIST=
# Outbound Connection Egress Policy (everything that is not a webhook)
#
# External data sources (security event connections such as Splunk, threat
# intel feeds), LLM providers, SMTP servers (project settings and the workflow
# Email component), SMTP and workflow OAuth token URLs, OIDC discovery, status
# page / dashboard domain verification and Runbook HTTP steps are checked by a
# separate guard. Loopback, link-local (169.254.169.254) and reserved ranges are
# refused everywhere. The private tier (RFC-1918, CGNAT, IPv6 unique-local) is
# ALLOWED on a self-hosted install, because the servers these connect to usually
# live there.
#
# Set this to true to refuse the private tier for these connections as well --
# for example when projects on this instance belong to people who should not
# reach your internal network. Only the exact value "true" turns it on. It is
# always on when BILLING_ENABLED=true, whatever this line says. It does not
# change which webhook targets (see above) or monitor targets (see below) are
# allowed, and it does not apply to a Global LLM Provider
# (GLOBAL_LLM_PROVIDER_* below, or one added in the Admin Dashboard): you
# choose its address, not a project. It does change how refusals read: with it
# on, a refused host name -- here, and for webhooks and workflow requests too
# -- is reported as "... could not be reached." without saying whether it
# failed to resolve or what it resolved to, so project members cannot use it
# to map internal names. LOG_LEVEL=DEBUG logs the exact reason.
DATA_SOURCE_BLOCK_PRIVATE_ADDRESSES=false
# Whether API, Website, External Status Page and Custom JavaScript Code
# MONITORS may reach private network addresses (RFC-1918, CGNAT, IPv6
# unique-local) from a probe.
#
# This is a separate, probe-side switch, and it is read by the probe process
# from its OWN environment — not from the settings above, which live on the API
# server. Whoever deploys a probe controls its environment, and they are the
# party who knows which network that probe can see. Off by default.
#
# It applies to every probe that has it set, including the bundled Docker
# Compose probes: docker-compose.base.yml passes this one value to probe-1 and
# probe-2 alike. Those are GLOBAL probes (they register with
# REGISTER_PROBE_KEY and every project can select them), so setting it to true
# here lets monitors from EVERY project on this instance reach private
# addresses through them. If projects on this instance should not share that
# reach, leave it false and deploy a private (custom) probe inside each
# network that needs monitoring.
#
# API, Website and External Status Page requests are DNS-validated and pinned
# at connection time; Custom Code uses the same address policy in its sandbox
# bridge. Only the exact value "true" turns it on.
#
# Turning it on does NOT open loopback, link-local or the cloud metadata
# endpoint — those stay refused on every probe.
#
# A global probe with BILLING_ENABLED=true in its environment (the hosted,
# open-signup product) stays public-only: the setting is ignored there, and the
# probe logs a warning at startup saying so. Both the bundled Compose probes and
# the Helm chart's probes are given BILLING_ENABLED for this.
#
# To turn it on, change the line below to true (do not add a second line: the
# later one wins) and run `npm run start` to recreate the probe containers.
# A value other than exactly "true" or "false" is reported as a warning at
# startup. The probe's routine "private network monitoring is on/off" line is
# logged at LOG_LEVEL=INFO, above the LOG_LEVEL=ERROR this file ships with
# (OneUptime issue #3879).
PROBE_ALLOW_PRIVATE_NETWORK_MONITORS=false
# Open Source Deployment Webhook
# This webhook is called when a new self-hosted open source deployment registers.
OPEN_SOURCE_DEPLOYMENT_WEBHOOK_URL=
# Notifications Webhook (Slack)
# This webhook notifies slack when the new user signs up or is created.
NOTIFICATION_SLACK_WEBHOOK_ON_CREATED_USER=
# This webhook notifies slack when the new project is created.
NOTIFICATION_SLACK_WEBHOOK_ON_CREATED_PROJECT=
# This webhook notifies slack when the project is deleted, with the feedback the customer gave for deleting it.
NOTIFICATION_SLACK_WEBHOOK_ON_DELETED_PROJECT=
# This webhook notifies slack when the subscription is updated, and when a project's SMS and call balance or AI balance is refilled or adjusted by a master admin.
NOTIFICATION_SLACK_WEBHOOK_ON_SUBSCRIPTION_UPDATE=
# This webhook notifies slack of each thumbs up or thumbs down people give an answer from OneUptime AI in Microsoft Teams, with what they wrote - reports of wrong or inappropriate answers to act on.
NOTIFICATION_SLACK_WEBHOOK_ON_AI_FEEDBACK=
# VAPID keys for Web Push Notifications
# Generate using: npx web-push generate-vapid-keys
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
VAPID_SUBJECT=mailto:support@oneuptime.com
# Expo access token for sending mobile push notifications directly via Expo SDK.
# If not set, push notifications are relayed through the push notification relay URL below.
EXPO_ACCESS_TOKEN=
# Push notification relay URL for self-hosted instances without Expo credentials.
# Self-hosted servers relay push notifications through this gateway.
PUSH_NOTIFICATION_RELAY_URL=https://oneuptime.com/api/notification/push-relay/send
# Whether this server relays mobile push notifications for other OneUptime
# servers (/api/notification/push-relay), sending what they ask with its
# EXPO_ACCESS_TOKEN. Leave it empty: it is then on only where
# BILLING_ENABLED=true (OneUptime's cloud). Set it to true only if your other
# OneUptime servers send their pushes through this one (their
# PUSH_NOTIFICATION_RELAY_URL). EXPO_ACCESS_TOKEN alone sends this server's own
# pushes and relays nothing. Any value other than true or empty turns it off.
PUSH_NOTIFICATION_RELAY_SERVER_ENABLED=
# The bundled global Runner (the global-runner service). It runs the runbook
# JavaScript steps, each in a sandbox that reaches the internet only, and the
# AI code fixes of every project that uses global Runners, never a repository's
# own commands. npm start and npm run update give GLOBAL_RUNNER_KEY a random
# value. Set GLOBAL_RUNNER_REPLICAS=0 to turn it off.
# GLOBAL_RUNNER_CONCURRENCY is how many steps one global Runner runs at once.
GLOBAL_RUNNER_KEY=please-change-this-to-random-value
GLOBAL_RUNNER_REPLICAS=1
GLOBAL_RUNNER_CONCURRENCY=4
GLOBAL_RUNNER_PORT=3877
# By default telemetry is disabled for all services in docker compose. If you want to enable telemetry for a service, then set the env var to false.
DISABLE_TELEMETRY_FOR_APP=true
DISABLE_TELEMETRY_FOR_TEST_SERVER=true
DISABLE_TELEMETRY_FOR_PROBE=true
DISABLE_TELEMETRY_FOR_INGRESS=true
DISABLE_TELEMETRY_FOR_RUNNER=true
# By default profiling is disabled for all services. Set to true to enable CPU profiling for a service.
ENABLE_PROFILING_FOR_APP=false
ENABLE_PROFILING_FOR_TEST_SERVER=false
ENABLE_PROFILING_FOR_PROBE=false
ENABLE_PROFILING_FOR_RUNNER=false
# Connect OneUptime with Slack App
SLACK_APP_CLIENT_ID=
SLACK_APP_CLIENT_SECRET=
SLACK_APP_SIGNING_SECRET=
# Where the ingress listens inside its container. Left empty, it listens on
# every IPv4 and IPv6 address it has. To listen on one address only, name it:
# IPv4 only:
# NGINX_LISTEN_ADDRESS=0.0.0.0:
# IPv6 only:
# NGINX_LISTEN_ADDRESS=[::]:
# NGINX_LISTEN_OPTIONS are options of the listening socket, such as
# backlog=4096.
NGINX_LISTEN_ADDRESS=
NGINX_LISTEN_OPTIONS=
# Microsoft Teams: a Microsoft Entra app registration for your organization
# only (Single tenant), and an Azure Bot of type Single Tenant for it.
# See: https://oneuptime.com/docs/self-hosted/microsoft-teams-integration
# MICROSOFT_TEAMS_APP_CLIENT_ID: the Application (client) ID, which is also
# the bot id of the Teams app package.
# MICROSOFT_TEAMS_APP_CLIENT_SECRET: the client secret's VALUE, not its
# Secret ID (the value is the longer string).
# MICROSOFT_TEAMS_APP_TENANT_ID: the Directory (tenant) ID. The bot
# authenticates in this tenant, and people sign in to it to connect their
# Microsoft Teams account.
# MICROSOFT_TEAMS_CLOUD: the Microsoft cloud your Microsoft 365 tenant is in.
# Leave it empty for the commercial cloud. For a US Government cloud set
# gcc, gcc-high or dod: the bot, the Microsoft Teams sign-ins and the Teams
# meetings app below then use that cloud's hosts. For gcc-high and dod,
# register the app and create the Azure Bot in Azure Government.
MICROSOFT_TEAMS_APP_CLIENT_ID=
MICROSOFT_TEAMS_APP_CLIENT_SECRET=
MICROSOFT_TEAMS_APP_TENANT_ID=
MICROSOFT_TEAMS_CLOUD=
# Video calls: connect Zoom, Google Meet and Microsoft Teams in one click
# (Project Settings > Video Calls). Someone signs in to the provider and allows
# this server's app to create meetings as that account. A provider whose
# client id and secret are both set is connected by signing in; without them,
# projects connect their own Zoom, Google or Microsoft app instead.
#
# Register these redirect URIs on the apps (replace <HOST> with HOST above):
# https://<HOST>/api/video-call-oauth/zoom/callback
# https://<HOST>/api/video-call-oauth/google-meet/callback
# https://<HOST>/api/video-call-oauth/microsoft-teams/callback
# See: https://oneuptime.com/docs/workspace-connections/video-calls#one-click-connect-on-a-self-hosted-server
#
# Zoom: a General app (user-managed) with the meeting:write:meeting and
# user:read:user scopes. ZOOM_APP_WEBHOOK_SECRET_TOKEN is the app's Secret
# Token, which verifies the event Zoom sends to
# https://<HOST>/api/video-call-oauth/zoom/events when someone removes the app.
ZOOM_APP_CLIENT_ID=
ZOOM_APP_CLIENT_SECRET=
ZOOM_APP_WEBHOOK_SECRET_TOKEN=
# Google: an OAuth client (web application) in a Google Cloud project with the
# Google Meet REST API enabled.
GOOGLE_MEET_APP_CLIENT_ID=
GOOGLE_MEET_APP_CLIENT_SECRET=
# Microsoft: an Entra app registration with the delegated
# OnlineMeetings.ReadWrite permission - not the Teams bot's registration above.
# A multi-tenant app needs no tenant ID. For an app registered for your own
# organization only (single tenant), set MICROSOFT_TEAMS_MEETINGS_APP_TENANT_ID
# to its Directory (tenant) ID: its sign-in then goes to that tenant.
MICROSOFT_TEAMS_MEETINGS_APP_CLIENT_ID=
MICROSOFT_TEAMS_MEETINGS_APP_CLIENT_SECRET=
MICROSOFT_TEAMS_MEETINGS_APP_TENANT_ID=
# Cloud > Connect: this server's own AWS identity, which signs in to the
# read-only IAM roles customers create for it. An IAM user's access key,
# allowed to call sts:AssumeRole and nothing else. With it, an AWS account is
# connected with a role (nothing secret is stored); without it, with a
# read-only access key. Azure and Google Cloud need nothing here.
CLOUD_CONNECT_AWS_ACCESS_KEY_ID=
CLOUD_CONNECT_AWS_SECRET_ACCESS_KEY=
# GitHub App Configuration
# Create a GitHub App at https://github.com/settings/apps
# Required for connecting GitHub repositories to OneUptime
#
# The GitHub App must have "Request user authorization (OAuth) during
# installation" enabled. OneUptime exchanges the OAuth code GitHub returns to
# confirm the person installing the app actually controls the installation
# before connecting it to their project; without it, connecting is refused.
# CLIENT_ID and CLIENT_SECRET are required for that exchange.
#
# GITHUB_APP_WEBHOOK_SECRET is also required: webhooks whose signature cannot
# be verified are rejected rather than trusted.
#
# GITHUB_APP_NAME must match the app's real name on GitHub. The app's mention
# handle is derived from it (lowercased, spaces to hyphens), so an app named
# "Acme AI" is addressed as "@acme-ai" — get this wrong and mentions silently
# never match. Answering mentions also needs the app to hold the "Issues:
# Read & write" permission and to be subscribed to the Issue comment, Issues,
# Pull request, Pull request review and Pull request review comment events.
# See: https://oneuptime.com/docs/self-hosted/github-integration
# and: https://oneuptime.com/docs/ai/github-app
GITHUB_APP_ID=
GITHUB_APP_NAME=
GITHUB_APP_CLIENT_ID=
GITHUB_APP_CLIENT_SECRET=
GITHUB_APP_PRIVATE_KEY=
GITHUB_APP_WEBHOOK_SECRET=
# Sign in with Microsoft
# A multi-tenant Microsoft Entra app registration ("Accounts in any
# organizational directory and personal Microsoft accounts") that lets people
# sign in to OneUptime with their Microsoft account. Required to sell on
# Microsoft Marketplace. Register this redirect URI on the app (Web platform):
# https://<HOST>/identity/microsoft/callback
# and add the optional ID token claims "email" and "xms_edov": an organization
# account signs in only when Microsoft confirms its organization owns the
# address. Leave empty to not offer it.
MICROSOFT_SIGN_IN_CLIENT_ID=
MICROSOFT_SIGN_IN_CLIENT_SECRET=
# Continue with Google
# A Google OAuth client (type "Web application") that lets people sign up for
# and sign in to OneUptime with their Google account, Gmail and Google
# Workspace alike. Create it in a Google Cloud project with an OAuth consent
# screen (the scopes openid, email and profile are all it asks for), and add
# this authorized redirect URI:
# https://<HOST>/identity/google/callback
# Only an address Google has verified and manages (Gmail, or a Google
# Workspace domain) signs in. Leave empty to not offer it.
# How to set it up: packages/Common/Server/Utils/GoogleSignIn/RELEASING.md
GOOGLE_SIGN_IN_CLIENT_ID=
GOOGLE_SIGN_IN_CLIENT_SECRET=
# Cloud marketplaces (OneUptime Cloud only - billing must be enabled)
# Sell OneUptime on AWS Marketplace, Microsoft Marketplace (Azure) and Google
# Cloud Marketplace. A marketplace is offered only when all of its settings
# are set. How to set each one up, and the URLs to give each marketplace, is in
# packages/Common/Server/Utils/Marketplace/RELEASING.md.
#
# AWS Marketplace (SaaS, pay as you go). Fulfillment URL:
# https://<HOST>/api/marketplace/aws/register. Events: an EventBridge rule for
# source aws.agreement-marketplace -> API destination
# https://<HOST>/api/marketplace/aws/events, with an API key connection whose
# header is x-oneuptime-marketplace-secret and whose value is
# AWS_MARKETPLACE_EVENTS_SECRET.
AWS_MARKETPLACE_ACCESS_KEY_ID=
AWS_MARKETPLACE_SECRET_ACCESS_KEY=
AWS_MARKETPLACE_PRODUCT_CODE=
AWS_MARKETPLACE_EVENTS_SECRET=
# Microsoft Marketplace (transactable SaaS offer). Landing page:
# https://<HOST>/api/marketplace/azure/landing. Connection webhook:
# https://<HOST>/api/marketplace/azure/webhook. The tenant and the
# single-tenant Entra app named in the offer's Technical configuration.
AZURE_MARKETPLACE_TENANT_ID=
AZURE_MARKETPLACE_CLIENT_ID=
AZURE_MARKETPLACE_CLIENT_SECRET=
# Google Cloud Marketplace (integrated SaaS). Sign-up URL:
# https://<HOST>/api/marketplace/google-cloud/signup. Pub/Sub push endpoint:
# https://<HOST>/api/marketplace/google-cloud/events. The service account key
# may be the downloaded JSON or the same JSON base64-encoded.
GOOGLE_CLOUD_MARKETPLACE_PROVIDER_ID=
GOOGLE_CLOUD_MARKETPLACE_SERVICE_ACCOUNT_KEY=
GOOGLE_CLOUD_MARKETPLACE_SERVICE_NAME=
GOOGLE_CLOUD_MARKETPLACE_USAGE_METRIC=
GOOGLE_CLOUD_MARKETPLACE_PUBSUB_SERVICE_ACCOUNT_EMAIL=
# Optional: default to HOST and to the push endpoint's URL.