better cards
This commit is contained in:
60
openspec/changes/deploy-without-node/design.md
Normal file
60
openspec/changes/deploy-without-node/design.md
Normal file
@@ -0,0 +1,60 @@
|
||||
## Context
|
||||
|
||||
- Production server environment is intentionally minimal: Docker is available, but Node.js is not installed on the host.
|
||||
- The site needs a repeatable way to get to the latest built content on that server.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Update the deployed site to the latest content using Docker-only operations on the server.
|
||||
- Keep the server host clean (no Node.js installation required).
|
||||
- Make the refresh procedure repeatable and verifiable.
|
||||
|
||||
**Non-Goals:**
|
||||
- Building site artifacts directly on the server host outside containers.
|
||||
- Introducing a new CMS/content authoring workflow.
|
||||
- Solving content freshness triggers end-to-end (webhooks, scheduling) beyond what is needed to support a Docker-based refresh.
|
||||
|
||||
## Decisions
|
||||
|
||||
1. Build in CI, deploy as a Docker image
|
||||
Why: keeps host clean and makes deploy deterministic.
|
||||
Alternatives considered:
|
||||
- Install Node.js on the host: rejected (violates clean server requirement).
|
||||
- Build on the host inside a one-off container writing to a bind mount/volume: possible, but adds operational complexity and makes server resources part of the build pipeline.
|
||||
|
||||
2. Refresh by pulling a published image and restarting the service
|
||||
Why: the server only needs Docker + registry access.
|
||||
Alternatives considered:
|
||||
- File-based sync (rsync/scp) of static assets: can work, but requires separate artifact distribution and is easier to drift.
|
||||
- Automated image updating (e.g., watchtower): may be useful later, but start with an explicit, documented operator command.
|
||||
|
||||
3. Version visibility via image metadata
|
||||
Why: operators need to confirm what is running.
|
||||
Approach:
|
||||
- Publish images with an immutable identifier (digest) and a human-friendly tag.
|
||||
- Expose build metadata through standard Docker inspection and/or a small endpoint/static file in the image.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] Content can be stale if the CI build does not run when content changes
|
||||
Mitigation: add a scheduled build and/or content-change trigger in CI (future enhancement if not already present).
|
||||
|
||||
- [Risk] Registry auth/secrets management on the server
|
||||
Mitigation: use least-privilege registry credentials and Docker-native secret handling where available.
|
||||
|
||||
- [Risk] Short downtime during restart
|
||||
Mitigation: use `docker compose up -d` to minimize downtime; consider health checks and rolling strategies if/when multiple replicas are used.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
- Add or update the Docker image build to produce a deployable image containing the built site output.
|
||||
- Update server deployment configuration (compose/service) to run the published image.
|
||||
- Document the operator refresh command(s): pull latest image, restart service, verify deployed version.
|
||||
- Rollback strategy: re-deploy the previously known-good image tag/digest.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- What is the authoritative "latest content" source (e.g., WordPress, filesystem, git) and what is the trigger to rebuild/publish a new image?
|
||||
- Where should operator commands live (Makefile, `ops/` scripts, README section)?
|
||||
- What is the current deployment target (single host compose, swarm, k8s) and should this change be scoped to one?
|
||||
Reference in New Issue
Block a user