wasm-cli 1.6.1__tar.gz → 1.6.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.
Files changed (247) hide show
  1. {wasm_cli-1.6.1/src/wasm_cli.egg-info → wasm_cli-1.6.3}/PKG-INFO +1 -1
  2. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/pyproject.toml +1 -1
  3. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/setup.py +1 -1
  4. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/__init__.py +1 -1
  5. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/webapp.py +32 -253
  6. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/base.py +6 -0
  7. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/docker_compose.py +3 -1
  8. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/permissions.py +12 -2
  9. wasm_cli-1.6.3/src/wasm/deployers/lifecycle.py +371 -0
  10. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/monorepo.py +5 -4
  11. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/apps.py +9 -2
  12. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/hooks.py +5 -44
  13. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/services.py +6 -0
  14. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/jobs.py +40 -29
  15. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/websockets/router.py +8 -1
  16. {wasm_cli-1.6.1 → wasm_cli-1.6.3/src/wasm_cli.egg-info}/PKG-INFO +1 -1
  17. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/SOURCES.txt +1 -0
  18. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/LICENSE +0 -0
  19. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/MANIFEST.in +0 -0
  20. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/README.md +0 -0
  21. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/MONITOR.md +0 -0
  22. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/OBS_SETUP.md +0 -0
  23. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/assets/logo.png +0 -0
  24. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/assets/logo_bg.png +0 -0
  25. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/superpowers/plans/2026-08-13-wasm-competitive-parity-roadmap.md +0 -0
  26. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/superpowers/specs/2026-08-12-wasm-panel-design-direction.md +0 -0
  27. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/superpowers/specs/2026-08-12-wasm-v1-refactor-design.md +0 -0
  28. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/superpowers/specs/2026-08-13-wasm-competitive-parity-design.md +0 -0
  29. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/docs/superpowers/specs/2026-08-14-wasm-panel-design-v2.md +0 -0
  30. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/man/wasm.1 +0 -0
  31. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/setup.cfg +0 -0
  32. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/__main__.py +0 -0
  33. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/__init__.py +0 -0
  34. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/app.py +0 -0
  35. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/__init__.py +0 -0
  36. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/backup.py +0 -0
  37. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/cert.py +0 -0
  38. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/config.py +0 -0
  39. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/db.py +0 -0
  40. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/env.py +0 -0
  41. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/health.py +0 -0
  42. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/monitor.py +0 -0
  43. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/service.py +0 -0
  44. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/setup.py +0 -0
  45. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/site.py +0 -0
  46. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/store.py +0 -0
  47. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/version.py +0 -0
  48. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/commands/web.py +0 -0
  49. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/interactive.py +0 -0
  50. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/panel_links.py +0 -0
  51. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/cli/prompts.py +0 -0
  52. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/completions/README.md +0 -0
  53. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/completions/_wasm +0 -0
  54. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/completions/wasm.bash +0 -0
  55. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/completions/wasm.fish +0 -0
  56. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/__init__.py +0 -0
  57. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/app_state.py +0 -0
  58. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/config.py +0 -0
  59. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/dependencies.py +0 -0
  60. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/exceptions.py +0 -0
  61. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/fs.py +0 -0
  62. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/logger.py +0 -0
  63. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/net.py +0 -0
  64. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/notifier.py +0 -0
  65. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/runner.py +0 -0
  66. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/store.py +0 -0
  67. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/totp.py +0 -0
  68. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/update_checker.py +0 -0
  69. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/core/utils.py +0 -0
  70. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/__init__.py +0 -0
  71. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/auto.py +0 -0
  72. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/__init__.py +0 -0
  73. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/env_manager.py +0 -0
  74. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/health.py +0 -0
  75. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/nginx_config.py +0 -0
  76. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/package_manager.py +0 -0
  77. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/path_resolver.py +0 -0
  78. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/preflight.py +0 -0
  79. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/prisma.py +0 -0
  80. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/registration.py +0 -0
  81. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/summary.py +0 -0
  82. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/turbo.py +0 -0
  83. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/helpers/workspace.py +0 -0
  84. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/interface.py +0 -0
  85. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/nextjs.py +0 -0
  86. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/nodejs.py +0 -0
  87. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/pipeline.py +0 -0
  88. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/python.py +0 -0
  89. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/recorder.py +0 -0
  90. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/registry.py +0 -0
  91. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/static.py +0 -0
  92. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/deployers/vite.py +0 -0
  93. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/main.py +0 -0
  94. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/__init__.py +0 -0
  95. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/apache_manager.py +0 -0
  96. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/backup_manager.py +0 -0
  97. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/backup_scheduler.py +0 -0
  98. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/base_manager.py +0 -0
  99. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/cert_manager.py +0 -0
  100. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/cron_manager.py +0 -0
  101. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/database/__init__.py +0 -0
  102. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/database/base.py +0 -0
  103. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/database/mongodb.py +0 -0
  104. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/database/mysql.py +0 -0
  105. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/database/postgres.py +0 -0
  106. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/database/redis.py +0 -0
  107. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/database/registry.py +0 -0
  108. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/nginx_manager.py +0 -0
  109. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/service_manager.py +0 -0
  110. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/source_manager.py +0 -0
  111. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/managers/webserver.py +0 -0
  112. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/monitor/__init__.py +0 -0
  113. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/monitor/email_notifier.py +0 -0
  114. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/monitor/metrics.py +0 -0
  115. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/monitor/models.py +0 -0
  116. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/monitor/observation_store.py +0 -0
  117. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/monitor/process_monitor.py +0 -0
  118. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/monitor/signals.py +0 -0
  119. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/monitor/timeseries.py +0 -0
  120. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/__init__.py +0 -0
  121. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/apache/proxy.conf.j2 +0 -0
  122. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/apache/static.conf.j2 +0 -0
  123. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/nginx/advanced.conf.j2 +0 -0
  124. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/nginx/monorepo.conf.j2 +0 -0
  125. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/nginx/proxy.conf.j2 +0 -0
  126. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/nginx/static.conf.j2 +0 -0
  127. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/systemd/_escape.j2 +0 -0
  128. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/systemd/app.service.j2 +0 -0
  129. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/systemd/backup-service.j2 +0 -0
  130. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/systemd/backup-timer.j2 +0 -0
  131. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/systemd/cron-service.j2 +0 -0
  132. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/systemd/cron-timer.j2 +0 -0
  133. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/templates/systemd/docker-compose.service.j2 +0 -0
  134. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/validators/__init__.py +0 -0
  135. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/validators/domain.py +0 -0
  136. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/validators/environment.py +0 -0
  137. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/validators/names.py +0 -0
  138. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/validators/port.py +0 -0
  139. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/validators/source.py +0 -0
  140. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/validators/ssh.py +0 -0
  141. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/__init__.py +0 -0
  142. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/__init__.py +0 -0
  143. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/auth.py +0 -0
  144. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/backup_schedules.py +0 -0
  145. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/backups.py +0 -0
  146. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/certs.py +0 -0
  147. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/config.py +0 -0
  148. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/cron.py +0 -0
  149. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/databases.py +0 -0
  150. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/deps.py +0 -0
  151. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/jobs.py +0 -0
  152. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/metrics.py +0 -0
  153. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/monitor.py +0 -0
  154. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/router.py +0 -0
  155. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/sites.py +0 -0
  156. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/api/system.py +0 -0
  157. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/auth.py +0 -0
  158. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/events.py +0 -0
  159. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/metrics_collector.py +0 -0
  160. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/pydantic_compat.py +0 -0
  161. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/server.py +0 -0
  162. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/app.css +0 -0
  163. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/logo.png +0 -0
  164. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/logo.webp +0 -0
  165. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/panel.js +0 -0
  166. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-mono-latin-400-normal.woff2 +0 -0
  167. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-mono-latin-500-normal.woff2 +0 -0
  168. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-sans-latin-400-normal.woff2 +0 -0
  169. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-sans-latin-500-normal.woff2 +0 -0
  170. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/fonts/geist-sans-latin-600-normal.woff2 +0 -0
  171. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/htmx.min.js +0 -0
  172. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/qrcodegen.js +0 -0
  173. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/sse.js +0 -0
  174. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/uplot.min.css +0 -0
  175. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/uplot.min.js +0 -0
  176. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/xterm.css +0 -0
  177. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/static/vendor/xterm.js +0 -0
  178. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/_macros.html +0 -0
  179. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/base.html +0 -0
  180. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/api_tokens.html +0 -0
  181. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/app_charts.html +0 -0
  182. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/app_env.html +0 -0
  183. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/backup_schedule_section.html +0 -0
  184. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/cron_runs.html +0 -0
  185. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/cron_section.html +0 -0
  186. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/db_console.html +0 -0
  187. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/db_engine.html +0 -0
  188. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_form_check.html +0 -0
  189. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_form_options.html +0 -0
  190. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_recent.html +0 -0
  191. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_rollback.html +0 -0
  192. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/deploy_rows.html +0 -0
  193. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/infra_service_editor.html +0 -0
  194. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/infra_service_form.html +0 -0
  195. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/infra_site_editor.html +0 -0
  196. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/infra_site_form.html +0 -0
  197. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/machine.html +0 -0
  198. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/notif_channels.html +0 -0
  199. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/sessions.html +0 -0
  200. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_editor.html +0 -0
  201. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_backups.html +0 -0
  202. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_notifications.html +0 -0
  203. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_paths.html +0 -0
  204. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_ssl.html +0 -0
  205. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_web.html +0 -0
  206. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_form_webserver.html +0 -0
  207. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/settings_section.html +0 -0
  208. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/totp.html +0 -0
  209. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/fragments/webhook_section.html +0 -0
  210. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/login.html +0 -0
  211. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/activity.html +0 -0
  212. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/app.html +0 -0
  213. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/backups.html +0 -0
  214. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/certificates.html +0 -0
  215. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/cron.html +0 -0
  216. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/dashboard.html +0 -0
  217. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/databases.html +0 -0
  218. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/deploy.html +0 -0
  219. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/deployment_detail.html +0 -0
  220. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/deployments.html +0 -0
  221. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/failure.html +0 -0
  222. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/missing.html +0 -0
  223. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/resources.html +0 -0
  224. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/service_editor.html +0 -0
  225. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/service_new.html +0 -0
  226. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/settings.html +0 -0
  227. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/site_editor.html +0 -0
  228. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/templates/pages/site_new.html +0 -0
  229. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/__init__.py +0 -0
  230. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/app_charts.py +0 -0
  231. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/backup_schedules.py +0 -0
  232. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/context.py +0 -0
  233. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/cron.py +0 -0
  234. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/databases.py +0 -0
  235. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/deploy_form.py +0 -0
  236. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/deployments.py +0 -0
  237. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/infrastructure.py +0 -0
  238. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/machine.py +0 -0
  239. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/rendering.py +0 -0
  240. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/resources.py +0 -0
  241. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/router.py +0 -0
  242. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/views/settings_editor.py +0 -0
  243. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm/web/websockets/__init__.py +0 -0
  244. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/dependency_links.txt +0 -0
  245. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/entry_points.txt +0 -0
  246. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/requires.txt +0 -0
  247. {wasm_cli-1.6.1 → wasm_cli-1.6.3}/src/wasm_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wasm-cli
