wip - test

This commit is contained in:
Min Idzelis 2024-06-15 12:36:38 +00:00
parent 4fcb757cf5
commit 3cb6ae3560
17 changed files with 271 additions and 32 deletions

2
cli/package-lock.json generated
View File

@ -54,7 +54,7 @@
"@oazapfts/runtime": "^1.0.2"
},
"devDependencies": {
"@types/node": "^20.14.2",
"@types/node": "^20.11.0",
"typescript": "^5.3.3"
}
},

21
docker/Caddyfile Normal file
View File

@ -0,0 +1,21 @@
:443 {
tls internal {
on_demand
}
reverse_proxy immich-web:3000
log {
output file /logs/caddy.log
}
}
:444 {
tls internal {
on_demand
}
reverse_proxy immich-server:3001
log {
output file /logs/caddy.log
}
}

View File

@ -5,6 +5,24 @@
name: immich-dev
services:
nginx:
container_name: nginx_web
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ../web/build:/usr/share/immich-web:ro
ports:
- 5000:80
caddy:
container_name: immich_caddy
image: caddy
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
ports:
- 5001:443
- 5002:444
- 2019:2019
immich-server:
container_name: immich_server
command: ['/usr/src/app/bin/immich-dev']
@ -19,6 +37,7 @@ services:
restart: always
volumes:
- ../server:/usr/src/app
- ../server/node_modules:/usr/src/node_modules
- ../open-api:/usr/src/open-api
- ${UPLOAD_LOCATION}/photos:/usr/src/app/upload
- ${UPLOAD_LOCATION}/photos/upload:/usr/src/app/upload/upload
@ -107,7 +126,22 @@ services:
interval: 5m
start_interval: 30s
start_period: 5m
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
command:
[
'postgres',
'-c',
'shared_preload_libraries=vectors.so',
'-c',
'search_path="$$user", public, vectors',
'-c',
'logging_collector=on',
'-c',
'max_wal_size=2GB',
'-c',
'shared_buffers=512MB',
'-c',
'wal_compression=on',
]
# set IMMICH_METRICS=true in .env to enable metrics
# immich-prometheus:
@ -131,6 +165,7 @@ services:
# - grafana-data:/var/lib/grafana
volumes:
caddy_data:
model-cache:
prometheus-data:
grafana-data:

View File

@ -1,6 +1,14 @@
name: immich-prod
services:
nginx:
container_name: nginx_web
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ../web/build:/usr/share/immich-web:ro
ports:
- 5000:80
immich-server:
container_name: immich_server
image: immich-server:latest
@ -15,6 +23,8 @@ services:
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
environment:
- IMMICH_ENV=production
ports:
- 2283:3001
depends_on:
@ -65,7 +75,22 @@ services:
interval: 5m
start_interval: 30s
start_period: 5m
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
command:
[
'postgres',
'-c',
'shared_preload_libraries=vectors.so',
'-c',
'search_path="$$user", public, vectors',
'-c',
'logging_collector=on',
'-c',
'max_wal_size=2GB',
'-c',
'shared_buffers=512MB',
'-c',
'wal_compression=on',
]
restart: always
# set IMMICH_METRICS=true in .env to enable metrics

40
docker/nginx.conf Normal file
View File

@ -0,0 +1,40 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;\
server {
listen 80;
location / {
root /usr/share/immich-web;
index index.html;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.html break;
}
}
}
}

23
docker/test.yml Normal file
View File

@ -0,0 +1,23 @@
# See:
# - https://immich.app/docs/developer/setup
# - https://immich.app/docs/developer/troubleshooting
name: immich-dev
services:
caddy:
container_name: immich_caddy
image: caddy
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
ports:
- 5001:443
- 2019:2019
volumes:
caddy_data:
model-cache:
prometheus-data:
grafana-data:

2
e2e/package-lock.json generated
View File

@ -88,7 +88,7 @@
"@oazapfts/runtime": "^1.0.2"
},
"devDependencies": {
"@types/node": "^20.14.2",
"@types/node": "^20.11.0",
"typescript": "^5.3.3"
}
},

View File

