diff --git a/docker/.env.example b/docker/.env.example
index e24a0208bb..18c96c3534 100644
--- a/docker/.env.example
+++ b/docker/.env.example
@@ -56,21 +56,6 @@ ENABLE_MAPBOX=false
 MAPBOX_KEY=
 
 
-
-
-###################################################################################
-# WEB - Required
-###################################################################################
-
-# This is the URL of your vm/server where you host Immich, so that the web frontend
-# know where can it make the request to.
-# For example: If your server IP address is 10.1.11.50, the environment variable will
-# be VITE_SERVER_ENDPOINT=http://10.1.11.50:2283/api
-# !CAUTION! THERE IS NO FORWARD SLASH AT THE END
-
-VITE_SERVER_ENDPOINT=
-
-
 ####################################################################################
 # WEB - Optional
 ####################################################################################
diff --git a/server/apps/immich/src/config/app.config.ts b/server/apps/immich/src/config/app.config.ts
index b2509db908..304bee8643 100644
--- a/server/apps/immich/src/config/app.config.ts
+++ b/server/apps/immich/src/config/app.config.ts
@@ -16,6 +16,5 @@ export const immichAppConfig: ConfigModuleOptions = {
       then: Joi.string().optional().allow(null, ''),
       otherwise: Joi.string().required(),
     }),
-    VITE_SERVER_ENDPOINT: Joi.string().required(),
   }),
 };
