Vibe coding a VestaCP alternative

mikhomikho AdministratorOG Bash Me Gently

This is a placeholder for things to come.

It will be a journey, and I want you all with me.
I will make some decisions that probably will make you all question me as a person.

Well, we all have our preferences; sometimes we don't agree, and that is fine.
The initial plan for this "fun" project is to vibe-code most parts. Manual edits of files will be kept at a minimum.

I will share some of the prompts, often the larger ones that make a lot of changes to the codebase.
Plans will be shared here, and of course the GitHub URL.

All when available.
I'm writing this to let you know about the plan. I hope there will be some updates later tonight.
Right now I have other pressing business to attend to.

“Technology is best when it brings people together.” – Matt Mullenweg

Comments

  • Enjoy ! Have fun ! And enjoy again .

    I believe in good luck. Harder that I work ,luckier i get.

  • AnthonySmithAnthonySmith AdministratorProviderOG

    This is going to be fun.

    TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
    FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/

  • edited August 25

    Vibe the vibe, it will be fun :D

    BillingServ - Easy, simple, and hassle-free online invoicing solution. Contact us today.
    White Label VPN | Software Licensing Billing | WHMCS Alternative

  • FalzoFalzo Senpai

    Best of luck :-)

  • @mikho said: The initial plan for this "fun" project is to vibe-code most parts.

    What set up are you planning to use? agent, model, expected costs?

  • mikhomikho AdministratorOG Bash Me Gently

    @cmeerw said:

    @mikho said: The initial plan for this "fun" project is to vibe-code most parts.

    What set up are you planning to use? agent, model, expected costs?

    This will be coded by Claude, my AI-assistant. The models and efforts will vary, depending on how many tokens I have left on my company account.

    I had very little time this evening, so I started by putting on the Plan hat on Claude, feeding this prompt.

     I'm planning on rewriting the web hosting panel which has the code in this github repository: [https://github.com/outroll/vesta](https://github.com/outroll/vesta)
    
    I ran a control of the code and the report can be found here:  [https://claude.ai/code/artifact/02e8efc5-13e6-4ba2-9edc-a51139a391c8?org=70e79a25-81f8-4951-9038-c9caa45b0fc2](https://claude.ai/code/artifact/02e8efc5-13e6-4ba2-9edc-a51139a391c8?org=70e79a25-81f8-4951-9038-c9caa45b0fc2)
    
    The codebase will be done with latest, stable version of Laravel and React.
    
    The UI should be similar to the original project but the backend should be completly re-written because of all the vulnerbilities and bad decisions made in the original code.
    
    Act like a senior technical lead managing a real engineering team.
    
    Before writing code:
    
    - Ask clarifying questions
    - Challenge bad decisions
    - Identify scaling risks
    - Suggest better approaches
    - Prioritize simplicity
    
    Think long-term like someone responsible for maintaining this product for 5+ years.
    
    Then provide:
    
    - Technical decisions
    - Tradeoff analysis
    - Recommended architecture
    - Implementation plan
    - Production-ready solution
    
    "You are now 4 elite Al agents working together on the same project:
    
    - Architect
    - Engineer
    - Reviewer
    - Optimizer
    
    Each agent has a specific role:
    
    - Architect → Design scalable system architecture
    - Engineer → Build the implementation
    - Reviewer → Perform senior-level code review
    - Optimizer → Improve performance and scalability
    
    Workflow: Architect designs the system
    
    Engineer builds it
    
    Reviewer critiques and improves it Optimizer makes it production-grade Finally provide:
    
    - Complete architecture
    - Full implementation
    - Review feedback
    - Final optimized version
    
    Think and collaborate like a world-class engineering team building a real startup product.
    

    And after many, long, boring minutes ..... this plan was formed, almost 2500 words.

    Plan: LESta Hosting Control Plane Rewrite

    TL;DR: Rebuild the Vesta product as a Laravel 13.17 and React 19 control plane, preserving the compact hosting-panel workflows while replacing privileged PHP shell execution, flat-file state, wildcard sudo, and executable queues. The first implementation milestone is a complete web-hosting vertical slice on Ubuntu LTS with a Go node agent boundary. Mail remains an MVP capability, but is isolated as a separately gated subsystem because it carries the highest abuse and operational risk.

    Steps

    Phase 0, decisions and product contract

    1. Pin the legacy Vesta reference commit and create a capability matrix from src/react/src/containers/ControlPanelContent, src/react/src/components/MainNav, web/inc/i18n/en.php, web/add, web/edit, web/delete, web/suspend, web/api/v1, bin/v-*, data/packages, and data/users. Record resource fields, lifecycle verbs, quotas, suspension semantics, role visibility, and cross-resource effects. Treat the Claude artifact as supplementary only because it is not publicly readable from this environment.
    2. Define the supported first-release environment: Ubuntu LTS, one managed node, self-hosted web/DNS/mail/database services, provider administrators plus customers, fresh installs, no billing, and no promise of importing existing Vesta installations. Reserve a later migration tool, but do not let compatibility force unsafe legacy behavior into the new runtime.
    3. Write the threat model and trust boundaries before host integration: browser to Laravel, Laravel to agent, agent to operating system/services, tenant to tenant, and backup/secret storage. Establish non-negotiable prohibitions: no generic RunCommand, no arbitrary command-plus-arguments API, no exec from controllers, no wildcard sudo, no raw user filesystem paths, no secrets in props/logs/job payloads, and no executable queue files.
    4. Resolve the database decision as an explicit ADR. MySQL/MariaDB is a confirmed requirement, so target MySQL 8.4 or MariaDB 11 compatibility, use strict SQL modes, foreign keys, indexed ownership/status/name fields, transactional outbox tables, and application-level constraints where PostgreSQL-specific features would otherwise be tempting. Revisit PostgreSQL only if reporting, locking, or JSON/query requirements prove materially painful.

    Phase 1, control-plane foundation

    1. Extend the existing Laravel foundation with relational aggregates for accounts, memberships, roles, permissions, hosting packages, package limits, nodes, node capabilities, IP allocations, audit events, idempotency receipts, outbox messages, and provisioning operations. Keep authentication identity separate from hosting ownership and resource state.
    2. Keep Fortify, passkeys, email verification, 2FA, secure session rotation, login throttling, password confirmation, and reauthentication for destructive actions. Add deny-by-default policies for provider administrators, customer accounts, and every owned resource. Do not reproduce Vesta's implicit session.look user switching without an explicit, audited impersonation model.
    3. Build application actions and query services behind thin controllers. Every mutation validates and authorizes at the boundary, updates desired state transactionally, writes an audit record, creates an idempotency receipt where appropriate, and dispatches provisioning work after commit. Use named route/controller contracts and regenerate Wayfinder after route changes.
    4. Define a versioned node protocol. Each operation has a named capability, strict schema, resource ID, desired-state version, idempotency key, deadline, request digest, correlation ID, and structured result. The agent authenticates using short-lived bootstrap exchange followed by per-node mTLS with certificate rotation and revocation.

    Phase 2, first vertical slice, web hosting

    1. Model web hosting with normalized domains, aliases, node assignment, IP allocation, web template reference, certificate metadata, suspension state, provisioning state, desired-state version, observed-state digest, and usage snapshots. Normalize DNS names and IDN input, enforce package quotas, and preserve Vesta's user-visible lifecycle without preserving its shell command names.
    2. Implement WebProvisioner and a fake adapter first, followed by the Go agent capability for staged configuration rendering, ownership and permission assignment, syntax validation, atomic activation, service reload, health check, and rollback. Laravel must never execute host commands directly. Operations must be bounded, idempotent, retryable, observable, and safe after lost responses.
    3. Add authenticated Inertia routes and React pages for web-domain list, create, edit, suspension, deletion, search, pagination, and provisioning status. Use the existing app layout and UI primitives, typed Wayfinder helpers, Inertia forms, validation errors, flash notifications, loading/empty/error states, responsive tables, and explicit destructive-action confirmation.
    4. Add focused Pest coverage for authentication, policy denial, tenant isolation, domain normalization, uniqueness, quota enforcement, lifecycle transitions, transaction rollback, after-commit dispatch, idempotency, fake adapter payloads, redacted logs, and provisioning failure visibility. Add browser coverage for the primary list/create/edit workflow and JavaScript-error smoke checks when browser tooling is available.

    Phase 3, core resource slices

    1. Add DNS as a full slice with zones, records, nameservers, type-specific validation, ownership policies, suspension behavior, and a typed DNS provisioner. Validate duplicate/conflicting records, generated configuration, eventual failure, retry, drift, and rollback.
    2. Add mail as a separate capability group, not incidental domain CRUD. Model mail domains, accounts, aliases, forwarding, autoreplies, quotas, DKIM keys, TLS settings, delivery queue state, abuse controls, and credential rotation. Isolate Exim/Dovecot, spam/antivirus, DKIM material, mail queues, and mailbox storage on the node. Require rate limits, bounce/abuse monitoring, resource quotas, secret redaction, and explicit operational health gates before enabling self-hosted mail for customers.
    3. Add managed databases with database hosts, database instances, encrypted credential metadata, type/charset/host validation, rotation, quota enforcement, queued create/drop/update operations, and no credential exposure through Inertia responses or logs. Use native database protocols or a tightly scoped agent capability, never interpolated SQL from user input.
    4. Add cron with normalized schedule fields, ownership, status, suspension behavior, execution history, and an explicitly defined command policy. Prefer a catalog of supported tasks or an isolated account-scoped runner. Reject privileged commands, unsafe interpreters, unbounded output, and cross-account paths.

    Phase 4, higher-risk operations

    1. Add filesystem access only through an account-root abstraction. Canonicalize paths, reject traversal, symlink and hard-link escapes, special files, unsafe archives, excessive depth, and unbounded transfer sizes. Stream uploads/downloads, audit changes, and keep file manager permissions separate from host-agent privilege.
    2. Add backups and restores with encrypted, integrity-checked, versioned artifacts in object storage, retention policy, access control, resumable transfer, isolated restore staging, and recurring restore drills. Replace Vesta pipe files and process scans with scheduler-dispatched unique jobs, durable states, backoff, dead-letter handling, and notifications.
    3. Add provider operations for nodes, capabilities, service health, IP pools, controlled firewall rules, status/restart/config-test actions, and package/template administration. Restrict these to operator policies, explicit capability allowlists, concurrency locks, rollback, and a complete audit trail. Defer unrestricted service editors and arbitrary firewall rules until separate threat models pass review.
    4. Add usage and statistics as incremental snapshots and read models, not repeated scans or manual counters. Paginate large histories and logs, eager-load dashboard relationships, and monitor queue backlog, node heartbeat age, mail queue depth, backup throughput, config failures, drift count, and lock contention.

    Phase 5, frontend parity and operations

    1. Extend the existing Inertia shell with role-aware navigation, account context, breadcrumbs, resource counters, search, notifications, and asynchronous operation feedback. Preserve Vesta's vocabulary and compact list/detail/add/edit workflow, but use modern accessibility, responsive behavior, keyboard support, and clear state transitions.
    2. Organize reusable React code under resources/js/components/{web,dns,mail,databases,cron,files,server,backups} and page props under resources/js/types. Use generated @/routes and @/actions for every backend call. Keep global Inertia props limited to authenticated identity, current account, permissions needed for navigation, and flash data.
    3. Run Laravel statelessly behind HTTPS. Use MySQL/MariaDB for authoritative state, Redis for queues/cache/locks/rate limiting, and object storage for backups and large artifacts. Operate scheduler and workers independently with health checks, bounded concurrency, retries, dead-letter states, metrics, centralized structured logs, and alerting.
    4. Replace curl-to-root installation with a signed, pinned deployment process for the control plane and Go agent. Publish checksums and SBOMs, verify provenance, use staged upgrades and health checks, retain rollback generations, and never silently replace an existing host configuration.

    Phase 6, review, optimization, and release

    1. The Reviewer gate checks authorization matrices, tenant escape, CSRF, MFA, rate limits, replay rejection, schema fuzzing, injection resistance, path/archive attacks, secret redaction, mail abuse controls, backup access, certificate rotation, signed-update rejection, and least-privilege agent permissions.
    2. The Optimizer gate checks MySQL query plans and indexes, N+1 behavior, pagination, queue throughput, per-node serialization, batching/debouncing of config changes, large artifact streaming, cache invalidation, noisy-neighbor limits, and horizontal control-plane scaling.
    3. Add CI checks for migrations, Pint, PHPStan, ESLint, Prettier, TypeScript, focused Pest suites, full tests, production Vite build, dependency/security scanning, and agent tests. Rehearse empty-database deployment, node bootstrap, agent offline behavior, duplicate delivery, lost response after mutation, invalid config rollback, disk-full handling, backup restore, and release rollback.
    4. Only after shadow/reconciliation and failure drills succeed should a later migration tool import Vesta data. It should be idempotent, dry-run by default, produce a field/error report, and never execute imported commands or trust imported paths. Legacy API deprecation and removal are outside the first vertical slice and require a separate cutover plan.

    Relevant files
    - /Users/mikho/Herd/LESta/composer.json and /Users/mikho/Herd/LESta/package.json, current Laravel 13.17, Inertia 3, React 19, Fortify, Wayfinder, Pest, and Tailwind 4 baseline. Do not add dependencies without approval.
    - /Users/mikho/Herd/LESta/routes/web.php and /Users/mikho/Herd/LESta/routes/settings.php, authenticated Inertia route boundaries and settings conventions.
    - /Users/mikho/Herd/LESta/app/Models/User.php and /Users/mikho/Herd/LESta/app/Http/Middleware/HandleInertiaRequests.php, identity and minimal shared props.
    - /Users/mikho/Herd/LESta/app/Actions/Fortify/, /Users/mikho/Herd/LESta/config/fortify.php, and /Users/mikho/Herd/LESta/app/Providers/FortifyServiceProvider.php, existing authentication extension points.
    - /Users/mikho/Herd/LESta/database/migrations/, /Users/mikho/Herd/LESta/database/factories/, and /Users/mikho/Herd/LESta/app/Models/, ordered schema, factories, relationships, casts, and lifecycle state.
    - /Users/mikho/Herd/LESta/app/Http/Controllers/, /Users/mikho/Herd/LESta/app/Http/Requests/, /Users/mikho/Herd/LESta/app/Policies/, and /Users/mikho/Herd/LESta/app/Actions/, thin HTTP boundaries, validation, authorization, and use cases.
    - /Users/mikho/Herd/LESta/app/Jobs/, /Users/mikho/Herd/LESta/app/Events/, /Users/mikho/Herd/LESta/app/Listeners/, /Users/mikho/Herd/LESta/app/Console/Commands/, and /Users/mikho/Herd/LESta/routes/console.php, durable provisioning, outbox processing, usage, backups, and scheduler integration.
    - /Users/mikho/Herd/LESta/app/Contracts/ and /Users/mikho/Herd/LESta/app/Services/, typed provisioner contracts, agent client, idempotency, secrets, path safety, and query/read services.
    - /Users/mikho/Herd/LESta/resources/js/app.tsx, /Users/mikho/Herd/LESta/resources/js/layouts/, /Users/mikho/Herd/LESta/resources/js/pages/, /Users/mikho/Herd/LESta/resources/js/components/, /Users/mikho/Herd/LESta/resources/js/types/, and /Users/mikho/Herd/LESta/resources/css/app.css, the existing Inertia shell, pages, reusable UI, types, and theme.
    - /Users/mikho/Herd/LESta/resources/js/routes/, /Users/mikho/Herd/LESta/resources/js/actions/, and /Users/mikho/Herd/LESta/resources/js/wayfinder/, generated route/controller contracts, never hand-edited.
    - /Users/mikho/Herd/LESta/tests/Pest.php, /Users/mikho/Herd/LESta/tests/Feature/, /Users/mikho/Herd/LESta/tests/Unit/, and /Users/mikho/Herd/LESta/tests/Browser/, feature, unit, architecture, and browser coverage.
    - /Users/mikho/Herd/LESta/.github/workflows/, CI and release checks. The Go agent should be a separately versioned deployable component, not embedded in Laravel request execution.
    - Legacy references: https://github.com/outroll/vesta paths bin/, web/api/v1/, data/packages/, data/users/, install/, src/deb/, src/rpm/, and src/react/src/. Use them for contract extraction only, never as implementation templates.

    Verification
    1. Before implementation, approve the threat model, capability matrix, MySQL/MariaDB version target, Ubuntu LTS version, mail stack support matrix, and first-slice acceptance criteria.
    2. For the web slice, run the narrow Pest tests first, then Pint, PHPStan, ESLint, Prettier, TypeScript, Wayfinder generation, and the production Vite build.
    3. Assert every mutation is policy-authorized, transactionally persisted, dispatched after commit, idempotent under retry, serialized per resource/node where required, and visible as a structured provisioning state.
    4. Run security tests for tenant isolation, CSRF, MFA gates, rate limiting, command injection, path traversal, archive extraction, secret redaction, agent authentication, replay, and privilege boundaries.
    5. Run reliability tests for duplicate operations, lost responses, offline agents, stale versions, invalid service configuration, rollback, partial subsystem failure, disk-full, backup corruption, and restore.
    6. Manually verify the primary React workflow at desktop and mobile widths, role-aware navigation, loading/error/empty states, destructive confirmations, dark mode, accessibility, and absence of browser JavaScript errors.
    7. Before production, rehearse signed installation, node bootstrap, database migration, queue/scheduler health, backup restore, alerting, rollback, and controlled feature enablement.

    Decisions
    - The requested first release is core hosting plus self-hosted mail, not billing.
    - Deployment starts as one Ubuntu LTS node but every resource is node-assigned and the protocol is multi-node ready.
    - Provider administrators and customers are the initial tenancy model. Reseller nesting is reserved until the account/membership model is proven.
    - MySQL/MariaDB is a hard requirement. PostgreSQL is not used unless a later ADR changes the decision.
    - A Go system service is the recommended node-agent implementation.
    - Fresh installs are the initial migration strategy. Vesta import/coexistence is later and dry-run first.
    - Web hosting is the first implementation milestone. Mail is MVP scope but must be gated behind its own capability, threat model, and operational readiness review.
    - Preserve UI vocabulary, navigation patterns, and resource workflows. Do not preserve legacy URLs, shell command names, flat-file state, or unsafe privilege assumptions.
    - No production implementation should begin until this plan is approved. No commit or branch creation is part of this plan.

    Tradeoff analysis
    - MySQL/MariaDB meets the stated requirement and is familiar in hosting environments, but PostgreSQL would provide stronger native constraints and more flexible reporting primitives. The design compensates with strict schema constraints, indexed relational read models, and explicit application services.
    - A Go agent adds a second deployable component and release pipeline, but it creates the necessary privilege boundary and keeps Laravel horizontally scalable. A PHP/Bash adapter would be faster only for a prototype and would recreate the main risk.
    - Self-hosted mail preserves Vesta parity and customer control, but it creates abuse, reputation, deliverability, storage, and incident-response obligations. It is therefore isolated, quota-limited, observable, and gated rather than mixed into generic domain provisioning.
    - A relational source of truth plus asynchronous reconciliation is more complex than direct config writes, but it enables transactions, retries, auditing, drift detection, rollback, multi-node growth, and recoverable failures.

    Scope boundaries
    - Included in the plan: authentication, authorization, accounts, packages, quotas, web, DNS, mail, databases, cron, backups, node health, typed provisioning, audit, responsive React UI, testing, and production operations.
    - Excluded from the first implementation slice: billing, Vesta import, broad OS support, reseller nesting, unrestricted file manager, arbitrary firewall/service editors, plugin marketplace, and full multi-node failover.
    - The current environment does not contain the legacy Vesta checkout, and the linked Claude artifact is unavailable without access. Exact field mappings and vulnerability claims must be confirmed against a pinned commit and representative production data before migration work.

    Tomorrow I will read all these words, form an opinion on the content, and probably run a couple of more prompts on it before any code is written.

    Question to the audience .... should the original UI be kept or should a more modern UI be built?

    “Technology is best when it brings people together.” – Matt Mullenweg

  • jarlandjarland ProviderOG
    edited August 25

    I've been accused of "vibe coding" enough that I have to defend myself in advance every time I talk about it. I do not "vibe code" anything that meets two requirements: public facing, contains or can access anything of consequence.

    But when the job is something where you compromising it just makes me laugh and delete it, it's super fun to just explain what you want, sit back, and watch it go. It's easily as entertaining as a good movie. I've got a ton of projects just sitting in a folder that were vibe coded just to see what the AI could do on its own. Sometimes they're even useful because the AI figured out a way to do something that you were struggling with, so you get to take that concept back to production code.

    Do everything as though everyone you’ll ever know is watching.

  • FritzFritz Behlnd you

    Can I also share some of Vibe Coded Server Panel I found for your references?

  • mikhomikho AdministratorOG Bash Me Gently

    @Fritz said:
    Can I also share some of Vibe Coded Server Panel I found for your references?

    Sure, why not.

    “Technology is best when it brings people together.” – Matt Mullenweg

  • FritzFritz Behlnd you

    @mikho said:

    @Fritz said:
    Can I also share some of Vibe Coded Server Panel I found for your references?

    Sure, why not.

    I'm not sure if this fits to your topic, but here you go:

    https://github.com/BrowserlessAPI/VortexPanel
    

    100% Vibe Coding.

  • mikhomikho AdministratorOG Bash Me Gently

    @Fritz said:

    @mikho said:

    @Fritz said:
    Can I also share some of Vibe Coded Server Panel I found for your references?

    Sure, why not.

    I'm not sure if this fits to your topic, but here you go:

    https://github.com/BrowserlessAPI/VortexPanel
    

    100% Vibe Coding.

    Thanks!
    I’m sure there are keywords in there that I can use when writing the prompts.
    Don’t want to miss out on the security and features.

    “Technology is best when it brings people together.” – Matt Mullenweg

  • This sounds like a fun project to follow, especially with the decision to keep manual code changes to a minimum. A VestaCP alternative built in the open should attract plenty of opinions once the first parts start taking shape. Sharing the larger prompts and design decisions will also be interesting since those choices often have as much impact as the code itself. Looking forward to seeing what you end up with.

  • @mikho said:

    Question to the audience .... should the original UI be kept or should a more modern UI be built?

    I like the simplicity of the original UI, but a subtle refresh might not hurt.

  • mikhomikho AdministratorOG Bash Me Gently

    @rcy026 said:

    @mikho said:

    Question to the audience .... should the original UI be kept or should a more modern UI be built?

    I like the simplicity of the original UI, but a subtle refresh might not hurt.

    Thats my thoughts exactly.
    No icons to keep things fast and simple, just text. Properly formatted.

    “Technology is best when it brings people together.” – Matt Mullenweg

  • mikhomikho AdministratorOG Bash Me Gently

    Step two.

    I had a little extra time while waiting for a meeting to start, so I took a jab at the first prompt and result.

    My native language is not English; it's Swedish, so my first step after creating the plan was to have a second project in Claude with a short instruction.

    This is the project folder (path to local directory with the documentation (ie markdown files)). I will write prompts in Swedish; translate them to English for me to use in my coding project.

    This is the translation of my prompt:

    The file LESta-rewrite-plan.md contains the plan for a rewrite of the webhosting panel VestaCP.
    The working name of the project is LESta, loosely based on the id that came from the site https://lowendspirit.com and the original name VestaCP.
    In this project, I will give instructions for you to write correct and well-thought-out prompts in English based on my information.

    Based on the plan's layout, create a folder called ".install", in this directory all installation scripts for the underlying services should be located.

    Based on the plan's layout, check in detail the layout regarding the installation of underlying services, how these configuration files should be handled based on the project's end goal.

    Plan and decide in which order services should be handled.
    Should all installation scripts be created first and then build the intelligence for the connection between the UI and the services, or should the UI be created first and then, continuously create installation scripts and intelligence per service?

    an extremly long second prompt including service installation layer, .install directory, and build sequencing decision

    With the plan laid out in LESta-rewrite-plan.md, do not start implementing service features yet. This step resolves the part of the plan that is still underspecified: how the underlying host services are installed, how their configuration files are owned and rendered over the product's lifetime, in what order the services are taken on, and whether the installation layer or the UI layer is built first.

    Read LESta-rewrite-plan.md in full first and treat it as the governing document. Where anything below conflicts with the plan, say so explicitly instead of silently resolving it.

    Role

    Continue as the four-agent team defined in the first prompt: Architect designs, Engineer specifies the concrete artifacts, Reviewer attacks the result for security and operational failure modes, Optimizer checks it for long-term maintenance cost. Act as a senior technical lead who will own this product for five or more years. Challenge weak decisions in the plan rather than implementing them faithfully. Prioritize simplicity, and prefer fewer moving parts over cleverness.

    Objective

    Produce a reviewed, decided, and documented service installation and configuration architecture for LESta, plus the .install directory that will hold it, plus a decided build order. This is a design and scaffolding step. The only code written in this step is the scaffolding, contracts, and at most one reference implementation that proves the contract, as decided in Task 4.

    Task 1, audit the plan's installation and configuration story

    The plan commits to a Go node agent, to Laravel never executing host commands, to staged rendering with syntax validation, atomic activation, reload, health check, and rollback (step 10), and to replacing curl-to-root installation with a signed, pinned deployment process that publishes checksums and SBOMs and never silently replaces existing host configuration (step 24). It does not yet say how a bare Ubuntu LTS node gets nginx, Apache, BIND, Exim, Dovecot, MariaDB, ClamAV, SpamAssassin, cron, the firewall, and ACME tooling in the first place, nor who owns the resulting files on disk for the rest of the product's life.

    Go through the plan in detail and answer, with reasoning:

    Bootstrap versus runtime. Draw the exact boundary between one-time host bootstrap, which installs packages and lays down a hardened baseline, and continuous runtime provisioning, which renders per-tenant configuration on every mutation. State which of the two .install owns. State what must never leak across that boundary. In particular, confirm or refute that the control plane must never invoke an .install script, directly or through the agent, at request time, and explain what mechanism prevents it from being reintroduced later.
    Language and ownership of the installer. The plan already introduces a Go agent as a deployable component. Decide whether the installers are POSIX shell scripts, a Go subcommand of the agent, a declarative manifest consumed by the agent, or a combination, and justify the choice against auditability, offline installation, operator trust, testability, and the cost of maintaining a second toolchain. If shell is chosen, say why the agent is not the better home.
    Configuration file ownership model. Given that MySQL/MariaDB is the authoritative desired state and the on-node configuration is a derived artifact, specify precisely:
    which files LESta owns and will overwrite without warning, which files it reads but never writes, and which files it must refuse to touch,
    how LESta-owned configuration is namespaced away from distribution defaults and from operator edits, for example include directories and drop-in fragments per service rather than rewriting the main configuration file,
    how generated files are staged, validated, activated atomically, and rolled back, and where the previous generation is retained,
    how observed-state digests detect drift when an operator edits a generated file by hand, and what the product does when it finds drift, including whether it reconciles, warns, or refuses,
    how templates are versioned so that an upgrade of LESta can re-render every existing tenant's configuration safely,
    how secrets inside configuration, DKIM private keys, database credentials, ACME account keys, are stored, permissioned, rotated, and kept out of logs, backups in plaintext, Inertia props, and job payloads.
    Idempotency and re-run semantics. Specify what happens when an installer is run twice, run against a partially installed node, run after a failed run, run against a node where an administrator has already installed a conflicting package or service, and run during an upgrade to a newer LESta release. Define whether installation is convergent or one-shot, and how a failed installation is unwound.
    Capability registration. The plan models node capabilities in step 5 and a versioned capability-named node protocol in step 8. Specify how a completed installation registers the capability it enables, how the control plane learns that a node can now serve a given resource type, and how a capability is marked degraded or withdrawn when a service is unhealthy.
    Gaps and corrections. List every place where the plan's installation and configuration story is incomplete, internally inconsistent, or would push unsafe legacy Vesta behavior back into the new runtime. Propose the correction. Do not defend the plan for its own sake.
    Task 2, create the .install directory

    Create a directory named .install in the repository root, /mikho/LESta/.install/. This directory is the single home for all installation logic for the underlying services.

    Requirements:

    Design the internal structure so that each service is self-contained and discoverable, and so that a shared base layer, for example package repositories, system users, directory layout, TLS trust, and firewall baseline, is expressed once rather than copied per service. Propose the layout and justify it. Include where per-service configuration templates live, and whether they live beside the installer in .install or in the runtime agent's own asset tree, and why.
    Write a .install/README.md that states the purpose of the directory, the boundary from Task 1, the execution model, and the rule that nothing in the application ever calls these scripts at request time.
    Write a written installer contract that every service installer must satisfy, and that is testable. At minimum it must cover: non-interactive and unattended execution, no network fetch of unpinned code, no curl | bash, explicit version pinning and checksum verification of anything downloaded, deterministic exit-code semantics, structured machine-readable output so the control plane can record the result, a required dry-run mode, a preflight check that verifies OS release, architecture, free disk, ports, and conflicting packages before any change is made, logging to a known location with secrets redacted, and a declared list of the capabilities the installer provides and depends on.
    Add a per-service metadata manifest format so that dependency order, provided capabilities, required capabilities, supported Ubuntu LTS releases, and the packages and ports touched are declared as data rather than encoded in script order.
    Verify that a dot-prefixed directory is actually workable here. Confirm it is tracked by git, not excluded by .gitignore, .gitattributes, export-ignore rules, Vite or Composer packaging, or the release artifact build. If the dot prefix creates a real risk of the directory being silently dropped from a build or overlooked by an operator, say so and recommend the alternative rather than quietly complying.

    Do not write the full set of service installers in this step. Which installers get written, and when, is the output of Task 4.

    Task 3, decide the service order

    Decide and justify the order in which the underlying services are taken on, from a bare Ubuntu LTS node to a complete panel. Produce a dependency graph, not just a list.

    Account for at least:

    the base layer that everything else assumes,
    that MySQL/MariaDB appears twice, once as the control plane's own authoritative store and once as the managed database service offered to tenants, and whether those are the same instance, and what the security consequence is either way,
    the web server, and whether the first release supports nginx, Apache, both, or nginx as a proxy in front of Apache as the original does, and what that choice costs in template surface,
    ACME and certificate issuance, including whether it is a separate service in the order or a property of the web service, and how issuance is rate limited and retried,
    DNS, and its ordering relationship to certificate issuance and to mail,
    cron, and the command policy the plan requires in step 16,
    the firewall, and whether a baseline is part of the base layer while tenant-visible rules stay deferred as the plan requires in step 19,
    mail last, isolated behind its own capability gate, threat model, and operational readiness review, as the plan requires in steps 14 and 19,
    backups, statistics, and node health, and where they fall relative to the rest.

    For each service state the ordering rationale, the hard prerequisites, the risk it introduces, and the acceptance gate that must pass before the next service starts. Explicitly call out any place where the plan's phase order and the installation dependency order disagree, and say which one wins.

    Task 4, decide the build sequencing strategy

    Decide, and justify, between these strategies, or a better one you can defend:

    A, installation layer first. Write every service installer and the full configuration contract for all services, then build the UI and the control plane intelligence that couples the UI to the services on top of a finished service layer.
    B, UI first. Build the React and Inertia surface across resource types first against fake adapters, then add installers and coupling intelligence per service afterwards.
    C, vertical slice per service. For one service at a time, take the whole chain to done, installer, configuration rendering, agent capability, provisioner contract, control plane actions, UI, and tests, before starting the next service.

    Requirements for this decision:

    Reconcile your answer with the plan, which already commits to a web-hosting vertical slice as the first implementation milestone in Phase 2 and builds WebProvisioner against a fake adapter before the real Go agent capability. If your recommendation deviates from that commitment, justify the deviation explicitly and state what in the plan must change.
    Evaluate each strategy against: time to a demonstrable working product, the risk of designing the wrong contract before any real service has been touched, rework cost, the ability to test without a live node, the cost of context switching between Laravel, React, Go, and shell, the risk of a half-finished installation layer rotting before it is ever exercised, and the fact that this is a single developer project rather than a staffed team.
    Name the alternatives you rejected and the specific reason each was rejected.
    Produce a concrete phased sequence with entry and exit criteria per phase, mapped onto the service order from Task 3 and onto the plan's existing phase numbering. Say what is built in the first phase down to the artifact level.
    State what must be true for you to revisit the decision later, so the decision is falsifiable rather than permanent by default.
    Non-negotiable constraints

    These come from the plan and hold for everything produced here:

    No generic RunCommand, no arbitrary command-plus-arguments API, no exec from controllers, no wildcard sudo, no raw user filesystem paths, no secrets in props, logs, or job payloads, no executable queue files.
    Laravel never executes host commands. Every host effect goes through a named, schema-validated, idempotent, bounded, observable agent capability.
    Ubuntu LTS, single managed node in the first release, but every resource is node-assigned and the protocol stays multi-node ready.
    MySQL/MariaDB is the authoritative store. PostgreSQL is out unless a later ADR changes it.
    Do not add dependencies without approval. Do not create commits or branches. Do not begin production implementation of service features in this step.
    Legacy Vesta is a contract reference only, never an implementation template. Its install/, src/deb/, and src/rpm/ trees may be read to extract what a working panel actually needs on a host, and must not be ported.
    Deliverables
    An ADR-style decision document written to the repository, covering Task 1's answers, Task 3's service order with its dependency graph, and Task 4's sequencing decision, each with tradeoffs and rejected alternatives stated.
    The .install directory, its README.md, the installer contract, the per-service manifest format, the shared base layer definition, and the directory skeleton for every planned service.
    A written specification of the configuration file ownership and rendering model from Task 1, item 3, precise enough that two different implementers would produce the same on-disk result.
    Whatever installer or slice Task 4's decision says should exist first, and nothing beyond it.
    A short list of the open questions that need my approval before implementation continues, phrased as decisions with options rather than open-ended questions.
    Verification
    Show that the .install directory is tracked by git and survives the release artifact build.
    Show that the installer contract is enforceable by something automated, and say what that something is.
    Walk the Reviewer through the failure cases: installer interrupted midway, installer run twice, operator has edited a generated configuration file by hand, service fails its syntax check after render, service reloads but fails its health check, node loses the agent connection between staging and activation, secret present in an installer log, an unpinned package version changing behavior between two nodes installed a month apart.
    Confirm that nothing produced here allows the control plane to reach a shell.
    Out of scope for this step

    Billing, Vesta data import, non-Ubuntu operating systems, reseller nesting, an unrestricted file manager, arbitrary firewall or service editors, multi-node failover, and any production implementation of resource features beyond what Task 4 explicitly authorizes.

    pretty interesting how it draws some conlusion from those few lines, while some other decisions are left to myself to chose from.
    I decided to add the following line to the end of the prompt.

    Do NOT write any code at this point, we are still in the planning phase of the project.
    As you work thru the prompt, ask me questions if there are any doubts on what option to chose, unless it is clearly decided.

    “Technology is best when it brings people together.” – Matt Mullenweg

  • mikhomikho AdministratorOG Bash Me Gently

    While runnning the second prompt the following questions were asked

    What Ubuntu LTS version should be supported?
    Answer both 24.0 & 26.04

    The platform target is now Ubuntu 24.04 and 26.04 LTS, with the added cost accepted. I’m documenting the resulting decision as: nginx only for the first release, MariaDB/MySQL control-plane and tenant databases logically isolated, ACME as a web capability, baseline firewall in bootstrap, tenant firewall rules deferred, and mail last behind an operational gate. The files will be contracts, manifests, READMEs, and directory skeletons only, with no executable installers or service features.

    While reading the chat log I noticed this

    The .install skeleton is complete for the decided service set: base, node health, firewall, nginx, ACME, BIND9, MariaDB, cron, backups, statistics, and gated mail. No Apache directory was added because the ADR explicitly defers Apache support. I’m now running contract-level checks across every manifest, checking the dependency graph and forbidden runtime paths, then I’ll stage only these new files so Git can prove they are tracked without creating a commit.

    Especially this: No Apache directory was added because the ADR explicitly defers Apache support.

    Which I don't understand as the prompt states:
    the web server, and whether the first release supports nginx, Apache, both, or nginx as a proxy in front of Apache as the original does, and what that choice costs in template surface,

    It did make a decision on it own, without consulting me.

    So i had to add a 3rd prompt, short and sweet.

    In the installation phase on a blank server, the project will support the option to select nginx, apache or both.
    Include this and report whats steps are to be taken after.

    Result;
    Next steps

    Approve the exact M* ariaDB/MySQL version.

    • Approve Ubuntu 24.04 and 26.04 support, or reduce to one release initially.
    • Choose ACME challenge mode: HTTP-01, DNS-01, or both.
    • Define the web capability contract shared by nginx and Apache.
    • Build the fake-backed web hosting vertical slice.
    • Implement the Go agent’s nginx capability.
    • Implement the Go agent’s Apache capability.
    • Test the combined nginx-to-Apache topology on disposable Ubuntu systems.
    • Write the real installer only after those capability tests pass.
    • Add automated profile selection, manifest validation, conflict detection, and rollback tests.

    Think this requires a commit and push to github

    “Technology is best when it brings people together.” – Matt Mullenweg

  • Awesome to follow! Also, from what I’ve seen, agents are far better than most of the junk development shops put out these days… also even if you pay for human coding, what’s to stop them just having an agent write it and then reviewing…

    Currently building a whmcs alternative (like a lot of people) with agents, human code, human review and 3rd party review. Probably way better than the junk from web pro’s!

    Rock Solid Web Hosting, VPS & VDS with a Refreshing Approach - Xeon + EPYC with DDoS protection and Enterprise Hardware! HostBilby Inc.

Sign In or Register to comment.