@ -5,7 +5,7 @@ import { CookieResponse, ImmichCookie } from 'src/dtos/auth.dto';
export const respondWithCookie = <T>(res: Response, body: T, { isSecure, values }: CookieResponse) => {
const defaults: CookieOptions = {
path: '/',
sameSite: 'lax',
sameSite: 'none',
httpOnly: true,
secure: isSecure,
maxAge: Duration.fromObject({ days: 400 }).toMillis(),

View File

@ -1,11 +1,13 @@
import { CorsOptionsCallback, CustomOrigin } from '@nestjs/common/interfaces/external/cors-options.interface';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { json } from 'body-parser';
import cookieParser from 'cookie-parser';
import { NextFunction, Request, Response } from 'express';
import { existsSync } from 'node:fs';
import sirv from 'sirv';
import { ApiModule } from 'src/app.module';
import { envName, excludePaths, isDev, serverVersion, WEB_ROOT } from 'src/constants';
import { WEB_ROOT, envName, excludePaths, isDev, serverVersion } from 'src/constants';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { WebSocketAdapter } from 'src/middleware/websocket.adapter';
import { ApiService } from 'src/services/api.service';
@ -22,8 +24,15 @@ async function bootstrap() {
const port = Number(process.env.IMMICH_PORT) || 3001;
const app = await NestFactory.create<NestExpressApplication>(ApiModule, { bufferLogs: true });
// app.use((req: Request, res: Response, next: NextFunction) => {
// console.log(req.url);
// console.log(req.get('origin'));
// console.log(req.get('host'));
// debugger;
// next();
// });
const logger = await app.resolve<ILoggerRepository>(ILoggerRepository);
//i
logger.setAppName('Api');
logger.setContext('Bootstrap');
app.useLogger(logger);
@ -31,8 +40,32 @@ async function bootstrap() {
app.set('etag', 'strong');
app.use(cookieParser());
app.use(json({ limit: '10mb' }));
debugger; // oddkjkjjh
const origins: CustomOrigin = (_, cb) => {
console.log('hi');
debugger;
cb(null, [
'http://192.168.4.248:2283',
'http://docker-dev:2283',
'https://docker-dev:5002',
'https://192.168.4.248:5001',
]);
};
if (isDev()) {
app.enableCors();
debugger;
app.enableCors((req, cb) => {
if (req.get('origin')) {
cb(null, {
credentials: true,
origin: origins,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
allowedHeaders: ['content-type', '*'],
});
} else {
cb(null, { origin: false });
}
});
}
app.useWebSocketAdapter(new WebSocketAdapter(app));
useSwagger(app);

32
web/nginx.conf Normal file
View File

@ -0,0 +1,32 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}

2
web/package-lock.json generated
View File

@ -74,7 +74,7 @@
"@oazapfts/runtime": "^1.0.2"
},
"devDependencies": {
"@types/node": "^20.14.2",
"@types/node": "^20.11.0",
"typescript": "^5.3.3"
}
},

View File

@ -15,7 +15,8 @@ export const loadUser = async () => {
try {
let user = get(user$);
let preferences = get(preferences$);
if ((!user || !preferences) && hasAuthCookie()) {
debugger;
if (!user || !preferences) {
[user, preferences] = await Promise.all([getMyUser(), getMyPreferences()]);
user$.set(user);
preferences$.set(preferences);

View File

@ -5,20 +5,23 @@ const wait = (ms: number) => new Promise((_, reject) => setTimeout(reject, ms));
const tryServers = async (fetchFn: typeof fetch) => {
const server_urls_env = env.PUBLIC_SERVER_URLS;
if (server_urls_env) {
const servers = server_urls_env.split(',');
// servers are in priority order, try in parallel, use first success
const fetchers = servers.map((url) => ({ url, fetcher: fetchFn(`${url}/server-info/config`) }));
for (const { url, fetcher } of fetchers) {
try {
const response = (await Promise.race([fetcher, wait(1000)])) as Response;
if (response?.ok) {
defaults.basePath = url;
return true;
}
} catch {
// ignore, handled upstream
let servers = server_urls_env.split(',');
servers = ['https://docker-dev:5002/api'];
// servers = [];
// servers are in priority order, try in parallel, use first success
const fetchers = servers.map((url) => ({ url, fetcher: fetchFn(`${url}/server-info/config`) }));
for (const { url, fetcher } of fetchers) {
try {
const response = (await Promise.race([fetcher, wait(1000)])) as Response;
if (response?.ok) {
debugger;
defaults.baseUrl = url;
defaults.credentials = 'include';
return true;
}
} catch {
// ignore, handled upstream
}
}

View File

@ -7,8 +7,16 @@ import type { LayoutLoad } from './$types';
export const ssr = false;
export const csr = true;
export const prerender = true;
export const load = (async ({ fetch }) => {
for (const { code, loader } of langs) {
register(code, loader);
}
const preferenceLang = get(lang);
await init({ fallbackLocale: preferenceLang === 'dev' ? 'dev' : defaultLang.code, initialLocale: preferenceLang });
let hasError = false;
try {
await initSDK(fetch);
@ -17,14 +25,6 @@ export const load = (async ({ fetch }) => {
hasError = true;
}
for (const { code, loader } of langs) {
register(code, loader);
}
const preferenceLang = get(lang);
await init({ fallbackLocale: preferenceLang === 'dev' ? 'dev' : defaultLang.code, initialLocale: preferenceLang });
return {
hasError,
meta: {

View File

@ -1,4 +1,5 @@
import { AppRoute } from '$lib/constants';
import { initSDK } from '$lib/utils/server';
import { getServerConfig } from '@immich/sdk';
import { redirect } from '@sveltejs/kit';
import { t } from 'svelte-i18n';
@ -10,6 +11,14 @@ export const ssr = false;
export const csr = true;
export const load = (async () => {
let hasError = false;
try {
await initSDK(fetch);
} catch {
// error pages use page layouts, so can't throw error - catch it and display error message in layout.
hasError = true;
}
debugger;
const authenticated = await loadUser();
if (authenticated) {
redirect(302, AppRoute.PHOTOS);
@ -24,6 +33,7 @@ export const load = (async () => {
const $t = get(t);
return {
hasError,
meta: {
title: $t('welcome') + ' 🎉',
description: $t('immich_web_interface'),

View File

@ -5,8 +5,18 @@ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
preprocess: vitePreprocess(),
kit: {
prerender: {
handleHttpError: ({ path, referrer, message }) => {
if (path === '/custom.css') {
return;
}
// otherwise fail the build
throw new Error(message);
},
},
adapter: adapter({
fallback: 'index.html',
// fallback: 'index.html',
precompress: true,
}),
alias: {

View File

@ -13,6 +13,9 @@ const upstream = {
};
export default defineConfig({
build: {
minify: false,
},
resolve: {
alias: {
'xmlhttprequest-ssl': './node_modules/engine.io-client/lib/xmlhttprequest.js',
@ -27,6 +30,9 @@ export default defineConfig({
'/.well-known/immich': upstream,
'/custom.css': upstream,
},
cors: {
origin: false,
},
},
plugins: [
sveltekit(),