3
- Version: 1.6.1
3
+ Version: 1.6.3
4
4
  Summary: Web App System Management - Deploy and manage web applications on Linux servers
5
5
  Author: Yago López Prado
6
6
  Author-email: Yago López Prado <yago.lopez.adeje@gmail.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wasm-cli"
7
- version = "1.6.1"
7
+ version = "1.6.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="1.6.1",
12
+ version="1.6.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",
@@ -15,7 +15,7 @@ from importlib.metadata import version as _installed_version
15
15
  #: as an OBS build directory. The single source of truth is the ``version``
16
16
  #: field of pyproject.toml; ``scripts/release.py`` keeps this literal and the
17
17
  #: distribution packaging files in step with it.
18
- _FALLBACK_VERSION = "1.6.1"
18
+ _FALLBACK_VERSION = "1.6.3"
19
19
 
20
20
  try:
21
21
  __version__ = _installed_version("wasm-cli")
@@ -24,7 +24,6 @@ from __future__ import annotations
24
24
 
25
25
  import re
26
26
  import sys
27
- import time
28
27
  from argparse import Namespace
29
28
  from collections.abc import Callable
30
29
  from pathlib import Path
@@ -43,18 +42,17 @@ from wasm.core.runner import (
43
42
  CommandResult,
44
43
  get_runner,
45
44
  )
