scaffold-deply/Design_Doc/Tech_Desc.md

621 lines
20 KiB
Markdown

# Project Name - Technical Description
## Architecture Overview
This deployment system follows a containerized architecture pattern using Docker as the runtime environment. The system is designed to be self-contained, configurable, and easily deployable across different environments.
### System Components
```
┌─────────────────────────────────────────────────────────────────┐
│ Deployment Script │
│ (deploy-project.sh) │
│ - Configuration loader │
│ - Interactive wizard │
│ - Docker image builder (ephemeral) │
│ - Container orchestrator │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Configuration Layer │
│ (.env file) │
│ - Environment variables │
│ - Volume bindings │
│ - Network settings │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Docker Runtime │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Container │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Application │ │ Volumes │ │ Network │ │ │
│ │ │ (manual) │ │ (Persistent)│ │ Interfaces │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ │ CMD: tail -f /dev/null (ephemeral runtime) │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## Script Structure
### Core Functions
#### Configuration Management
```bash
# Load environment from .env file
load_env_file() {
if has_env_file; then
set -a
source "${ENV_FILE}"
set +a
fi
}
# Save configuration to .env file
save_env_file() {
cat > "${ENV_FILE}" << EOF
# Configuration
INSTANCE_NAME="${INSTANCE_NAME}"
IMAGE_NAME="${IMAGE_NAME}"
IMAGE_TAG="${IMAGE_TAG}"
EOF
}
```
#### State Detection
```bash
# Check if container exists
has_container() {
docker ps -a --format '{{.Names}}' | grep -q "^${INSTANCE_NAME}$"
}
# Check if container is running
is_container_running() {
docker ps --format '{{.Names}}' | grep -q "^${INSTANCE_NAME}$"
}
```
#### Interactive Prompts
```bash
prompt_user() {
local prompt_text="$1"
local default_value="$2"
local var_name="$3"
echo -n "${prompt_text} [${default_value}]: "
local user_input
if [ -r /dev/tty ]; then
read user_input </dev/tty
else
read user_input
fi
if [ -z "${user_input}" ]; then
user_input="${default_value}"
fi
eval "${var_name}='${user_input}'"
}
```
### Deployment Flow
```
1. Script Start
│
▼
2. Load Configuration
├── Check for .env file
└── Load or trigger wizard
│
▼
3. Detect State
├── Container exists?
└── Configuration exists?
│
▼
4. Execute Action
├── Setup new (wizard + create)
└── Renew (recreate with config)
│
▼
5. Build Image (Ephemeral)
├── Create build context
├── Build Docker image
└── Cleanup build context
│
▼
6. Deploy Container
├── Remove old container
├── Create volumes/networks
└── Start new container
│
▼
7. Validate
├── Container running?
└── Health check passed?
│
▼
8. Complete
```
## Ephemeral Runtime Implementation
### Build Context Creation
```bash
create_build_context() {
log_info "Creating ephemeral build context..."
# Create build directory
mkdir -p "${BUILD_CONTEXT_DIR}"
# Create Dockerfile
cat > "${BUILD_CONTEXT_DIR}/Dockerfile" << 'DOCKERFILE'
# Base image
FROM alpine:3.19
# Install any required dependencies
RUN apk add --no-cache bash coreutils
# Create application directory
WORKDIR /app
# Create data and config directories
RUN mkdir -p /app/data /app/config
# Keep container running indefinitely without starting any application
# tail -f /dev/null runs forever, allowing users to exec in and run commands manually
CMD ["tail", "-f", "/dev/null"]
DOCKERFILE
log_success "Build context created"
}
```
### Image Build
```bash
build_image() {
log_info "Building Docker image: ${FULL_IMAGE_NAME}"
# Create build context
create_build_context
# Build the image
docker build -t "${FULL_IMAGE_NAME}" "${BUILD_CONTEXT_DIR}"
log_success "Docker image built successfully"
}
```
### Cleanup (Ephemeral Policy)
```bash
cleanup_build_context() {
if [ -d "${BUILD_CONTEXT_DIR}" ]; then
rm -rf "${BUILD_CONTEXT_DIR}"
log_info "Cleaned up ephemeral build context"
fi
}
```
## Docker Configuration
### Container Creation
The script uses `docker run` with the following pattern:
```bash
docker run -d \
--name "${INSTANCE_NAME}" \
--restart unless-stopped \
$(build_volume_args) \
$(build_network_args) \
-e TZ="${TZ:-UTC}" \
"${FULL_IMAGE_NAME}"
```
### Volume Management
Volumes are configured in the `.env` file as an array:
```bash
VOLUMES=(
"_data-vol:/app/data"
"_config-vol:/app/config"
)
```
The script processes these into Docker volume flags:
```bash
build_volume_args() {
local args=""
for vol in "${VOLUMES[@]}"; do
local src=$(echo "$vol" | cut -d: -f1)
local dst=$(echo "$vol" | cut -d: -f2)
# Handle named volumes (start with _)
if [[ "$src" == _* ]]; then
src="${INSTANCE_NAME}${src}"
# Create volume if not exists
docker volume inspect "${src}" &>/dev/null || \
docker volume create "${src}" >/dev/null
fi
args="$args -v ${src}:${dst}"
done
echo "$args"
}
```
### Network Configuration
```bash
NETWORKS=(
"_internal-net" # Auto-prefixed with instance name
)
```
```bash
build_network_args() {
local args=""
for net in "${NETWORKS[@]}"; do
# Handle named networks (start with _)
if [[ "$net" == _* ]]; then
net="${INSTANCE_NAME}${net}"
# Create network if not exists
docker network inspect "${net}" &>/dev/null || \
docker network create "${net}" >/dev/null
fi
args="$args --network ${net}"
done
echo "$args"
}
```
## Error Handling
### Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | General error |
| 2 | Configuration error |
| 3 | Docker error |
| 4 | Network error |
### Error Recovery
```bash
# Trap errors and cleanup
trap cleanup_on_error ERR
cleanup_on_error() {
log_error "Deployment failed. Cleaning up..."
docker rm -f "${INSTANCE_NAME}" 2>/dev/null || true
cleanup_build_context
exit 1
}
```
## Logging System
### Color-Coded Output
```bash
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
```
### Debug Mode
```bash
if [ "${DEBUG}" = "true" ] || [ "${DEBUG}" = "1" ]; then
set -x # Enable command tracing
fi
```
## Security Considerations
### Environment Variables
- Sensitive data stored in `.env` (should be protected)
- No secrets logged to console
- File permissions should be restricted: `chmod 600 .env`
### Container Security
- Runs as root by default (can be modified in Dockerfile)
- Network isolation via Docker networks
- Minimal base image (Alpine)
### Volume Permissions
```bash
# Volumes are mounted with specific ownership
# Can be configured in Dockerfile with RUN chown
```
## Performance Optimization
### Local Build
No network pull required for application image:
- Faster deployment
- Works offline after base image cached
- No registry dependencies
### Cleanup
```bash
# Remove old container before creating new
remove_container
# Cleanup build context immediately
cleanup_build_context
# Prune unused images (optional)
docker image prune -f
```
## Extension Points
### Custom Dockerfile
Modify the `create_build_context()` function to customize:
```bash
# Add custom packages
RUN apk add --no-cache <your-packages>
# Add custom users
RUN addgroup -g 1000 appgroup && \
adduser -u 1000 -G appgroup -s /bin/bash -D appuser
# Set custom workdir
WORKDIR /app
# Copy application files
COPY . /app
# Set entrypoint
ENTRYPOINT ["/app/entrypoint.sh"]
# Keep ephemeral runtime
CMD ["tail", "-f", "/dev/null"]
```
### Custom Hooks
Add custom logic at these points:
```bash
# Pre-deployment hook
pre_deploy() {
# Custom validation or setup
}
# Post-deployment hook
post_deploy() {
# Health checks, notifications, etc.
}
```
## Testing Strategy
### Unit Tests
Test individual functions:
```bash
test_has_container() {
# Mock docker command
# Assert expected behavior
}
```
### Integration Tests
Test full deployment flow:
```bash
test_full_deployment() {
# Run script
# Verify container running
# Verify configuration
# Cleanup
}
```
## Version History
| Version | Date | Changes |
|---------|------|---------|
| 1.0.0 | 2026-01-01 | Initial release with ephemeral runtime policy |
# AI Prompt
- The content is organised into distinct sections according to the topics below. (Grouped by section)
- Messages are sorted chronologically, with the most recent at the top and the oldest at the bottom. (Sorted by date: newest first, oldest last.)
## AI Prompt habit as a reminder
- Refer to `Design_Doc/instructions.md`
## Design
- Rename `Design_Doc/instructions.md` to `Design_Doc/instructions2AI.md`, this document file is for input instructions for AI. The content should be same for all different projects, so all projects reference to this scaffold should copy this `Design_Doc/instructions2AI.md` same content to their own project. Update the corresponding document, such as: `Design_Doc/README.md`.
- Result
1. ✅ Renamed Design_Doc/instructions.md → Design_Doc/instructions2AI.md
2. ✅ Updated README.md to include instructions2AI.md in the documentation table with a description
The document is now ready for AI assistants to reference, and all projects using this scaffold should copy the
same instructions2AI.md content.
- I have the following reference project(s) i built before, you go to find the common structure including the folder(s) structure and file(s) with their content except the content as for corresponding project only. These deployment scripts are for auto. deployment application with docker by bash script.
- You can read the public sites:
- [rvs-prxy](https://app.radicle.xyz/nodes/ash.radicle.garden/rad%3Az3ASs6eodxMzh17pJv4NFbNWELhas)
- [qwen-code-cntr](https://app.radicle.xyz/nodes/ash.radicle.garden/rad:z3w8yKCUpzzeVguFnCCWFcQtVeYnV)
- [web-srv-nginx-depl](https://app.radicle.xyz/nodes/ash.radicle.garden/rad%3Az3eqQeA4nVrMPgs75H2M3jTLAJha5)
- [wg-deploy](https://app.radicle.xyz/nodes/ash.radicle.garden/rad%3Az32iTB6h6Nz9t5CPnwfjnSnHTQ7K1)
- Remark, if you are:
- VsCode Copilot: not sure can read or not, but not handle the corresponding sites.
- qwen-code: canNOT access JS website
- OR you read them from the corresponding folder at local current computer
- [rvs-prxy](../../cmptr-infra/rvs-prxy)
- [qwen-code-cntr](../../cmptr-infra/qwen-code)
- [web-srv-nginx-depl](../../pt-ai-big-data-iot-struc/web-app-pf/web-srv-nginx-depl)
- [wg-deploy](../../cmptr-infra/vpn/wg/wg)
- Remark, if you are:
- VsCode Copilot: canNOT access computer folders, need to manually add folder into workspace, then attached those files one by one.
- qwen-code: can read other folders in same computer, just do it.
- You collect the common items including folders and file's content. Then you build this scaffold at current folder.
- Result
- structure I've created:
1 scaffold-deply/
2 ├── README.md # Project overview with documentation links
3 ├── deploy-project.sh # Main deployment script (executable)
4 ├── .env.sample # Configuration template
5 ├── .gitignore # Git ignore rules
6 └── Design_Doc/
7 ├── Spec.md # Specifications and features
8 ├── Operations.md # User guide and troubleshooting
9 └── Tech_Desc.md # Technical architecture details
Common structure extracted from your reference projects:
1. Documentation Structure (4 files):
- README.md - Simple overview, links to detailed docs
- Design_Doc/Spec.md - Features, capabilities, requirements
- Design_Doc/Operations.md - Quick start, common operations, troubleshooting
- Design_Doc/Tech_Desc.md - Architecture, code structure, technical details
2. Deploy Script Features:
- Color-coded output (INFO, SUCCESS, WARNING, ERROR)
- Interactive wizard via /dev/tty (works with curl | bash)
- State detection (.env exists? container exists?)
- Four scenarios: new setup, reinstall, renew, update
- Configuration persistence in .env
- Docker volume/network/port management
- Help/usage function
3. Configuration:
- .env.sample template with documented variables
- .gitignore protecting sensitive data
To use: Copy this scaffold, rename deploy-project.sh to your project name, and customize the variables and Docker image settings.
- Do not need `.env.sample` and `.gitignore` in this scaffold
- Remember to add "ephemeral runtime policy", reference
- Result
Scaffold updated successfully. Here's the final structure:
1 scaffold-deply/
2 ├── README.md # Project overview with ephemeral runtime highlights
3 ├── deploy-project.sh # Main deployment script (executable, 11KB)
4 └── Design_Doc/
5 ├── Spec.md # Specifications with ephemeral runtime policy
6 ├── Operations.md # User guide with manual exec instructions
7 ├── Tech_Desc.md # Technical architecture with build/cleanup details
8 └── instructions.md # Task instructions (preserved)
Key changes made:
1. Removed: .env.sample and .gitignore (per instructions)
2. Added Ephemeral Runtime Policy:
- Docker image built locally from embedded Dockerfile in script
- Build context (.app-build/) created temporarily, cleaned up immediately
- Container runs with CMD ["tail", "-f", "/dev/null"] for manual exec
- No external image dependencies
3. Updated all documentation to reflect:
- Local image build process
- Manual exec mode (docker exec -it <name> bash)
- Clean operation (no leftover build files)
- Four-scenario smart setup
- I aim to add a "Deployment Complete Output", you reference to `../../pt-ai-big-data-iot-struc/web-app-pf/web-srv-nginx-depl/Design_Doc/Operations.md` -> Section "Deployment Complete Output", then implement into this scaffold, including script and corresponding document(s).
- Result
1. Deploy Script (`deploy-project.sh`):
- Added show_deployment_complete() function that displays a formatted summary box with:
- Re-Run Container instructions
- Container Accessing command (docker exec -it -u root)
- View Logs command (docker logs --tail 50)
- Inspect command
- Remove Container command
- Remove Volumes command (auto-lists all instance volumes)
- Updated validate_deployment() to call show_deployment_complete() on success
2. Operations Guide (`Design_Doc/Operations.md`):
- Added new "Deployment Complete Output" section after Quick Start
- Shows example output with formatted command reference box
- Includes note about volume naming convention
Final Scaffold Structure:
1 scaffold-deply/
2 ├── README.md # 4.3KB
3 ├── deploy-project.sh # 12KB (with Deployment Complete Output)
4 └── Design_Doc/
5 ├── Spec.md # 6.5KB
6 ├── Operations.md # 6.8KB (with Deployment Complete Output section)
7 ├── Tech_Desc.md # 17KB (AI Prompt section preserved)
8 └── instructions.md # 3.4KB
- I aim to add a "Deployment Complete Output" with "Container Accessing" which has node and root users, you reference to `../../cmptr-infra/qwen-code/Design_Doc/Operations.md` -> Section "Deployment Complete Output", then implement into this scaffold, including script and corresponding document(s).
- Result
1. Deploy Script (deploy-project.sh)
Updated show_deployment_complete() function to show both user options:
1 Container Accessing:
2 docker exec -it -u root ${INSTANCE_NAME} bash
3 docker exec -it -u node ${INSTANCE_NAME} bash
2. Operations Guide (Design_Doc/Operations.md)
- Updated example output to show both root and node user access commands
- Added explanatory note:
- root user: Full privileges for administrative tasks
- node user: Non-root, limited privileges for regular application operations
Final Scaffold Structure
1 scaffold-deply/
2 ├── README.md # 4.3KB
3 ├── deploy-project.sh # 12.5KB (with dual-user Container Accessing)
4 └── Design_Doc/
5 ├── Spec.md # 6.5KB
6 ├── Operations.md # 7.1KB (updated with dual-user access note)
7 ├── Tech_Desc.md # 18.5KB (AI Prompt section preserved)
8 └── instructions.md # 3.4KB
The "Container Accessing" section now shows both root and node user options, following the qwen-code project's pattern. Users can choose the
appropriate privilege level for their task.