diff --git a/apps/client/package.json b/apps/client/package.json
index 31184029f..823410201 100644
--- a/apps/client/package.json
+++ b/apps/client/package.json
@@ -39,7 +39,7 @@
"build": "vite build",
"build:local": "cross-env NODE_ENV=local vite build",
"build:electron": "cross-env NODE_ENV=local vite build",
- "build:docker": "vite build",
+ "build:docker": "cross-env VITE_IS_CLOUD=true vite build",
"build:localdocker": "cross-env NODE_ENV=local vite build",
"lint": "eslint . --quiet",
"test": "vitest",
diff --git a/apps/client/src/common/api/constants.ts b/apps/client/src/common/api/constants.ts
index 4751a3711..a75d75385 100644
--- a/apps/client/src/common/api/constants.ts
+++ b/apps/client/src/common/api/constants.ts
@@ -1,3 +1,5 @@
+import { serverURL } from '../../externals';
+
// keys in tanstack store
export const APP_INFO = ['appinfo'];
export const APP_SETTINGS = ['appSettings'];
@@ -14,19 +16,7 @@ export const URL_PRESETS = ['urlpresets'];
export const VIEW_SETTINGS = ['viewSettings'];
export const CLIENT_LIST = ['clientList'];
-// resolve location
-const location = window.location;
-const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
-export const isProduction = import.meta.env.MODE === 'production';
-export const isDev = !isProduction;
-export const isLocalhost = location.hostname === 'localhost' || location.hostname === '127.0.0.1';
-
-// resolve port
-const STATIC_PORT = 4001;
-export const serverPort = isProduction ? location.port : STATIC_PORT;
-export const serverURL = `${location.protocol}//${location.hostname}:${serverPort}`;
-export const websocketUrl = `${socketProtocol}://${location.hostname}:${serverPort}/ws`;
-
+// API URLs
export const apiEntryUrl = `${serverURL}/data`;
export const projectDataURL = `${serverURL}/project`;
diff --git a/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx
index 179d44b66..7180f2d36 100644
--- a/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx
+++ b/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx
@@ -17,8 +17,8 @@ import { IoExpand } from '@react-icons/all-files/io5/IoExpand';
import { IoLockClosedOutline } from '@react-icons/all-files/io5/IoLockClosedOutline';
import { IoSwapVertical } from '@react-icons/all-files/io5/IoSwapVertical';
+import { isLocalhost, serverPort } from '../../../externals';
import { navigatorConstants } from '../../../viewerConfig';
-import { isLocalhost, serverPort } from '../../api/constants';
import useClickOutside from '../../hooks/useClickOutside';
import { useElectronEvent } from '../../hooks/useElectronEvent';
import useInfo from '../../hooks-query/useInfo';
diff --git a/apps/client/src/common/components/protect-route/ProtectRoute.tsx b/apps/client/src/common/components/protect-route/ProtectRoute.tsx
index da5dbac03..540c24626 100644
--- a/apps/client/src/common/components/protect-route/ProtectRoute.tsx
+++ b/apps/client/src/common/components/protect-route/ProtectRoute.tsx
@@ -1,6 +1,6 @@
import { PropsWithChildren, useCallback, useContext } from 'react';
-import { isLocalhost } from '../../api/constants';
+import { isLocalhost } from '../../../externals';
import { AppContext } from '../../context/AppContext';
import PinPage from './PinPage';
diff --git a/apps/client/src/common/hooks-query/useAppVersion.ts b/apps/client/src/common/hooks-query/useAppVersion.ts
index 65136c58c..399380b8d 100644
--- a/apps/client/src/common/hooks-query/useAppVersion.ts
+++ b/apps/client/src/common/hooks-query/useAppVersion.ts
@@ -2,7 +2,8 @@ import { useQuery } from '@tanstack/react-query';
import { dayInMs } from 'ontime-utils';
import { version } from '../../../../../package.json';
-import { APP_VERSION, isLocalhost } from '../api/constants';
+import { isLocalhost } from '../../externals';
+import { APP_VERSION } from '../api/constants';
import { getLatestVersion, HasUpdate } from '../api/external';
const placeholder: HasUpdate & { hasUpdates: boolean } = { url: '', version: '', hasUpdates: false };
diff --git a/apps/client/src/common/hooks/useMemoisedFn.ts b/apps/client/src/common/hooks/useMemoisedFn.ts
index d0f416e57..179c00e0c 100644
--- a/apps/client/src/common/hooks/useMemoisedFn.ts
+++ b/apps/client/src/common/hooks/useMemoisedFn.ts
@@ -6,7 +6,7 @@
import { useMemo, useRef } from 'react';
-import { isDev } from '../api/constants';
+import { isDev } from '../../externals';
type noop = (this: any, ...args: any[]) => any;
diff --git a/apps/client/src/common/utils/socket.ts b/apps/client/src/common/utils/socket.ts
index b4389d492..aee453a62 100644
--- a/apps/client/src/common/utils/socket.ts
+++ b/apps/client/src/common/utils/socket.ts
@@ -1,16 +1,9 @@
import { Log, RundownCached, RuntimeStore } from 'ontime-types';
-import { CLIENT_LIST, CUSTOM_FIELDS, isProduction, RUNDOWN, RUNTIME, websocketUrl } from '../api/constants';
+import { isProduction, websocketUrl } from '../../externals';
import { invalidateAllCaches } from '../api/utils';
import { ontimeQueryClient } from '../queryClient';
-import {
- getClientId,
- getClientName,
- setClientId,
- setClientName,
- setClientRedirect,
- setClients,
-} from '../stores/clientStore';
+import { getClientId, getClientName, setClientId, setClientName, setClients } from '../stores/clientStore';
import { addLog } from '../stores/logger';
import { patchRuntime, runtimeStore } from '../stores/runtime';
diff --git a/apps/client/src/externals.ts b/apps/client/src/externals.ts
index a456611f9..720f44907 100644
--- a/apps/client/src/externals.ts
+++ b/apps/client/src/externals.ts
@@ -1,6 +1,25 @@
+/**
+ * This file contains a list of constants that may need to be resolved at runtime
+ */
+
export const githubUrl = 'https://www.github.com/cpvalente/ontime';
export const apiRepoLatest = 'https://api.github.com/repos/cpvalente/ontime/releases/latest';
export const websiteUrl = 'https://www.getontime.no';
export const documentationUrl = 'https://docs.getontime.no';
export const customFieldsDocsUrl = 'https://docs.getontime.no/features/custom-fields/';
+
+// resolve environment
+export const isProduction = import.meta.env.MODE === 'production';
+export const isDev = !isProduction;
+export const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
+export const isOntimeCloud = Boolean(import.meta.env.VITE_IS_CLOUD);
+
+// resolve protocol
+const socketProtocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
+
+// resolve port
+const STATIC_PORT = 4001;
+export const serverPort = isProduction ? window.location.port : STATIC_PORT;
+export const serverURL = `${window.location.protocol}//${location.hostname}:${serverPort}`;
+export const websocketUrl = `${socketProtocol}://${location.hostname}:${serverPort}/ws`;
diff --git a/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx b/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx
index 3c3178f47..cf7927fcc 100644
--- a/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx
+++ b/apps/client/src/features/app-settings/panel/network-panel/NetworkInterfaces.tsx
@@ -1,9 +1,9 @@
import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp';
-import { serverPort } from '../../../../common/api/constants';
import CopyTag from '../../../../common/components/copy-tag/CopyTag';
import useInfo from '../../../../common/hooks-query/useInfo';
import { openLink } from '../../../../common/utils/linkUtils';
+import { serverPort } from '../../../../externals';
import style from './NetworkInterfaces.module.scss';
diff --git a/apps/client/src/features/app-settings/panel/network-panel/NetworkLogPanel.tsx b/apps/client/src/features/app-settings/panel/network-panel/NetworkLogPanel.tsx
index 2026aca1d..51773d320 100644
--- a/apps/client/src/features/app-settings/panel/network-panel/NetworkLogPanel.tsx
+++ b/apps/client/src/features/app-settings/panel/network-panel/NetworkLogPanel.tsx
@@ -1,4 +1,5 @@
import useScrollIntoView from '../../../../common/hooks/useScrollIntoView';
+import { isOntimeCloud } from '../../../../externals';
import type { PanelBaseProps } from '../../panel-list/PanelList';
import * as Panel from '../../panel-utils/PanelUtils';
import ClientControlPanel from '../client-control-panel/ClientControlPanel';
@@ -14,6 +15,7 @@ export default function NetworkLogPanel({ location }: PanelBaseProps) {
<>
Network
+ {isOntimeCloud && Ontime cloud}
Ontime is streaming on the following network interfaces
diff --git a/apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx b/apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx
index e72ac7b67..21f192df4 100644
--- a/apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx
+++ b/apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx
@@ -10,8 +10,8 @@ import {
useDisclosure,
} from '@chakra-ui/react';
-import { isLocalhost } from '../../../../common/api/constants';
import { useElectronEvent } from '../../../../common/hooks/useElectronEvent';
+import { isLocalhost } from '../../../../externals';
import * as Panel from '../../panel-utils/PanelUtils';
export default function ShutdownPanel() {