Roadmap
Daps Project Roadmap
Section titled “Daps Project Roadmap”Planned work for the next release. Items here are future work — not yet implemented. Anything
completed moves to readme-changelog.md under its version and is deleted from this doc.
See planning-versioning.md for what makes a change MAJOR, MINOR, or PATCH.
Planning: v0.3.3
Section titled “Planning: v0.3.3”Add HostingProvider.IsRemoteUserRoot computed property
Section titled “Add HostingProvider.IsRemoteUserRoot computed property”returns whether the username is root or not. The point would be to remove that logic as it appears elsewhere
Documentation: Upgrades
Section titled “Documentation: Upgrades”Upgrades are confusing, and should be contextualized in one document so the different kinds can be explained.
That is, what do we mean by upgrades, with regards to:
- Daps itself
- Daps dependencies
- docker
- caddy
- toolkit
- ubuntu
- python
- etc
- Templated projects
- The templates themselves, e.g. scripts, compose files
- Wordpress
- core
- plugins
- Grist
- ?
- Astro
- ?
The details of each can be captured in other documents as it makes sense, e.g. how to upgrade wordpress in the wordpress template doc
wordpress 7.1.2
Section titled “wordpress 7.1.2”I had to update the wordpress.dockerfile like so:
FROM wordpress:7.1-php8.3-apache TO FROM wordpress:7.1.2-php8.3-apache
in order for dapsman local build --build --project dapster-wp to force the wordpress image to update to version 7.1.2. Why is that?
I also modified compose_dapster-wp.dev.yaml to add the missing define( 'WP_AUTO_UPDATE_CORE', false ); statement, so that might also have affected it.
Either way, the —build switch should ensure that the latest image is pulled, I thought?
Progress indicator during long operations
Section titled “Progress indicator during long operations”e.g. when running dapster prod deploy it can take a while and the cursor is doing nothing.
I don’t think we can have an actual progress indicator but an indeterminate one would be better than nothing.
CLI provider is passed to plan builders twice
Section titled “CLI provider is passed to plan builders twice”Six plan builders take a providerName through their constructor. Five of them also read options.ProviderName, and resolve with _providerName ?? options.ProviderName — but DapsmanRunner
passes _parsed.ProviderName into both, so the ?? always collapses to the same value. The
coalesce reads like precedence logic and is not. There is a standing TODO at
RemoteBackupPlanBuilder.cs:37 asking exactly this.
Affected: LocalSyncFromRemotePlanBuilder, RemoteBackupPlanBuilder,
RemoteOfflineStatusPlanBuilder, RemoteSyncFromLocalPlanBuilder, RemoteTeardownPlanBuilder
(all line 38, except teardown at 35). RemoteCaddyRestartPlanBuilder takes the constructor
parameter only and has no duplication. RemoteDeployPlanBuilder is not affected.
The work: pick one channel and delete the other. Options is the better one — it matches
ProjectName, DryRun and the rest of the per-run inputs, and it keeps the builders
constructible without knowing the invocation. Drop the constructor parameter from the five
builders and their DapsmanRunner call sites.
Do it as one change across all of them rather than per-workflow: fixing a single builder makes the codebase less consistent, not more.
PATCH.
Remote plans that do not name their provider
Section titled “Remote plans that do not name their provider”prod teardown gained a - provider: <name> line in 0.3.2, because printing only
- remote: <user>@<host> shows a bare IP for an OpenStack provider and identifies nothing. The
same gap remains in the remote plans that still lack a ProviderName: RemoteBackupPlan,
OfflineStatusPlan, SyncFromLocalPlan, SyncFromRemotePlan and UnprovisionPlan.
CaddyRestartPlan is shared by local caddy restart and prod caddy restart, so it needs a
nullable provider or a local/remote split rather than a required property — worth deciding
before touching it.
The work: per plan, a required string ProviderName, one assignment from
provider.ConfigDefinition.Name in the builder, one line in the printer. Three lines each.
PATCH.
Unregistered projects in the other prod workflows
Section titled “Unregistered projects in the other prod workflows”prod teardown no longer needs a daps.yaml entry (0.3.2). prod backup,
prod offline/online and prod system still do, via IProjectResolver.Resolve.
This is lower value than it looks: those workflows have a workable answer that teardown did not — re-add the entry and run them. Teardown was the case where the entry was gone and the only route to remove the remote copy went through it.
The mechanism already exists if it is wanted: IProjectResolver.TryResolve returns null instead
of throwing, and IHostingProviderResolver.ResolveExplicit refuses to guess a host when no
project provider is available to fall back on.
PATCH.
specifying multiple projects in teardown workflow
Section titled “specifying multiple projects in teardown workflow”prod teardown —project a —project b produces —project
cli option table
Section titled “cli option table”CliArguments.Parse has no per-command option table. The option loop is global, so prod teardown --build --template wordpress parses fine and silently ignores both.
--config pointing outside the daps root breaks relative provider paths. DapsRootPath is derived from the config file’s directory, so an OpenStack provider’s openrc: ./hosting/... resolves against wherever that file sits — ERROR: OpenStack RC script not found for provider 'ramnode'. I (Claude) hit this while verifying the unregistered-teardown path and worked around it by putting the test config in the daps root.
Planning: v0.4.0
Section titled “Planning: v0.4.0”Upgrade templated projects
Section titled “Upgrade templated projects”We need something like:
dapsman init --update --project <name>
Which would essentially rerun init and overwrite transformed and untransformed files, but not others, depending on the template. Like for wordpress, it would update _scripts and _docker, including the dockerfile. Any user mods to those files would be lost, unless they’re managing things in git and can catch their own mods in the diffs
Daps Aspirational Roadmap
Section titled “Daps Aspirational Roadmap”Ideas for what to do later, someday. Items can move from here to a specific release plan above.
Robustness
Section titled “Robustness”prod offline misses single-line and wrapped Caddy site blocks
Section titled “prod offline misses single-line and wrapped Caddy site blocks”ReadSiteAddresses (RemoteOfflineStatusPlanBuilder.cs, line 89) recognizes a site block only when
a top-level line ends in { (line 102). Two valid Caddy forms slip past it:
- a single-line block —
example.com { respond "hi" } - an address list wrapped across lines, with the
{on a later line
A missed block is not a visible error. Its domains are simply absent from the generated offline config and fall through to Caddy’s default handling while the project is meant to be offline. If every block is missed the method throws, which is at least loud; the partial case is the dangerous one.
All four shipped templates use the multi-line form, so this does not bite today — it bites the first
user who hand-edits a .prod.caddy into a form Caddy accepts and Daps does not.
The work: parse on brace position rather than line ending — accumulate text until the first
top-level {, treat everything before it as the address list, then track depth as now. Extend
RemoteOfflineStatusPlanBuilderTests with a single-line block and a wrapped address list.
Note that a user who needs an exact offline config already has an escape hatch: a
_caddy_sites/<name>.offline.caddy file is used verbatim when present, and none of this parsing
runs.
PATCH.
Optimization
Section titled “Optimization”Toolkit Linux version (questions, not planning)
Section titled “Toolkit Linux version (questions, not planning)”Q: The toolkit is ubuntu because that’s what I thought to use, because it’s common, but it appears to be 500MB on disk. Would another distro have made more sense?
A: Reasonable choice, but yes there are lighter options. The short answer: Ubuntu is fine here, the size doesn’t matter much for a toolkit, but here’s the tradeoff landscape:
Why Ubuntu is heavier: It ships with a lot of userspace tooling you don’t need (systemd, snapd stubs, locale data, etc.). The OpenStack CLI is also Python-based and pulls in a significant dependency tree on top of that.
Lighter alternatives:
- debian:bookworm-slim — similar compatibility to Ubuntu, maybe 30-40% smaller. Near-zero migration effort since it’s the same package ecosystem (apt). Probably the most sensible swap if you ever wanted to.
- Alpine — the extreme version (~7 MB base). Alpine uses musl libc instead of glibc, which causes subtle breakage with some Python packages (OpenStack CLI in particular can be finicky). Doable but requires more Dockerfile work and occasional debugging when a package behaves differently.
- python:3.12-slim — since OpenStack CLI is a Python package, starting from a Python image makes the dependency story cleaner. Still Debian-based so full compatibility.
Why it doesn’t matter much here: The toolkit runs continuously on your local machine, is never uploaded to a remote host, and is pulled once then cached. 500 MB sitting idle on disk costs nothing in practice. Size optimization matters most for images that get pulled frequently (CI runners, prod containers scaled horizontally) — neither of which applies to the toolkit.
If you ever revisit it, debian:bookworm-slim would be the lowest-risk swap. Alpine is only worth it if you’re really constrained on disk and willing to do the musl compatibility testing.
Wordpress initial deployment leaves a vulnerable new installation before sync
Section titled “Wordpress initial deployment leaves a vulnerable new installation before sync”I’m not sure how big a problem this is but when you first run dapsman prod deploy on a wordpress project, it’s out there as a “new install” ready for customization. Someone finding the site could conceivably set it up and create an admin user, etc. Running sync should overwrite whatever they do but still, it’s not ideal. It might be good to leave it in a “prod offline” mode in caddy and then the user has to run dapsman prod online to reveal it.
Features
Section titled “Features”dapsman local cleanup Workflow
Section titled “dapsman local cleanup Workflow”This workflow would validate the local setup and look for things to clean up in the local installation, like:
- confirm that all projects have a docker compose file for daps
- confirm that each caddy file matches an active project and remove those that don’t
- clean docker image cache
- etc
Validated items can be reported back to the user before requiring confirmation for cleanup.
Add more items as we think of them.