wasm-cli 0.15.2__tar.gz → 0.15.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wasm_cli-0.15.2/src/wasm_cli.egg-info → wasm_cli-0.15.3}/PKG-INFO +1 -1
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/pyproject.toml +1 -1
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/setup.py +1 -1
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/__init__.py +1 -1
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/docker_compose.py +49 -26
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/helpers/env_manager.py +1 -1
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/service_manager.py +12 -9
- {wasm_cli-0.15.2 → wasm_cli-0.15.3/src/wasm_cli.egg-info}/PKG-INFO +1 -1
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/LICENSE +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/MANIFEST.in +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/README.md +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/docs/MONITOR.md +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/docs/OBS_SETUP.md +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/docs/assets/logo.png +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/docs/assets/logo_bg.png +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/man/wasm.1 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/setup.cfg +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/__main__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/backup.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/cert.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/config.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/db.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/env.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/health.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/monitor.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/service.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/setup.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/site.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/store.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/version.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/web.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/commands/webapp.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/interactive.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/cli/parser.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/completions/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/completions/_wasm +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/completions/wasm.bash +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/completions/wasm.fish +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/core/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/core/config.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/core/dependencies.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/core/exceptions.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/core/logger.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/core/store.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/core/update_checker.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/core/utils.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/base.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/helpers/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/helpers/nginx_config.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/helpers/package_manager.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/helpers/path_resolver.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/helpers/prisma.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/helpers/turbo.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/helpers/workspace.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/monorepo.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/nextjs.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/nodejs.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/python.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/registry.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/static.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/deployers/vite.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/main.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/apache_manager.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/backup_manager.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/backup_scheduler.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/base_manager.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/cert_manager.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/database/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/database/base.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/database/mongodb.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/database/mysql.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/database/postgres.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/database/redis.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/database/registry.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/nginx_manager.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/managers/source_manager.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/monitor/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/monitor/ai_analyzer.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/monitor/email_notifier.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/monitor/process_monitor.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/monitor/threat_store.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/apache/proxy.conf.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/apache/static.conf.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/nginx/advanced.conf.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/nginx/monorepo.conf.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/nginx/proxy.conf.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/nginx/static.conf.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/systemd/app.service.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/systemd/backup-service.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/systemd/backup-timer.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/templates/systemd/docker-compose.service.j2 +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/validators/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/validators/domain.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/validators/port.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/validators/source.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/validators/ssh.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/apps.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/auth.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/backups.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/certs.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/config.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/databases.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/jobs.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/monitor.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/router.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/services.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/sites.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/api/system.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/auth.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/jobs.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/server.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/css/main.css +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/index.html +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/components/cards.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/components/jobs.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/components/metrics.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/components/skeleton.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/api.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/dialogs.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/notifications.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/router.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/search.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/shortcuts.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/theme.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/ui.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/core/websocket.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/main.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/apps.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/backups.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/certs.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/config.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/dashboard.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/databases.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/jobs.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/logs.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/monitor.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/services.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/js/pages/sites.js +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/login.html +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/logo.png +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/static/logo.webp +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/websockets/__init__.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm/web/websockets/router.py +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm_cli.egg-info/SOURCES.txt +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm_cli.egg-info/dependency_links.txt +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm_cli.egg-info/entry_points.txt +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm_cli.egg-info/requires.txt +0 -0
- {wasm_cli-0.15.2 → wasm_cli-0.15.3}/src/wasm_cli.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "wasm-cli"
|
|
7
|
-
version = "0.15.
|
|
7
|
+
version = "0.15.3"
|
|
8
8
|
description = "Web App System Management - Deploy and manage web applications on Linux servers"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "WASM-NCSAL" }
|
|
@@ -9,7 +9,7 @@ from setuptools import setup, find_packages
|
|
|
9
9
|
|
|
10
10
|
setup(
|
|
11
11
|
name="wasm-cli",
|
|
12
|
-
version="0.15.
|
|
12
|
+
version="0.15.3",
|
|
13
13
|
description="Web App System Management - Deploy and manage web applications on Linux servers",
|
|
14
14
|
author="Yago López Prado",
|
|
15
15
|
author_email="yago.lopez.adeje@gmail.com",
|
|
@@ -216,11 +216,20 @@ class DockerComposeDeployer:
|
|
|
216
216
|
self.compose_profiles = compose_profiles or []
|
|
217
217
|
self.port = port
|
|
218
218
|
|
|
219
|
+
def _is_headless(self) -> bool:
|
|
220
|
+
"""
|
|
221
|
+
Check if the application has no web-facing services.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
True if no services expose ports (headless/worker mode).
|
|
225
|
+
"""
|
|
226
|
+
return not any(svc.is_web for svc in self.services)
|
|
227
|
+
|
|
219
228
|
def deploy(self) -> None:
|
|
220
229
|
"""
|
|
221
230
|
Execute the full deployment workflow.
|
|
222
231
|
|
|
223
|
-
|
|
232
|
+
For web-facing apps (services with ports):
|
|
224
233
|
1. Fetch source code
|
|
225
234
|
2. Discover compose file
|
|
226
235
|
3. Parse compose services
|
|
@@ -231,6 +240,9 @@ class DockerComposeDeployer:
|
|
|
231
240
|
8. Create systemd service
|
|
232
241
|
9. Start and verify
|
|
233
242
|
|
|
243
|
+
For headless/worker apps (no exposed ports):
|
|
244
|
+
Steps 6 and 7 are skipped automatically.
|
|
245
|
+
|
|
234
246
|
Raises:
|
|
235
247
|
DeploymentError: If any deployment step fails.
|
|
236
248
|
"""
|
|
@@ -246,17 +258,26 @@ class DockerComposeDeployer:
|
|
|
246
258
|
self.logger.step(3, total_steps, "Parsing compose services")
|
|
247
259
|
self._parse_compose_services()
|
|
248
260
|
|
|
261
|
+
headless = self._is_headless()
|
|
262
|
+
|
|
249
263
|
self.logger.step(4, total_steps, "Configuring environment")
|
|
250
264
|
self._configure_environment()
|
|
251
265
|
|
|
252
266
|
self.logger.step(5, total_steps, "Building Docker images")
|
|
253
267
|
self._build_images()
|
|
254
268
|
|
|
255
|
-
|
|
256
|
-
|
|
269
|
+
if headless:
|
|
270
|
+
self.logger.step(6, total_steps, "Skipping Nginx (headless worker)")
|
|
271
|
+
self.logger.substep("No services expose ports, web server not needed")
|
|
272
|
+
self.logger.step(7, total_steps, "Skipping SSL (headless worker)")
|
|
273
|
+
self.logger.substep("No web-facing services, certificate not needed")
|
|
274
|
+
self.ssl = False
|
|
275
|
+
else:
|
|
276
|
+
self.logger.step(6, total_steps, "Creating site configuration")
|
|
277
|
+
self._create_site()
|
|
257
278
|
|
|
258
|
-
|
|
259
|
-
|
|
279
|
+
self.logger.step(7, total_steps, "Obtaining SSL certificate")
|
|
280
|
+
self._obtain_certificate()
|
|
260
281
|
|
|
261
282
|
self.logger.step(8, total_steps, "Creating systemd service")
|
|
262
283
|
self._create_systemd_service()
|
|
@@ -273,7 +294,10 @@ class DockerComposeDeployer:
|
|
|
273
294
|
self.logger.key_value("Path", str(self.app_path))
|
|
274
295
|
self.logger.key_value("Compose File", str(self.compose_path.name))
|
|
275
296
|
self.logger.key_value("Services", str(len(self.services)))
|
|
276
|
-
|
|
297
|
+
if headless:
|
|
298
|
+
self.logger.key_value("Mode", "Headless worker (no web server)")
|
|
299
|
+
else:
|
|
300
|
+
self.logger.key_value("SSL", "Yes" if self.ssl else "No")
|
|
277
301
|
|
|
278
302
|
except Exception as e:
|
|
279
303
|
self.logger.error(f"Deployment failed: {e}")
|
|
@@ -285,7 +309,7 @@ class DockerComposeDeployer:
|
|
|
285
309
|
source_manager = SourceManager(verbose=self.verbose)
|
|
286
310
|
source_manager.fetch(
|
|
287
311
|
source=self.source,
|
|
288
|
-
|
|
312
|
+
destination=self.app_path,
|
|
289
313
|
branch=self.branch,
|
|
290
314
|
)
|
|
291
315
|
self.logger.substep(f"Source fetched to {self.app_path}")
|
|
@@ -407,7 +431,7 @@ class DockerComposeDeployer:
|
|
|
407
431
|
if no_cache:
|
|
408
432
|
cmd.append("--no-cache")
|
|
409
433
|
|
|
410
|
-
result = run_command(cmd, cwd=self.app_path, timeout=
|
|
434
|
+
result = run_command(cmd, cwd=self.app_path, timeout=600)
|
|
411
435
|
if not result.success:
|
|
412
436
|
raise DockerError(
|
|
413
437
|
"Failed to build Docker images",
|
|
@@ -561,14 +585,11 @@ class DockerComposeDeployer:
|
|
|
561
585
|
|
|
562
586
|
service_manager.create_service(
|
|
563
587
|
name=self.app_name,
|
|
588
|
+
working_directory=str(self.app_path),
|
|
589
|
+
description=f"Docker Compose app: {self.domain}",
|
|
590
|
+
environment=service_env,
|
|
564
591
|
template="docker-compose",
|
|
565
|
-
|
|
566
|
-
"name": self.app_name,
|
|
567
|
-
"description": f"Docker Compose app: {self.domain}",
|
|
568
|
-
"working_directory": str(self.app_path),
|
|
569
|
-
"environment": service_env,
|
|
570
|
-
"compose_file": compose_file_rel,
|
|
571
|
-
},
|
|
592
|
+
compose_file=compose_file_rel,
|
|
572
593
|
)
|
|
573
594
|
self.logger.substep(f"Created systemd service: {self.app_name}")
|
|
574
595
|
|
|
@@ -638,7 +659,8 @@ class DockerComposeDeployer:
|
|
|
638
659
|
|
|
639
660
|
def _register_app(self) -> None:
|
|
640
661
|
"""Register the application in the WASM store."""
|
|
641
|
-
|
|
662
|
+
headless = self._is_headless()
|
|
663
|
+
primary_port = 0 if headless else self._get_primary_port()
|
|
642
664
|
|
|
643
665
|
app = App(
|
|
644
666
|
domain=self.domain,
|
|
@@ -647,7 +669,7 @@ class DockerComposeDeployer:
|
|
|
647
669
|
branch=self.branch,
|
|
648
670
|
port=primary_port,
|
|
649
671
|
app_path=str(self.app_path),
|
|
650
|
-
webserver=self.webserver,
|
|
672
|
+
webserver="" if headless else self.webserver,
|
|
651
673
|
ssl_enabled=self.ssl,
|
|
652
674
|
status=AppStatus.RUNNING.value,
|
|
653
675
|
env_vars=self.env_vars,
|
|
@@ -676,14 +698,15 @@ class DockerComposeDeployer:
|
|
|
676
698
|
except Exception:
|
|
677
699
|
pass
|
|
678
700
|
|
|
679
|
-
# Remove nginx config
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
nginx.
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
701
|
+
# Remove nginx config (only if web-facing)
|
|
702
|
+
if not self._is_headless():
|
|
703
|
+
try:
|
|
704
|
+
nginx = NginxManager(verbose=self.verbose)
|
|
705
|
+
if nginx.site_exists(self.domain):
|
|
706
|
+
nginx.delete_site(self.domain)
|
|
707
|
+
nginx.reload()
|
|
708
|
+
except Exception:
|
|
709
|
+
pass
|
|
687
710
|
|
|
688
711
|
# Remove app directory
|
|
689
712
|
if self.app_path.exists():
|
|
@@ -791,7 +814,7 @@ class DockerComposeDeployer:
|
|
|
791
814
|
cmd.extend(["-f", str(self.compose_path)])
|
|
792
815
|
cmd.extend(["up", "-d", "--remove-orphans"])
|
|
793
816
|
|
|
794
|
-
result = run_command(cmd, cwd=self.app_path, timeout=
|
|
817
|
+
result = run_command(cmd, cwd=self.app_path, timeout=300)
|
|
795
818
|
if not result.success:
|
|
796
819
|
raise DockerError("Failed to update containers", result.stderr)
|
|
797
820
|
|
|
@@ -113,7 +113,7 @@ class EnvManager:
|
|
|
113
113
|
|
|
114
114
|
# Secret detection patterns
|
|
115
115
|
SECRET_PATTERNS = [
|
|
116
|
-
"PASSWORD", "SECRET", "TOKEN", "API_KEY", "PRIVATE_KEY",
|
|
116
|
+
"PASSWORD", "_PASS", "SECRET", "TOKEN", "API_KEY", "PRIVATE_KEY",
|
|
117
117
|
"ENCRYPTION_KEY", "SIGNING_KEY", "ACCESS_KEY", "SECRET_KEY",
|
|
118
118
|
"CLIENT_SECRET", "WEBHOOK_SECRET",
|
|
119
119
|
]
|
|
@@ -238,41 +238,43 @@ class ServiceManager(BaseManager):
|
|
|
238
238
|
def create_service(
|
|
239
239
|
self,
|
|
240
240
|
name: str,
|
|
241
|
-
command: str,
|
|
242
|
-
working_directory: str,
|
|
241
|
+
command: str = "",
|
|
242
|
+
working_directory: str = "",
|
|
243
243
|
user: Optional[str] = None,
|
|
244
244
|
group: Optional[str] = None,
|
|
245
245
|
environment: Optional[Dict[str, str]] = None,
|
|
246
246
|
description: Optional[str] = None,
|
|
247
247
|
template: str = "app",
|
|
248
|
+
**kwargs,
|
|
248
249
|
) -> bool:
|
|
249
250
|
"""
|
|
250
251
|
Create a new systemd service.
|
|
251
|
-
|
|
252
|
+
|
|
252
253
|
Args:
|
|
253
254
|
name: Service name.
|
|
254
|
-
command: Command to execute.
|
|
255
|
+
command: Command to execute (not required for docker-compose template).
|
|
255
256
|
working_directory: Working directory for the service.
|
|
256
257
|
user: User to run service as.
|
|
257
258
|
group: Group to run service as.
|
|
258
259
|
environment: Environment variables.
|
|
259
260
|
description: Service description.
|
|
260
261
|
template: Template name.
|
|
261
|
-
|
|
262
|
+
**kwargs: Extra context variables passed to the template.
|
|
263
|
+
|
|
262
264
|
Returns:
|
|
263
265
|
True if service was created successfully.
|
|
264
|
-
|
|
266
|
+
|
|
265
267
|
Raises:
|
|
266
268
|
ServiceError: If creation fails.
|
|
267
269
|
"""
|
|
268
270
|
service_name = self._get_service_name(name)
|
|
269
|
-
|
|
271
|
+
|
|
270
272
|
if self.service_exists(name):
|
|
271
273
|
raise ServiceError(f"Service already exists: {service_name}")
|
|
272
|
-
|
|
274
|
+
|
|
273
275
|
if not self.jinja_env:
|
|
274
276
|
raise ServiceError("Template environment not initialized")
|
|
275
|
-
|
|
277
|
+
|
|
276
278
|
# Prepare context
|
|
277
279
|
ctx = {
|
|
278
280
|
"name": service_name,
|
|
@@ -283,6 +285,7 @@ class ServiceManager(BaseManager):
|
|
|
283
285
|
"group": group or self.config.service_group,
|
|
284
286
|
"environment": environment or {},
|
|
285
287
|
}
|
|
288
|
+
ctx.update(kwargs)
|
|
286
289
|
|
|
287
290
|
# Render template
|
|
288
291
|
try:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|