46
- from wasm.core.store import get_store
45
+ from wasm.core.store import DeploymentTrigger, get_store
47
46
  from wasm.core.utils import domain_to_app_name, remove_directory
48
- from wasm.deployers import detect_app_type, get_deployer
47
+ from wasm.deployers import get_deployer
49
48
  from wasm.deployers.docker_compose import DockerComposeDeployer
49
+ from wasm.deployers.lifecycle import update_app
50
50
  from wasm.deployers.monorepo import MonorepoDeployer
51
51
  from wasm.deployers.registry import available_types
52
52
  from wasm.managers.apache_manager import ApacheManager
53
- from wasm.managers.backup_manager import RollbackManager
54
53
  from wasm.managers.cert_manager import CertManager
55
54
  from wasm.managers.nginx_manager import NginxManager
56
55
  from wasm.managers.service_manager import ServiceManager
57
- from wasm.managers.source_manager import SourceManager
58
56
  from wasm.validators.domain import should_include_www, validate_domain
59
57
  from wasm.validators.port import find_available_port, validate_port
60
58
 
@@ -648,8 +646,8 @@ def _update_app(
648
646
  """
649
647
  Rebuild a deployed application from its source, then restart it.
650
648
 
651
- The service is only restarted once the new build succeeded, so a broken
652
- build leaves the previous one serving traffic.
649
+ The sequence itself is :func:`wasm.deployers.lifecycle.update_app`, shared
650
+ with the panel and the git webhook; this only presents it.
653
651
 
654
652
  Args:
655
653
  domain: Application domain.
@@ -664,265 +662,46 @@ def _update_app(
664
662
  Raises:
665
663
  WASMError: When the application is unknown or a step fails.
666
664
  """
667
- config = Config()
668
- store = get_store()
669
-
670
- domain = validate_domain(domain)
671
-
672
- # The store holds the real path, which is what keeps legacy apps deployed
673
- # under a wasm- prefix updatable.
674
- app = store.get_app(domain)
675
-
676
- if app and app.app_path:
677
- app_path = Path(app.app_path)
678
- app_name = app_path.name
679
- else:
680
- app_name = domain_to_app_name(domain)
681
- app_path = config.apps_directory / app_name
682
-
683
- if not app_path.exists():
684
- raise WASMError(
685
- f"Application not found: {domain}",
686
- details=f"Nothing is deployed at {app_path}. Deploy it with: wasm create -d {domain}",
687
- )
688
-
689
665
  logger.header(f"Updating: {domain}")
690
666
  logger.blank()
691
667
 
692
- total_steps = 7
693
-
694
- logger.step(1, total_steps, "Creating pre-update backup")
695
- try:
696
- rollback_manager = RollbackManager(verbose=logger.verbose)
697
- backup = rollback_manager.create_pre_deploy_backup(
698
- domain=domain, description="Pre-update automatic backup"
699
- )
700
- if backup:
701
- logger.substep(f"Backup created: {backup.id}")
702
- else:
703
- logger.substep("No existing app to backup")
704
- except (WASMError, OSError) as e:
705
- logger.substep(f"Backup skipped: {e}")
706
-
707
- source_manager = SourceManager(verbose=logger.verbose)
708
-
709
- if source:
710
- logger.step(2, total_steps, "Fetching from new source")
711
- logger.substep(f"Source: {source}")
712
- # A forced fetch wipes the tree, and the environment file is the one
713
- # thing in it that is not in version control.
714
- env_backup = None
715
- env_file = app_path / ".env"
716
- if env_file.exists():
717
- env_backup = env_file.read_text()
718
-
719
- source_manager.fetch(source, app_path, branch=branch, force=True)
720
-
721
- if env_backup:
722
- env_file.write_text(env_backup)
723
- logger.substep("Restored .env file")
724
- else:
725
- logger.step(2, total_steps, "Pulling latest changes")
726
- source_manager.pull(app_path, branch=branch)
727
-
728
- logger.step(3, total_steps, "Detecting application type")
729
-
730
- # The initial deploy already settled the type; re-detecting can only change
731
- # its mind for the worse on a tree that now has build output in it.
732
- stored_type = app.app_type if app else None
733
- if stored_type and stored_type != "unknown":
734
- app_type = stored_type
735
- logger.substep(f"Detected: {app_type}")
736
- else:
737
- detected = detect_app_type(app_path, verbose=logger.verbose)
738
- if not detected:
739
- app_type = "nodejs"
740
- logger.substep(f"Using default: {app_type}")
741
- else:
742
- app_type = detected
743
- logger.substep(f"Detected: {app_type}")
744
-
745
- if app_type == "monorepo":
746
- return _update_monorepo(app_path, app_name, domain, logger, total_steps)
747
-
748
- if app_type == "docker-compose":
749
- return _update_docker_compose(app_path, app_name, domain, logger)
750
-
751
- deployer = get_deployer(app_type, verbose=logger.verbose)
752
- deployer.configure(
753
- domain=domain,
754
- source=str(app_path),
755
- app_path=app_path,
668
+ outcome = update_app(
669
+ domain,
670
+ source=source,
671
+ branch=branch,
756
672
  package_manager=package_manager,
673
+ trigger=DeploymentTrigger.CLI.value,
674
+ on_phase=logger.step,
675
+ on_step=logger.substep,
676
+ logger=logger,
677
+ verbose=logger.verbose,
757
678
  )
758
679
 
759
- # One call, not a second copy of the deploy pipeline. The deployer reports
760
- # each step as it starts so the numbering here stays the CLI's business.
761
- step = iter(range(4, total_steps + 1))
762
- result = deployer.update(on_step=lambda message: logger.step(next(step), total_steps, message))
763
-
764
- logger.substep(f"Package manager: {result.package_manager}")
765
- if result.prisma_updated:
766
- logger.substep("Prisma updated")
767
-
768
- logger.step(7, total_steps, "Restarting application")
769
- service_manager = ServiceManager(verbose=logger.verbose)
770
-
771
- if result.is_static:
772
- logger.substep("Static application - no service restart needed")
773
- logger.success(f"Application updated successfully: {domain}")
680
+ if outcome.is_static:
681
+ logger.success(f"Application updated successfully: {outcome.domain}")
774
682
  logger.blank()
775
- logger.key_value("Type", "Static")
776
- logger.key_value("Package Manager", result.package_manager)
683
+ logger.key_value("Type", outcome.app_type)
684
+ logger.key_value("Package Manager", outcome.package_manager)
777
685
  return 0
778
686
 
779
- status = service_manager.get_status(app_name)
780
- if not status.get("exists"):
781
- logger.warning("Service not found - application may need to be redeployed")
782
- logger.info(f"Try: wasm create -d {domain}")
687
+ if not outcome.restarted:
688
+ logger.warning("No service found to restart - the application may need to be redeployed")
689
+ logger.info(f"Try: wasm create -d {outcome.domain}")
783
690
  return 0
784
691
 
785
- logger.substep("Minimal downtime during restart...")
786
- service_manager.restart(app_name)
787
-
788
- # systemd reports the unit active the instant it forks, so give the process
789
- # a moment to fail before believing the health check.
790
- time.sleep(2)
791
-
792
- status = service_manager.get_status(app_name)
793
- if status.get("active"):
794
- logger.success(f"Application updated successfully: {domain}")
795
- logger.blank()
796
- logger.key_value("Status", "Running")
797
- logger.key_value("Package Manager", result.package_manager)
798
- if result.prisma_updated:
799
- logger.key_value("Prisma", "Updated")
800
- else:
692
+ if not outcome.active:
801
693
  logger.warning("Application restarted but may not be running correctly")
802
- logger.info(f"Check logs with: wasm logs {domain}")
803
-
804
- return 0
805
-
806
-
807
- def _update_monorepo(
808
- app_path: Path,
809
- app_name: str,
810
- domain: str,
811
- logger: Logger,
812
- total_steps: int,
813
- ) -> int:
814
- """
815
- Rebuild every workspace of a monorepo and restart their services.
816
-
817
- Args:
818
- app_path: Directory holding the application.
819
- app_name: Directory name of the application.
820
- domain: Validated domain.
821
- logger: Logger of the current command.
822
- total_steps: Number of steps reported to the user.
823
-
824
- Returns:
825
- Exit code.
826
-
827
- Raises:
828
- WASMError: When a build step fails.
829
- """
830
- deployer = MonorepoDeployer(verbose=logger.verbose)
831
- deployer.app_path = app_path
832
- deployer.app_name = app_name
833
- deployer.domain = domain
834
- deployer.package_manager = "pnpm"
835
-
836
- logger.step(4, total_steps, "Installing dependencies")
837
- deployer._install_dependencies()
838
-
839
- logger.step(5, total_steps, "Running database migrations")
840
- deployer._run_prisma_migrations()
841
-
842
- logger.step(6, total_steps, "Building applications")
843
- deployer._set_permissions()
844
- deployer._build_all()
845
-
846
- logger.step(7, total_steps, "Restarting applications")
847
- service_manager = ServiceManager(verbose=logger.verbose)
848
-
849
- store = get_store()
850
- app = store.get_app(domain)
851
-
852
- restarted = []
853
- if app:
854
- all_services = store.list_services()
855
- services = [s for s in all_services if s.app_id == app.id]
856
- for service in services:
857
- logger.substep(f"Restarting {service.name}")
858
- try:
859
- service_manager.restart(service.name)
860
- restarted.append(service.name)
861
- except ServiceError as e:
862
- logger.warning(f"Failed to restart {service.name}: {e}")
863
- else:
864
- status = service_manager.get_status(app_name)
865
- if status.get("exists"):
866
- service_manager.restart(app_name)
867
- restarted.append(app_name)
868
-
869
- if restarted:
870
- time.sleep(3)
871
- logger.success(f"Monorepo updated successfully: {domain}")
872
- logger.blank()
873
- for name in restarted:
874
- logger.key_value("Restarted", name)
875
- else:
876
- logger.warning("No services found to restart")
877
- logger.info(f"Try redeploying: wasm create -d {domain}")
878
-
879
- return 0
880
-
881
-
882
- def _update_docker_compose(
883
- app_path: Path,
884
- app_name: str,
885
- domain: str,
886
- logger: Logger,
887
- ) -> int:
888
- """
889
- Rebuild the images of a Docker Compose project and recreate its containers.
890
-
891
- Args:
892
- app_path: Directory holding the application.
893
- app_name: Directory name of the application.
894
- domain: Validated domain.
895
- logger: Logger of the current command.
896
-
897
- Returns:
898
- Exit code.
899
-
900
- Raises:
901
- WASMError: When the compose file cannot be found or a build fails.
902
- """
903
- deployer = DockerComposeDeployer(verbose=logger.verbose)
904
- deployer.app_path = app_path
905
- deployer.app_name = app_name
906
- deployer.domain = domain
907
-
908
- deployer._discover_compose_file()
909
-
910
- logger.step(4, 5, "Rebuilding Docker images")
911
- deployer._build_images()
912
-
913
- logger.step(5, 5, "Restarting containers")
914
- cmd = ["docker", "compose"]
915
- if deployer.compose_path:
916
- cmd.extend(["-f", str(deployer.compose_path)])
917
- cmd.extend(["up", "-d", "--remove-orphans"])
918
- result = get_runner().run(cmd, cwd=app_path, timeout=_COMPOSE_TIMEOUT)
919
-
920
- if result.success:
921
- logger.success(f"Docker Compose app updated: {domain}")
922
- else:
923
- logger.warning("Update may have issues. Check with: docker compose ps")
924
- logger.warning(result.stderr)
694
+ logger.info(f"Check logs with: wasm logs {outcome.domain}")
695
+ return 0
925
696
 
697
+ logger.success(f"Application updated successfully: {outcome.domain}")
698
+ logger.blank()
699
+ logger.key_value("Status", "Running")
700
+ for name in outcome.restarted:
701
+ logger.key_value("Restarted", name)
702
+ logger.key_value("Package Manager", outcome.package_manager)
703
+ if outcome.prisma_updated:
704
+ logger.key_value("Prisma", "Updated")
926
705
  return 0
927
706
 
928
707
 
@@ -1348,6 +1348,12 @@ class BaseDeployer(AppDeployer):
1348
1348
  report("Building")
1349
1349
  self.build()
1350
1350
 
1351
+ # The pull, the install and the build all ran as root, and the
1352
+ # service writes into what they produced: Next.js creates
1353
+ # .next/cache/images on the first optimised image, and uploads land
1354
+ # in directories a pull may have just added.
1355
+ self._set_permissions()
1356
+
1351
1357
  start_command = self.get_start_command()
1352
1358
  result = UpdateResult(
1353
1359
  package_manager=self.package_manager,
@@ -928,7 +928,9 @@ class DockerComposeDeployer(AppDeployer):
928
928
  self._build_images()
929
929
 
930
930
  report("Recreating containers")
931
- result = self._run(self._compose("up", "-d", "--remove-orphans"))
931
+ # Services that name an image instead of building one pull it here,
932
+ # which is a download, not a local recreate.
933
+ result = self._run(self._compose("up", "-d", "--remove-orphans"), timeout=BUILD_TIMEOUT)
932
934
  if not result.success:
933
935
  raise DockerError("Failed to update containers", result.stderr)
934
936
 
@@ -56,15 +56,25 @@ def hand_over_tree(
56
56
  ["chown", "-R", f"{user}:{group}", str(app_path)],
57
57
  timeout=_PERMISSIONS_TIMEOUT,
58
58
  )
59
+ # Not fatal: the build is good, and an app that never writes runs fine. One
60
+ # that does fails with EACCES in its own log, far from here, so this is the
61
+ # only place the operator can be told the cause.
59
62
  if not result.success:
60
- logger.debug(f"chown failed: {result.stderr}")
63
+ logger.warning(
64
+ f"Could not hand {app_path} over to {user}:{group}; the service may fail "
65
+ f"with EACCES: {result.stderr.strip()}"
66
+ )
61
67
 
62
68
  # Directories need the execute bit and the built assets must stay readable
63
69
  # by the web server, whatever umask the fetch and the build left behind.
64
- runner.run(
70
+ result = runner.run(
65
71
  ["chmod", "-R", "u+rwX,g+rX,o+rX", str(app_path)],
66
72
  timeout=_PERMISSIONS_TIMEOUT,
67
73
  )
74
+ if not result.success:
75
+ logger.warning(
76
+ f"Could not make {app_path} readable by the web server: {result.stderr.strip()}"
77
+ )
68
78
 
69
79
  # That -R also put o+r on the .env files, which hold the secrets this
70
80
  # deployment was given. The chown above has just made the service account