diff --git a/e2e/0005-guest-dashboard.spec.ts b/e2e/0005-guest-dashboard.spec.ts index 1abeb53d78..f7d20fa32c 100644 --- a/e2e/0005-guest-dashboard.spec.ts +++ b/e2e/0005-guest-dashboard.spec.ts @@ -1,6 +1,5 @@ import { expect, test } from '@playwright/test'; -import { app } from '../packages/backend/src/core/database/drizzle/schema'; -import { loginUser } from './fixtures/fixtures'; +import { installApp, loginUser } from './fixtures/fixtures'; import { clearDatabase, db } from './helpers/db'; import { setSettings } from './helpers/settings'; @@ -21,45 +20,29 @@ test('user can activate the guest dashboard and see it when logged out', async ( await expect(page.getByText('No apps to display')).toBeVisible(); }); -test('logged out users can see the apps on the guest dashboard', async ({ browser }) => { +test('logged out users can see the apps on the guest dashboard', async ({ page, context }) => { + await loginUser(page, context); + const store = await db.query.appStore.findFirst(); - await db.insert(app).values({ - config: {}, - isVisibleOnGuestDashboard: true, - id: `hello-world_${store?.id}`, - exposed: true, - exposedLocal: true, - domain: 'duckduckgo.com', - status: 'running', - openPort: true, - }); - await db.insert(app).values({ - config: {}, - openPort: true, - isVisibleOnGuestDashboard: false, - id: `actual-budget_${store?.id}`, - exposed: false, - exposedLocal: false, - status: 'running', - }); - - const context = await browser.newContext(); - const page = await context.newPage(); + if (!store) { + throw new Error('No store found'); + } - await loginUser(page, context); - await page.goto('/settings'); + await installApp(page, store?.id, 'nginx', { visibleOnGuestDashboard: true, domain: 'duckduckgo.com' }); + await installApp(page, store?.id, '2fauth', { visibleOnGuestDashboard: false }); + await page.goto('/settings'); await page.getByRole('tab', { name: 'Settings' }).click(); await page.getByLabel('guestDashboard').setChecked(true); await page.getByRole('button', { name: 'Update settings' }).click(); await page.getByTestId('logout-button').click(); - await expect(page.getByText(/Hello World web server/)).toBeVisible(); - const locator = page.locator('text=Actual Budget'); + await expect(page.getByText(/Open-source simple and fast web server/)).toBeVisible(); + const locator = page.locator('text=2Fauth'); await expect(locator).not.toBeVisible(); - await page.getByRole('link', { name: /Hello World/ }).click(); + await page.getByRole('link', { name: /Nginx/ }).click(); const [newPage] = await Promise.all([context.waitForEvent('page'), page.getByRole('menuitem', { name: 'duckduckgo.com' }).click()]); diff --git a/e2e/fixtures/fixtures.ts b/e2e/fixtures/fixtures.ts index bf6abcd70d..799c406cc9 100644 --- a/e2e/fixtures/fixtures.ts +++ b/e2e/fixtures/fixtures.ts @@ -27,3 +27,31 @@ export const loginUser = async (page: Page, _: BrowserContext) => { await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible(); }; + +type InstallAppOpts = { + visibleOnGuestDashboard?: boolean; + domain?: string; +}; + +export const installApp = async (page: Page, storeId: number, appId: string, opts: InstallAppOpts = {}) => { + await page.goto(`/app-store/${storeId}/${appId}`); + + // Install app + await page.getByRole('button', { name: 'Install' }).click(); + + await expect(page.getByText('Display on guest dashboard')).toBeVisible(); + + if (opts.visibleOnGuestDashboard) { + await page.getByLabel('isVisibleOnGuestDashboard').setChecked(true); + } + + if (opts.domain) { + await page.getByLabel('exposed', { exact: true }).setChecked(true); + await page.getByPlaceholder('Domain name').fill(opts.domain); + } + + await page.getByRole('button', { name: 'Install' }).click(); + + await expect(page.getByText('Installing')).toBeVisible(); + await expect(page.getByText('Running')).toBeVisible({ timeout: 60000 }); +}; diff --git a/packages/backend/src/modules/app-lifecycle/app-lifecycle-command.factory.ts b/packages/backend/src/modules/app-lifecycle/app-lifecycle-command.factory.ts index 487091f1e4..a00aa0efd1 100644 --- a/packages/backend/src/modules/app-lifecycle/app-lifecycle-command.factory.ts +++ b/packages/backend/src/modules/app-lifecycle/app-lifecycle-command.factory.ts @@ -4,7 +4,6 @@ import type { z } from 'zod'; import { AppFilesManager } from '../apps/app-files-manager'; import { AppHelpers } from '../apps/app.helpers'; import { BackupManager } from '../backups/backup.manager'; -import { DockerComposeBuilder } from '../docker/builders/compose.builder'; import { DockerService } from '../docker/docker.service'; import { EnvUtils } from '../env/env.utils'; import { MarketplaceService } from '../marketplace/marketplace.service'; @@ -30,7 +29,6 @@ export class AppLifecycleCommandFactory { private readonly dockerService: DockerService, private readonly backupManager: BackupManager, private readonly marketplaceService: MarketplaceService, - private readonly dockerComposeBuilder: DockerComposeBuilder, ) {} createCommand(eventData: z.infer) { @@ -38,89 +36,36 @@ export class AppLifecycleCommandFactory { switch (command) { case 'install': - return new InstallAppCommand( - this.logger, - this.appFilesManager, - this.dockerService, - this.marketplaceService, - this.dockerComposeBuilder, - this.appHelpers, - this.envUtils, - ); + return new InstallAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers, this.envUtils); case 'start': - return new StartAppCommand( - this.logger, - this.appFilesManager, - this.dockerService, - this.marketplaceService, - this.dockerComposeBuilder, - this.appHelpers, - ); + return new StartAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers); case 'stop': - return new StopAppCommand( - this.logger, - this.appFilesManager, - this.dockerService, - this.marketplaceService, - this.dockerComposeBuilder, - this.appHelpers, - ); + return new StopAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers); case 'restart': - return new RestartAppCommand( - this.logger, - this.appFilesManager, - this.dockerService, - this.marketplaceService, - this.dockerComposeBuilder, - this.appHelpers, - ); + return new RestartAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers); case 'uninstall': - return new UninstallAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.dockerComposeBuilder); + return new UninstallAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService); case 'reset': - return new ResetAppCommand( - this.logger, - this.appFilesManager, - this.dockerService, - this.marketplaceService, - this.dockerComposeBuilder, - this.appHelpers, - this.envUtils, - ); + return new ResetAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers, this.envUtils); case 'backup': - return new BackupAppCommand( - this.logger, - this.appFilesManager, - this.dockerService, - this.marketplaceService, - this.dockerComposeBuilder, - this.backupManager, - ); + return new BackupAppCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.backupManager); case 'restore': return new RestoreAppCommand( this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, - this.dockerComposeBuilder, this.backupManager, eventData.filename, ); case 'generate_env': - return new GenerateAppEnvCommand( - this.logger, - this.appFilesManager, - this.dockerService, - this.marketplaceService, - this.dockerComposeBuilder, - this.appHelpers, - ); + return new GenerateAppEnvCommand(this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, this.appHelpers); case 'update': return new UpdateAppCommand( this.logger, this.appFilesManager, this.dockerService, this.marketplaceService, - this.dockerComposeBuilder, this.appHelpers, this.backupManager, eventData.performBackup, diff --git a/packages/backend/src/modules/app-lifecycle/commands/backup-app-command.ts b/packages/backend/src/modules/app-lifecycle/commands/backup-app-command.ts index 14a7fef7cd..6558cfb259 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/backup-app-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/backup-app-command.ts @@ -1,7 +1,6 @@ import { LoggerService } from '@/core/logger/logger.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import { BackupManager } from '@/modules/backups/backup.manager'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { DockerService } from '@/modules/docker/docker.service'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; import { AppLifecycleCommand } from './command'; @@ -12,10 +11,9 @@ export class BackupAppCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly backupManager: BackupManager, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); this.logger = logger; this.appFilesManager = appFilesManager; diff --git a/packages/backend/src/modules/app-lifecycle/commands/command.ts b/packages/backend/src/modules/app-lifecycle/commands/command.ts index f249850dfb..8d95b6ce89 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/command.ts @@ -14,7 +14,6 @@ export class AppLifecycleCommand { protected appFilesManager: AppFilesManager, protected dockerService: DockerService, protected marketplaceService: MarketplaceService, - protected dockerComposeBuilder: DockerComposeBuilder, ) {} protected async ensureAppDir(appId: string, form: AppEventFormInput): Promise { @@ -31,7 +30,8 @@ export class AppLifecycleCommand { try { const { services } = dynamicComposeSchema.parse(composeJson.content); const { storeId } = extractAppId(appId); - const composeFile = this.dockerComposeBuilder.getDockerCompose(services, form, storeId); + const dockerComposeBuilder = new DockerComposeBuilder(); + const composeFile = dockerComposeBuilder.getDockerCompose(services, form, storeId); await this.appFilesManager.writeDockerComposeYml(appId, composeFile); } catch (err) { diff --git a/packages/backend/src/modules/app-lifecycle/commands/generate-env-command.ts b/packages/backend/src/modules/app-lifecycle/commands/generate-env-command.ts index e8b5a121d1..758e7546cd 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/generate-env-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/generate-env-command.ts @@ -1,7 +1,6 @@ import type { LoggerService } from '@/core/logger/logger.service'; import type { AppFilesManager } from '@/modules/apps/app-files-manager'; import type { AppHelpers } from '@/modules/apps/app.helpers'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import type { DockerService } from '@/modules/docker/docker.service'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; import type { AppEventFormInput } from '@/modules/queue/entities/app-events'; @@ -13,10 +12,9 @@ export class GenerateAppEnvCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly appHelpers: AppHelpers, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); } public async execute(appId: string, form: AppEventFormInput): Promise<{ success: boolean; message: string }> { diff --git a/packages/backend/src/modules/app-lifecycle/commands/install-app-command.ts b/packages/backend/src/modules/app-lifecycle/commands/install-app-command.ts index 1d7609ec73..155fc40919 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/install-app-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/install-app-command.ts @@ -1,7 +1,6 @@ import { LoggerService } from '@/core/logger/logger.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import { AppHelpers } from '@/modules/apps/app.helpers'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { DockerService } from '@/modules/docker/docker.service'; import { EnvUtils } from '@/modules/env/env.utils'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; @@ -14,11 +13,10 @@ export class InstallAppCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly appHelpers: AppHelpers, private readonly envUtils: EnvUtils, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); } public async execute(appId: string, form: AppEventFormInput): Promise<{ success: boolean; message: string }> { diff --git a/packages/backend/src/modules/app-lifecycle/commands/reset-app-command.ts b/packages/backend/src/modules/app-lifecycle/commands/reset-app-command.ts index add2d611bf..f9448a1f9c 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/reset-app-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/reset-app-command.ts @@ -1,7 +1,6 @@ import { LoggerService } from '@/core/logger/logger.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import { AppHelpers } from '@/modules/apps/app.helpers'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { DockerService } from '@/modules/docker/docker.service'; import type { EnvUtils } from '@/modules/env/env.utils'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; @@ -14,11 +13,10 @@ export class ResetAppCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly appHelpers: AppHelpers, private readonly envUtils: EnvUtils, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); } public async execute(appId: string, form: AppEventFormInput): Promise<{ success: boolean; message: string }> { diff --git a/packages/backend/src/modules/app-lifecycle/commands/restart-app-command.ts b/packages/backend/src/modules/app-lifecycle/commands/restart-app-command.ts index f8addd53ec..9438670fe6 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/restart-app-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/restart-app-command.ts @@ -1,7 +1,6 @@ import { LoggerService } from '@/core/logger/logger.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import { AppHelpers } from '@/modules/apps/app.helpers'; -import type { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { DockerService } from '@/modules/docker/docker.service'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; import type { AppEventFormInput } from '@/modules/queue/entities/app-events'; @@ -13,10 +12,9 @@ export class RestartAppCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly appHelpers: AppHelpers, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); } public async execute(appId: string, form: AppEventFormInput, skipEnvGeneration = false): Promise<{ success: boolean; message: string }> { diff --git a/packages/backend/src/modules/app-lifecycle/commands/restore-app-command.ts b/packages/backend/src/modules/app-lifecycle/commands/restore-app-command.ts index 672c8b1922..ec2b9f251b 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/restore-app-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/restore-app-command.ts @@ -1,7 +1,6 @@ import { LoggerService } from '@/core/logger/logger.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import { BackupManager } from '@/modules/backups/backup.manager'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { DockerService } from '@/modules/docker/docker.service'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; import { AppLifecycleCommand } from './command'; @@ -12,11 +11,10 @@ export class RestoreAppCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly backupManager: BackupManager, private readonly filename: string, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); } public async execute(appId: string): Promise<{ success: boolean; message: string }> { diff --git a/packages/backend/src/modules/app-lifecycle/commands/start-app-command.ts b/packages/backend/src/modules/app-lifecycle/commands/start-app-command.ts index 1759911bd5..1c97b0b47f 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/start-app-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/start-app-command.ts @@ -1,7 +1,6 @@ import { LoggerService } from '@/core/logger/logger.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import { AppHelpers } from '@/modules/apps/app.helpers'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { DockerService } from '@/modules/docker/docker.service'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; import type { AppEventFormInput } from '@/modules/queue/entities/app-events'; @@ -13,10 +12,9 @@ export class StartAppCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly appHelpers: AppHelpers, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); this.logger = logger; this.appFilesManager = appFilesManager; diff --git a/packages/backend/src/modules/app-lifecycle/commands/stop-app-command.ts b/packages/backend/src/modules/app-lifecycle/commands/stop-app-command.ts index c0dda40c03..1206ca6557 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/stop-app-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/stop-app-command.ts @@ -1,7 +1,6 @@ import { LoggerService } from '@/core/logger/logger.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import { AppHelpers } from '@/modules/apps/app.helpers'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { DockerService } from '@/modules/docker/docker.service'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; import type { AppEventFormInput } from '@/modules/queue/entities/app-events'; @@ -13,10 +12,9 @@ export class StopAppCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly appHelpers: AppHelpers, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); } public async execute(appId: string, form: AppEventFormInput, skipEnvGeneration = false) { diff --git a/packages/backend/src/modules/app-lifecycle/commands/update-app-command.ts b/packages/backend/src/modules/app-lifecycle/commands/update-app-command.ts index b347d55866..0982f4e281 100644 --- a/packages/backend/src/modules/app-lifecycle/commands/update-app-command.ts +++ b/packages/backend/src/modules/app-lifecycle/commands/update-app-command.ts @@ -2,7 +2,6 @@ import { LoggerService } from '@/core/logger/logger.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import type { AppHelpers } from '@/modules/apps/app.helpers'; import type { BackupManager } from '@/modules/backups/backup.manager'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { DockerService } from '@/modules/docker/docker.service'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; import type { AppEventFormInput } from '@/modules/queue/entities/app-events'; @@ -14,12 +13,11 @@ export class UpdateAppCommand extends AppLifecycleCommand { appFilesManager: AppFilesManager, dockerService: DockerService, marketplaceService: MarketplaceService, - dockerComposeBuilder: DockerComposeBuilder, private readonly appHelpers: AppHelpers, private readonly backupManager: BackupManager, private readonly performBackup: boolean = true, ) { - super(logger, appFilesManager, dockerService, marketplaceService, dockerComposeBuilder); + super(logger, appFilesManager, dockerService, marketplaceService); } public async execute(appId: string, form: AppEventFormInput) { diff --git a/packages/backend/src/modules/apps/apps.service.ts b/packages/backend/src/modules/apps/apps.service.ts index b85dad4cc2..cde981805d 100644 --- a/packages/backend/src/modules/apps/apps.service.ts +++ b/packages/backend/src/modules/apps/apps.service.ts @@ -28,7 +28,9 @@ export class AppsService { const updateInfo = await this.marketplaceService.getAppUpdateInfo(app.id).catch((_) => { return { latestVersion: 0, latestDockerVersion: '0.0.0' }; }); + if (!appInfo) { + this.logger.debug(`App ${app.id} not found in app files`); return null; } return { app, info: appInfo, updateInfo }; diff --git a/packages/backend/src/modules/docker/builders/compose.builder.ts b/packages/backend/src/modules/docker/builders/compose.builder.ts index 4694d34ced..12b982eb23 100644 --- a/packages/backend/src/modules/docker/builders/compose.builder.ts +++ b/packages/backend/src/modules/docker/builders/compose.builder.ts @@ -1,5 +1,4 @@ import type { AppEventFormInput } from '@/modules/queue/entities/app-events'; -import { Injectable } from '@nestjs/common'; import * as yaml from 'yaml'; import { type Service, type ServiceInput, serviceSchema } from './schemas'; import { type BuiltService, ServiceBuilder } from './service.builder'; @@ -11,24 +10,23 @@ interface Network { external: boolean; } -@Injectable() export class DockerComposeBuilder { private services: Record = {}; private networks: Record = {}; - addService(service: BuiltService) { + private addService(service: BuiltService) { this.services[service.container_name] = service; return this; } - addServices(services: BuiltService[]) { + private addServices(services: BuiltService[]) { for (const service of services) { this.addService(service); } return this; } - addNetwork(network: Network) { + private addNetwork(network: Network) { this.networks[network.key || network.name] = { name: network.name, external: network.external, @@ -36,25 +34,13 @@ export class DockerComposeBuilder { return this; } - build() { + private build() { return yaml.stringify({ services: this.services, networks: this.networks, }); } - public getDockerCompose = (services: ServiceInput[], form: AppEventFormInput, storeId: string) => { - const myServices = services.map((service) => this.buildService(serviceSchema.parse(service), form, storeId)); - - const dockerCompose = this.addServices(myServices).addNetwork({ - key: 'tipi_main_network', - name: 'runtipi_tipi_main_network', - external: true, - }); - - return dockerCompose.build(); - }; - private buildService = (params: Service, form: AppEventFormInput, storeId: string) => { const service = new ServiceBuilder(); service @@ -98,4 +84,16 @@ export class DockerComposeBuilder { return service.build(); }; + + public getDockerCompose = (services: ServiceInput[], form: AppEventFormInput, storeId: string) => { + const myServices = services.map((service) => this.buildService(serviceSchema.parse(service), form, storeId)); + + const dockerCompose = this.addServices(myServices).addNetwork({ + key: 'tipi_main_network', + name: 'runtipi_tipi_main_network', + external: true, + }); + + return dockerCompose.build(); + }; } diff --git a/packages/backend/src/modules/docker/docker.module.ts b/packages/backend/src/modules/docker/docker.module.ts index 91d127ef11..bb7c7857a0 100644 --- a/packages/backend/src/modules/docker/docker.module.ts +++ b/packages/backend/src/modules/docker/docker.module.ts @@ -2,12 +2,11 @@ import { SocketModule } from '@/core/socket/socket.module'; import { Module } from '@nestjs/common'; import { AppStoreModule } from '../app-stores/app-store.module'; import { AppsModule } from '../apps/apps.module'; -import { DockerComposeBuilder } from './builders/compose.builder'; import { DockerService } from './docker.service'; @Module({ imports: [AppsModule, AppStoreModule, SocketModule], - providers: [DockerService, DockerComposeBuilder], - exports: [DockerService, DockerComposeBuilder], + providers: [DockerService], + exports: [DockerService], }) export class DockerModule {} diff --git a/packages/backend/src/tests/integration/app-lifecycle.test.ts b/packages/backend/src/tests/integration/app-lifecycle.test.ts index 439d5cd67e..101470c31e 100644 --- a/packages/backend/src/tests/integration/app-lifecycle.test.ts +++ b/packages/backend/src/tests/integration/app-lifecycle.test.ts @@ -12,7 +12,6 @@ import { AppStoreService } from '@/modules/app-stores/app-store.service'; import { AppFilesManager } from '@/modules/apps/app-files-manager'; import { AppHelpers } from '@/modules/apps/app.helpers'; import { AppsRepository } from '@/modules/apps/apps.repository'; -import { DockerComposeBuilder } from '@/modules/docker/builders/compose.builder'; import { EnvUtils } from '@/modules/env/env.utils'; import { MarketplaceService } from '@/modules/marketplace/marketplace.service'; import { AppEventsQueue, appEventResultSchema, appEventSchema } from '@/modules/queue/entities/app-events'; @@ -64,7 +63,6 @@ describe('App lifecycle', () => { AppsRepository, EnvUtils, AppHelpers, - DockerComposeBuilder, { provide: DatabaseService, useValue: databaseService,