diff --git a/server/entrypoint.sh b/server/entrypoint.sh
deleted file mode 100644
index 9f35169bf6..0000000000
--- a/server/entrypoint.sh
+++ /dev/null
@@ -1 +0,0 @@
-npm start immich
\ No newline at end of file
diff --git a/web/src/api/api.ts b/web/src/api/api.ts
index 12b7dee9a8..d8454350ec 100644
--- a/web/src/api/api.ts
+++ b/web/src/api/api.ts
@@ -16,7 +16,7 @@ class ImmichApi {
 	public authenticationApi: AuthenticationApi;
 	public deviceInfoApi: DeviceInfoApi;
 	public serverInfoApi: ServerInfoApi;
-	private config = new Configuration({ basePath: serverEndpoint });
+	private config = new Configuration({ basePath: '/api' });
 
 	constructor() {
 		this.userApi = new UserApi(this.config);
@@ -34,6 +34,12 @@ class ImmichApi {
 	public removeAccessToken() {
 		this.config.accessToken = undefined;
 	}
+
+	public setBaseUrl(baseUrl: string) {
+		this.config.basePath = baseUrl;
+	}
 }
 
 export const api = new ImmichApi();
+export const serverApi = new ImmichApi();
+serverApi.setBaseUrl('http://immich-server:3001');
diff --git a/web/src/hooks.ts b/web/src/hooks.ts
index 44f9a33e0d..788f169eb0 100644
--- a/web/src/hooks.ts
+++ b/web/src/hooks.ts
@@ -1,6 +1,6 @@
 import type { ExternalFetch, GetSession, Handle } from '@sveltejs/kit';
 import * as cookie from 'cookie';
-import { api } from '@api';
+import { api, serverApi } from '@api';
 
 export const handle: Handle = async ({ event, resolve }) => {
 	const cookies = cookie.parse(event.request.headers.get('cookie') || '');
@@ -11,8 +11,8 @@ export const handle: Handle = async ({ event, resolve }) => {
 	const accessToken = cookies['immich_access_token'];
 
 	try {
-		api.setAccessToken(accessToken);
-		const { data } = await api.userApi.getMyUserInfo();
+		serverApi.setAccessToken(accessToken);
+		const { data } = await serverApi.userApi.getMyUserInfo();
 		event.locals.user = data;
 
 		return await resolve(event);
diff --git a/web/src/lib/components/album-page/album-viewer.svelte b/web/src/lib/components/album-page/album-viewer.svelte
index b9098f8a84..9d18e1ff0b 100644
--- a/web/src/lib/components/album-page/album-viewer.svelte
+++ b/web/src/lib/components/album-page/album-viewer.svelte
@@ -60,7 +60,7 @@
 	});
 
 	$: {
-		if (album.assets.length < 6) {
+		if (album.assets?.length < 6) {
 			thumbnailSize = Math.floor(viewWidth / album.assets.length - album.assets.length);
 		} else {
 			thumbnailSize = Math.floor(viewWidth / 6 - 6);
diff --git a/web/src/lib/components/shared-components/status-box.svelte b/web/src/lib/components/shared-components/status-box.svelte
index 1fecc700b4..fe92641a9a 100644
--- a/web/src/lib/components/shared-components/status-box.svelte
+++ b/web/src/lib/components/shared-components/status-box.svelte
@@ -82,11 +82,6 @@
 		<div class="text-xs">
 			<p class="text-sm font-medium text-immich-primary">Server</p>
 
-			<input
-				class="border p-2 rounded-md bg-gray-200 mt-2 text-immich-primary font-medium"
-				value={endpoint}
-				disabled={true}
-			/>
 			<div class="flex justify-items-center justify-between mt-2">
 				<p>Status</p>
 
diff --git a/web/src/lib/stores/assets.ts b/web/src/lib/stores/assets.ts
index 35865b022f..107a98763f 100644
--- a/web/src/lib/stores/assets.ts
+++ b/web/src/lib/stores/assets.ts
@@ -29,3 +29,7 @@ export const getAssetsInfo = async () => {
 		console.log('Error [getAssetsInfo]');
 	}
 };
+
+export const setAssetInfo = (data: AssetResponseDto[]) => {
+	assets.set(data);
+};
diff --git a/web/src/lib/utils/file-uploader.ts b/web/src/lib/utils/file-uploader.ts
index edcdcdaa7d..8c1aa6be55 100644
--- a/web/src/lib/utils/file-uploader.ts
+++ b/web/src/lib/utils/file-uploader.ts
@@ -168,7 +168,7 @@ async function fileUploader(asset: File, uploadType: UploadType) {
 			uploadAssetsStore.updateProgress(deviceAssetId, percentComplete);
 		};
 
-		request.open('POST', `${serverEndpoint}/asset/upload`);
+		request.open('POST', `api/asset/upload`);
 
 		request.send(formData);
 	} catch (e) {
diff --git a/web/src/routes/admin/index.svelte b/web/src/routes/admin/index.svelte
index 8da545eba1..641821802d 100644
--- a/web/src/routes/admin/index.svelte
+++ b/web/src/routes/admin/index.svelte
@@ -2,10 +2,12 @@
 	import type { Load } from '@sveltejs/kit';
 	import { api, UserResponseDto } from '@api';
 
-	export const load: Load = async () => {
+	export const load: Load = async ({ fetch }) => {
 		try {
-			const { data: allUsers } = await api.userApi.getAllUsers(false);
-			const { data: user } = await api.userApi.getMyUserInfo();
+			const [user, allUsers] = await Promise.all([
+				fetch('/data/user/get-my-user-info').then((r) => r.json()),
+				fetch('/data/user/get-all-users?isAll=false').then((r) => r.json())
+			]);
 
 			return {
 				status: 200,
diff --git a/web/src/routes/albums/[albumId]/index.svelte b/web/src/routes/albums/[albumId]/index.svelte
index 73d7b2d20f..7f1a2fd506 100644
--- a/web/src/routes/albums/[albumId]/index.svelte
+++ b/web/src/routes/albums/[albumId]/index.svelte
@@ -2,13 +2,15 @@
 	export const prerender = false;
 
 	import type { Load } from '@sveltejs/kit';
-	import { AlbumResponseDto, api } from '@api';
+	import { AlbumResponseDto } from '@api';
 
-	export const load: Load = async ({ params }) => {
+	export const load: Load = async ({ fetch, params }) => {
 		try {
 			const albumId = params['albumId'];
 
-			const { data: albumInfo } = await api.albumApi.getAlbumInfo(albumId);
+			const albumInfo = await fetch(`/data/album/get-album-info?albumId=${albumId}`).then((r) =>
+				r.json()
+			);
 
 			return {
 				status: 200,
diff --git a/web/src/routes/albums/[albumId]/photos/[assetId].svelte b/web/src/routes/albums/[albumId]/photos/[assetId].svelte
index 5a5db2e620..e646a19f55 100644
--- a/web/src/routes/albums/[albumId]/photos/[assetId].svelte
+++ b/web/src/routes/albums/[albumId]/photos/[assetId].svelte
@@ -1,12 +1,10 @@
 <script context="module" lang="ts">
 	export const prerender = false;
-
-	import { api } from '@api';
 	import type { Load } from '@sveltejs/kit';
 
 	export const load: Load = async ({ params }) => {
 		try {
-			await api.userApi.getMyUserInfo();
+			await fetch('/data/user/get-my-user-info');
 		} catch (e) {
 			return {
 				status: 302,
diff --git a/web/src/routes/albums/index.svelte b/web/src/routes/albums/index.svelte
index 0921a786f0..fcd4df23f0 100644
--- a/web/src/routes/albums/index.svelte
+++ b/web/src/routes/albums/index.svelte
@@ -9,10 +9,12 @@
 	import SideBar from '$lib/components/shared-components/side-bar/side-bar.svelte';
 	import { AlbumResponseDto, api } from '@api';
 
-	export const load: Load = async () => {
+	export const load: Load = async ({ fetch }) => {
 		try {
-			const { data: user } = await api.userApi.getMyUserInfo();
-			const { data: albums } = await api.albumApi.getAllAlbums();
+			const [user, albums] = await Promise.all([
+				fetch('/data/user/get-my-user-info').then((r) => r.json()),
+				fetch('/data/album/get-all-albums').then((r) => r.json())
+			]);
 
 			return {
 				status: 200,
diff --git a/web/src/routes/data/README.md b/web/src/routes/data/README.md
new file mode 100644
index 0000000000..9067c01fb2
--- /dev/null
+++ b/web/src/routes/data/README.md
@@ -0,0 +1 @@
+This directory contain SSR endpoints to user serverApi instance to make request directly to DNS
\ No newline at end of file
diff --git a/web/src/routes/data/album/get-album-info.ts b/web/src/routes/data/album/get-album-info.ts
new file mode 100644
index 0000000000..ddb637eec2
--- /dev/null
+++ b/web/src/routes/data/album/get-album-info.ts
@@ -0,0 +1,18 @@
+import { AlbumResponseDto, serverApi } from '@api';
+import type { RequestEvent, RequestHandlerOutput } from '@sveltejs/kit';
+
+export const GET = async ({
+	url
+}: RequestEvent): Promise<RequestHandlerOutput<AlbumResponseDto>> => {
+	try {
+		const albumId = url.searchParams.get('albumId') || '';
+		const { data } = await serverApi.albumApi.getAlbumInfo(albumId);
+		return {
+			body: data
+		};
+	} catch {
+		return {
+			status: 500
+		};
+	}
+};
diff --git a/web/src/routes/data/album/get-all-albums.ts b/web/src/routes/data/album/get-all-albums.ts
new file mode 100644
index 0000000000..3f0fb69b54
--- /dev/null
+++ b/web/src/routes/data/album/get-all-albums.ts
@@ -0,0 +1,18 @@
+import { AlbumResponseDto, serverApi } from '@api';
+import type { RequestEvent, RequestHandler, RequestHandlerOutput } from '@sveltejs/kit';
+
+export const GET = async ({
+	url
+}: RequestEvent): Promise<RequestHandlerOutput<AlbumResponseDto[]>> => {
+	try {
+		const isShared = url.searchParams.get('isShared') === 'true' || undefined;
+		const { data } = await serverApi.albumApi.getAllAlbums(isShared);
+		return {
+			body: data
+		};
+	} catch {
+		return {
+			status: 500
+		};
+	}
+};
diff --git a/web/src/routes/data/asset/get-all-assets.ts b/web/src/routes/data/asset/get-all-assets.ts
new file mode 100644
index 0000000000..d175061f97
--- /dev/null
+++ b/web/src/routes/data/asset/get-all-assets.ts
@@ -0,0 +1,15 @@
+import { AssetResponseDto, serverApi } from '@api';
+import type { RequestHandlerOutput } from '@sveltejs/kit';
+
+export const GET = async (): Promise<RequestHandlerOutput<AssetResponseDto[]>> => {
+	try {
+		const { data } = await serverApi.assetApi.getAllAssets();
+		return {
+			body: data
+		};
+	} catch {
+		return {
+			status: 500
+		};
+	}
+};
diff --git a/web/src/routes/data/user/get-all-users.ts b/web/src/routes/data/user/get-all-users.ts
new file mode 100644
index 0000000000..00a7ecb3ff
--- /dev/null
+++ b/web/src/routes/data/user/get-all-users.ts
@@ -0,0 +1,17 @@
+import { serverApi, UserResponseDto } from '@api';
+import type { RequestEvent, RequestHandlerOutput } from '@sveltejs/kit';
+
+export const GET = async ({url} : RequestEvent): Promise<RequestHandlerOutput<UserResponseDto[]>> => {
+	try {
+    const isAll = url.searchParams.get('isAll') === 'true';
+
+		const { data } = await serverApi.userApi.getAllUsers(isAll);
+		return {
+			body: data
+		};
+	} catch {
+		return {
+			status: 500
+		};
+	}
+};
diff --git a/web/src/routes/data/user/get-my-user-info.ts b/web/src/routes/data/user/get-my-user-info.ts
new file mode 100644
index 0000000000..65cc8c5baa
--- /dev/null
+++ b/web/src/routes/data/user/get-my-user-info.ts
@@ -0,0 +1,15 @@
+import { serverApi, UserResponseDto } from '@api';
+import type { RequestHandlerOutput } from '@sveltejs/kit';
+
+export const GET = async (): Promise<RequestHandlerOutput<UserResponseDto>> => {
+	try {
+		const { data } = await serverApi.userApi.getMyUserInfo();
+		return {
+			body: data
+		};
+	} catch {
+		return {
+			status: 500
+		};
+	}
+};
diff --git a/web/src/routes/index.svelte b/web/src/routes/index.svelte
index 6ade4a468e..188547b830 100644
--- a/web/src/routes/index.svelte
+++ b/web/src/routes/index.svelte
@@ -4,28 +4,31 @@
 	import { api } from '@api';
 
 	export const load: Load = async () => {
-		try {
-			const { data: user } = await api.userApi.getMyUserInfo();
+		if (browser) {
+			try {
+				const { data: user } = await api.userApi.getMyUserInfo();
+
+				return {
+					status: 302,
+					redirect: '/photos'
+				};
+			} catch (e) {}
+
+			const { data } = await api.userApi.getUserCount();
 
 			return {
-				status: 302,
-				redirect: '/photos'
+				status: 200,
+				props: {
+					isAdminUserExist: data.userCount == 0 ? false : true
+				}
 			};
-		} catch (e) {}
-
-		const { data } = await api.userApi.getUserCount();
-
-		return {
-			status: 200,
-			props: {
-				isAdminUserExist: data.userCount == 0 ? false : true
-			}
-		};
+		}
 	};
 </script>
 
 <script lang="ts">
 	import { goto } from '$app/navigation';
+	import { browser } from '$app/env';
 
 	export let isAdminUserExist: boolean;
 
diff --git a/web/src/routes/photos/[assetId].svelte b/web/src/routes/photos/[assetId].svelte
index 0b06c70452..a1c829bf2c 100644
--- a/web/src/routes/photos/[assetId].svelte
+++ b/web/src/routes/photos/[assetId].svelte
@@ -1,12 +1,12 @@
 <script context="module" lang="ts">
 	export const prerender = false;
 
-	import { api } from '@api';
 	import type { Load } from '@sveltejs/kit';
 
-	export const load: Load = async () => {
+	export const load: Load = async ({ fetch }) => {
 		try {
-			await api.userApi.getMyUserInfo();
+			await fetch('/data/user/get-my-user-info');
+
 			return {
 				status: 302,
 				redirect: '/photos'
diff --git a/web/src/routes/photos/index.svelte b/web/src/routes/photos/index.svelte
index 02b7f7f44a..e2182ac01a 100644
--- a/web/src/routes/photos/index.svelte
+++ b/web/src/routes/photos/index.svelte
@@ -2,20 +2,25 @@
 	export const prerender = false;
 
 	import type { Load } from '@sveltejs/kit';
-	import { getAssetsInfo } from '$lib/stores/assets';
+	import { setAssetInfo } from '$lib/stores/assets';
 
-	export const load: Load = async () => {
+	export const load: Load = async ({ fetch }) => {
 		try {
-			const { data } = await api.userApi.getMyUserInfo();
-			await getAssetsInfo();
+			const [userInfo, assets] = await Promise.all([
+				fetch('/data/user/get-my-user-info').then((r) => r.json()),
+				fetch('/data/asset/get-all-assets').then((r) => r.json())
+			]);
+
+			setAssetInfo(assets);
 
 			return {
 				status: 200,
 				props: {
-					user: data
+					user: userInfo
 				}
 			};
 		} catch (e) {
+			console.log('ERROR load photos index');
 			return {
 				status: 302,
 				redirect: '/auth/login'
@@ -33,7 +38,7 @@
 	import moment from 'moment';
 	import AssetViewer from '$lib/components/asset-viewer/asset-viewer.svelte';
 	import { openFileUploadDialog, UploadType } from '$lib/utils/file-uploader';
-	import { api, AssetResponseDto, UserResponseDto } from '@api';
+	import { AssetResponseDto, UserResponseDto } from '@api';
 	import SideBar from '$lib/components/shared-components/side-bar/side-bar.svelte';
 
 	export let user: UserResponseDto;
diff --git a/web/src/routes/sharing/index.svelte b/web/src/routes/sharing/index.svelte
index 2ad725680b..4c6196e577 100644
--- a/web/src/routes/sharing/index.svelte
+++ b/web/src/routes/sharing/index.svelte
@@ -4,10 +4,12 @@
 	import type { Load } from '@sveltejs/kit';
 	import { AlbumResponseDto, api, UserResponseDto } from '@api';
 
-	export const load: Load = async () => {
+	export const load: Load = async ({ fetch }) => {
 		try {
-			const { data: user } = await api.userApi.getMyUserInfo();
-			const { data: sharedAlbums } = await api.albumApi.getAllAlbums(true);
+			const [user, sharedAlbums] = await Promise.all([
+				fetch('/data/user/get-my-user-info').then((r) => r.json()),
+				fetch('/data/album/get-all-albums?isShared=true').then((r) => r.json())
+			]);
 
 			return {
 				status: 200,