@bostonuniversity/buwp-local 0.7.4 → 0.7.6
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.
- package/docs/ARCHITECTURE.md +5 -67
- package/docs/CHANGELOG.md +17 -0
- package/docs/COMMANDS.md +1 -0
- package/docs/GETTING_STARTED.md +2 -0
- package/docs/MIGRATION_FROM_VM.md +4 -1
- package/docs/ROADMAP.md +24 -48
- package/lib/commands/init.js +1 -0
- package/lib/commands/update.js +11 -3
- package/lib/config.js +1 -0
- package/lib/index.js +0 -14
- package/package.json +1 -1
- package/readme.md +1 -0
- package/.buwp-local.example.json +0 -27
- package/.env.local.example +0 -26
- package/docs/archive/IMPLEMENTATION_NOTES_V0.5.0_PHASE3.md +0 -240
- package/docs/archive/IMPLEMENTATION_SUMMARY.md +0 -385
- package/docs/archive/KEYCHAIN_IMPLEMENTATION.md +0 -140
- package/docs/archive/macos-keychain-notes.md +0 -11
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -465,78 +465,16 @@ This architecture provides clean boundaries:
|
|
|
465
465
|
|
|
466
466
|
| Concern | Location | Update Mechanism |
|
|
467
467
|
|---------|----------|------------------|
|
|
468
|
-
| WordPress core | Docker image | `
|
|
469
|
-
| BU plugins | Docker image | `
|
|
470
|
-
| BU theme | Docker image | `
|
|
468
|
+
| WordPress core | Docker image | `docker pull` |
|
|
469
|
+
| BU plugins | Docker image | `docker pull` |
|
|
470
|
+
| BU theme | Docker image | `docker pull` |
|
|
471
471
|
| **Your plugin** | **Local filesystem** | **Your editor** |
|
|
472
472
|
| **Your theme** | **Local filesystem** | **Your editor** |
|
|
473
|
-
| Database | Docker volume
|
|
474
|
-
|
|
|
473
|
+
| Database | Docker volume | Persists across updates |
|
|
474
|
+
| Uploads | Docker volume | Persists across updates |
|
|
475
475
|
|
|
476
476
|
Updates to WordPress never touch your development code. Updates to your code never require rebuilding WordPress.
|
|
477
477
|
|
|
478
|
-
### S3 Upload Architecture
|
|
479
|
-
|
|
480
|
-
A critical design decision enables safe WordPress core updates: **all media uploads are stored in S3, not in the container filesystem**.
|
|
481
|
-
|
|
482
|
-
```
|
|
483
|
-
WordPress Upload Flow:
|
|
484
|
-
┌──────────────┐
|
|
485
|
-
│ User │ Uploads file via WP admin
|
|
486
|
-
└──────┬───────┘
|
|
487
|
-
│
|
|
488
|
-
↓
|
|
489
|
-
┌──────────────────────────────────┐
|
|
490
|
-
│ WordPress Container │
|
|
491
|
-
│ │
|
|
492
|
-
│ BU S3 Uploads Plugin │
|
|
493
|
-
│ (intercepts upload) │
|
|
494
|
-
└──────┬───────────────────────────┘
|
|
495
|
-
│
|
|
496
|
-
↓
|
|
497
|
-
┌──────────────────────────────────┐
|
|
498
|
-
│ s3proxy Container │
|
|
499
|
-
│ (AWS SigV4 authentication) │
|
|
500
|
-
└──────┬───────────────────────────┘
|
|
501
|
-
│
|
|
502
|
-
↓
|
|
503
|
-
┌──────────────────────────────────┐
|
|
504
|
-
│ S3 Bucket │
|
|
505
|
-
│ (permanent storage) │
|
|
506
|
-
└──────────────────────────────────┘
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
**Key Configuration** (from `compose-generator.js`):
|
|
510
|
-
|
|
511
|
-
```javascript
|
|
512
|
-
if (config.services.s3proxy) {
|
|
513
|
-
wpConfigExtra += "define('S3_UPLOADS_AUTOENABLE', true);\n";
|
|
514
|
-
wpConfigExtra += "define('S3_UPLOADS_DISABLE_REPLACE_UPLOAD_URL', true);\n";
|
|
515
|
-
}
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
**What this means for updates:**
|
|
519
|
-
|
|
520
|
-
The `wp_build` volume contains **zero user data**:
|
|
521
|
-
- ✅ WordPress core files (disposable - from image)
|
|
522
|
-
- ✅ BU plugins/themes (disposable - from image)
|
|
523
|
-
- ❌ **No media uploads** (in S3 bucket)
|
|
524
|
-
- ❌ **No database** (separate db_data volume)
|
|
525
|
-
- ❌ **No custom code** (mapped from host filesystem)
|
|
526
|
-
|
|
527
|
-
**Result:** The `wp_build` volume is purely infrastructure and can be safely wiped during updates to refresh WordPress core files.
|
|
528
|
-
|
|
529
|
-
```bash
|
|
530
|
-
# This is safe because:
|
|
531
|
-
# - Database preserved (db_data volume)
|
|
532
|
-
# - Uploads preserved (S3 bucket)
|
|
533
|
-
# - Your code preserved (local filesystem)
|
|
534
|
-
npx buwp-local update # Wipes wp_build, recreates from image
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
**Contrast with traditional WordPress:**
|
|
538
|
-
In a standard WordPress installation, `wp-content/uploads/` contains irreplaceable user media files. In buwp-local, that directory is empty or contains only regenerable thumbnails/cache.
|
|
539
|
-
|
|
540
478
|
For detailed migration guidance, see [MIGRATION_FROM_VM.md](MIGRATION_FROM_VM.md).
|
|
541
479
|
|
|
542
480
|
## Security Model
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to buwp-local will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.7.6]
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **`update` command now regenerates docker-compose.yml** - Config changes in `.buwp-local.json` are now applied during `update`, not just during `start`
|
|
12
|
+
- Ports, services, volume mappings, and other config changes now take effect when running `npx buwp-local update`
|
|
13
|
+
- Previously, config changes were silently ignored during update, requiring `stop` + `start` to apply
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- `update` command now follows same pattern as `start` command for compose file generation
|
|
17
|
+
- Improved user feedback showing compose file regeneration step
|
|
18
|
+
|
|
19
|
+
## [0.7.5]
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- Init template updated with `WP_ENVIRONMENT_TYPE=local` by default
|
|
23
|
+
- Provides standardized environment detection for plugins/themes
|
|
24
|
+
|
|
8
25
|
## [0.7.4]
|
|
9
26
|
|
|
10
27
|
### Changed
|
package/docs/COMMANDS.md
CHANGED
|
@@ -141,6 +141,7 @@ npx buwp-local update --preserve-wpbuild
|
|
|
141
141
|
|
|
142
142
|
**What it does:**
|
|
143
143
|
- Checks if environment exists and Docker is running
|
|
144
|
+
- **Regenerates docker-compose.yml from current `.buwp-local.json` config** (applies config changes)
|
|
144
145
|
- Pulls latest Docker images from registry
|
|
145
146
|
- **Removes wp_build volume** to get fresh WordPress core files (unless `--preserve-wpbuild`)
|
|
146
147
|
- Recreates containers with new images
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -93,6 +93,8 @@ sudo bash -c 'echo "127.0.0.1 username-myproject.local" >> /etc/hosts'
|
|
|
93
93
|
|
|
94
94
|
Replace `username-myproject.local` with the hostname you chose in step 4.
|
|
95
95
|
|
|
96
|
+
The `init` command will also display this command for you to run.
|
|
97
|
+
|
|
96
98
|
### 6. Start Your Environment
|
|
97
99
|
|
|
98
100
|
Start the Docker containers:
|
|
@@ -198,6 +198,9 @@ npx buwp-local start
|
|
|
198
198
|
```bash
|
|
199
199
|
# Check Docker Desktop is running
|
|
200
200
|
docker info
|
|
201
|
+
|
|
202
|
+
# Check port conflicts
|
|
203
|
+
npx buwp-local start --verbose
|
|
201
204
|
```
|
|
202
205
|
|
|
203
206
|
### Code changes not appearing
|
|
@@ -221,7 +224,7 @@ Check volume mappings in `.buwp-local.json`:
|
|
|
221
224
|
# Verify Keychain entries
|
|
222
225
|
npx buwp-local keychain list
|
|
223
226
|
|
|
224
|
-
# Or use .env.local fallback
|
|
227
|
+
# Or use .env.local fallback
|
|
225
228
|
npx buwp-local keychain export > .env.local
|
|
226
229
|
```
|
|
227
230
|
|
package/docs/ROADMAP.md
CHANGED
|
@@ -218,6 +218,25 @@ hostile.remove('127.0.0.1', config.hostname);
|
|
|
218
218
|
|
|
219
219
|
**Breaking Change Note:** Existing projects will need `buwp-local update` or restart to apply new port bindings. Database access from phones/tablets/other computers will no longer work (rare use case).
|
|
220
220
|
|
|
221
|
+
### Shipped in v0.7.5
|
|
222
|
+
- **Init Template updated with WP_ENVIRONMENT_TYPE** ✅
|
|
223
|
+
- New projects set `WP_ENVIRONMENT_TYPE=local` by default
|
|
224
|
+
- Provides standardized environment detection for plugins/themes
|
|
225
|
+
- Can be overridden to simulate staging/production if needed
|
|
226
|
+
|
|
227
|
+
### Shipped in v0.7.6
|
|
228
|
+
- **Update Command Config Regeneration** ✅
|
|
229
|
+
- `update` command now regenerates docker-compose.yml from current `.buwp-local.json` config
|
|
230
|
+
- Config changes (ports, services, volume mappings, etc.) are now applied during `update`
|
|
231
|
+
- Fixes bug where config changes were silently ignored, requiring `stop` + `start` to apply
|
|
232
|
+
- Follows same pattern as `start` command for consistent behavior
|
|
233
|
+
|
|
234
|
+
**Problem:** User edited `.buwp-local.json` config (changed ports from 8080/8443 to 80/443), ran `npx buwp-local update`, but ports stayed at old values. Some settings updated (hostname) while others didn't, causing confusion.
|
|
235
|
+
|
|
236
|
+
**Root Cause:** Update command reused existing docker-compose.yml file instead of regenerating from current config like `start` command does.
|
|
237
|
+
|
|
238
|
+
**Solution:** Added compose file regeneration step to `update` command before pulling images. Now matches `start` command pattern and ensures config changes take effect.
|
|
239
|
+
|
|
221
240
|
### Potential Features
|
|
222
241
|
|
|
223
242
|
- **Ability to add custom WORDPRESS_CONFIG_EXTRA environment variables**
|
|
@@ -227,6 +246,11 @@ hostile.remove('127.0.0.1', config.hostname);
|
|
|
227
246
|
- Commands to export credentials to JSON file
|
|
228
247
|
- Useful for migrating between machines or sharing setup
|
|
229
248
|
|
|
249
|
+
- **Command to generate a valid super-user**
|
|
250
|
+
- Consider adding a buwp-local command like `create-super-user` with a prompt that defaults to the current system username that can be used to create a valid WordPress super user tied to the current developer's BU account.
|
|
251
|
+
- This would be especially helpful for new users who are not familiar with WP CLI or need a quick way to get admin access without manually running WP CLI commands.
|
|
252
|
+
- One concern is that we don't want the primary command namespace to get too crowded with niche commands, perhaps we could have a "utils" command group for less commonly used commands like this, e.g. `buwp-local utils create-super-user`?
|
|
253
|
+
|
|
230
254
|
- **Advanced Port Binding Configuration**
|
|
231
255
|
- Optional config to override localhost-only binding for database/Redis
|
|
232
256
|
- For advanced users who need network access to services
|
|
@@ -325,54 +349,6 @@ Will be informed by feedback from initial small group of users and actual pain p
|
|
|
325
349
|
### Quality
|
|
326
350
|
- Standardized help for all CLI commands
|
|
327
351
|
|
|
328
|
-
### Code Structure
|
|
329
|
-
|
|
330
|
-
#### Refactor credential handling to avoid duplication
|
|
331
|
-
Suggested refactor:
|
|
332
|
-
```javascript
|
|
333
|
-
// lib/docker-helpers.js (new file)
|
|
334
|
-
export function prepareDockerComposeEnv(projectPath, projectName) {
|
|
335
|
-
const credentials = loadKeychainCredentials();
|
|
336
|
-
let tempEnvPath = null;
|
|
337
|
-
|
|
338
|
-
if (Object.keys(credentials).length > 0) {
|
|
339
|
-
try {
|
|
340
|
-
tempEnvPath = createSecureTempEnvFile(credentials, projectName);
|
|
341
|
-
} catch (err) {
|
|
342
|
-
console.warn(chalk.yellow(`⚠️ Could not load keychain credentials: ${err.message}`));
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
const envFilePath = path.join(projectPath, ENV_FILE_NAME);
|
|
347
|
-
const envFileFlag = fs.existsSync(envFilePath) ? `--env-file ${envFilePath}` : '';
|
|
348
|
-
const tempEnvFileFlag = tempEnvPath ? `--env-file ${tempEnvPath}` : '';
|
|
349
|
-
|
|
350
|
-
return {
|
|
351
|
-
flags: `${tempEnvFileFlag} ${envFileFlag}`.trim(),
|
|
352
|
-
tempEnvPath,
|
|
353
|
-
cleanup: () => tempEnvPath && secureDeleteTempEnvFile(tempEnvPath)
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
#### Centralize volume naming logic
|
|
359
|
-
|
|
360
|
-
Suggested refactor:
|
|
361
|
-
```javascript
|
|
362
|
-
// lib/volume-naming.js (new file)
|
|
363
|
-
export function getVolumeNames(projectName) {
|
|
364
|
-
return {
|
|
365
|
-
db: `${projectName}_db_data`,
|
|
366
|
-
wp: `${projectName}_wp_build`
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// Or simpler - just add to config.js
|
|
371
|
-
export function getWpVolumeName(projectName) {
|
|
372
|
-
return `${projectName}_wp_build`;
|
|
373
|
-
}
|
|
374
|
-
```
|
|
375
|
-
|
|
376
352
|
---
|
|
377
353
|
|
|
378
354
|
## Decision Framework
|
package/lib/commands/init.js
CHANGED
package/lib/commands/update.js
CHANGED
|
@@ -7,17 +7,17 @@ import { execSync } from 'child_process';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import fs from 'fs';
|
|
9
9
|
import { loadConfig, loadKeychainCredentials, createSecureTempEnvFile, secureDeleteTempEnvFile, ENV_FILE_NAME } from '../config.js';
|
|
10
|
+
import { generateComposeFile } from '../compose-generator.js';
|
|
10
11
|
|
|
11
12
|
async function updateCommand(options = {}) {
|
|
12
13
|
console.log(chalk.blue('🔄 Updating Docker images...\n'));
|
|
13
14
|
|
|
14
15
|
try {
|
|
15
16
|
const projectPath = process.cwd();
|
|
16
|
-
const composePath = path.join(projectPath, '.buwp-local', 'docker-compose.yml');
|
|
17
|
-
const composeDir = path.dirname(composePath);
|
|
18
17
|
const envFilePath = path.join(projectPath, ENV_FILE_NAME);
|
|
18
|
+
const composePath = path.join(projectPath, '.buwp-local', 'docker-compose.yml');
|
|
19
19
|
|
|
20
|
-
// Check if docker-compose.yml exists
|
|
20
|
+
// Check if docker-compose.yml exists (indicates environment was previously started)
|
|
21
21
|
if (!fs.existsSync(composePath)) {
|
|
22
22
|
console.log(chalk.yellow('⚠️ No environment found.'));
|
|
23
23
|
console.log(chalk.gray('Run "buwp-local start" to create an environment.\n'));
|
|
@@ -28,6 +28,14 @@ async function updateCommand(options = {}) {
|
|
|
28
28
|
const config = loadConfig(projectPath);
|
|
29
29
|
const projectName = config.projectName || 'buwp-local';
|
|
30
30
|
|
|
31
|
+
// Regenerate docker-compose.yml from current config
|
|
32
|
+
// This ensures any config changes are applied during update
|
|
33
|
+
console.log(chalk.gray('Regenerating docker-compose.yml from current config...'));
|
|
34
|
+
const newComposePath = generateComposeFile(config, projectPath);
|
|
35
|
+
console.log(chalk.green(`✓ Generated ${newComposePath}\n`));
|
|
36
|
+
|
|
37
|
+
const composeDir = path.dirname(composePath);
|
|
38
|
+
|
|
31
39
|
// Check if Docker is running
|
|
32
40
|
try {
|
|
33
41
|
execSync('docker info', { stdio: 'ignore' });
|
package/lib/config.js
CHANGED
package/lib/index.js
CHANGED
|
@@ -15,17 +15,3 @@ export const generateComposeFile = composeGenerator.generateComposeFile;
|
|
|
15
15
|
export const CONFIG_FILE_NAME = config.CONFIG_FILE_NAME;
|
|
16
16
|
export const ENV_FILE_NAME = config.ENV_FILE_NAME;
|
|
17
17
|
export const DEFAULT_CONFIG = config.DEFAULT_CONFIG;
|
|
18
|
-
|
|
19
|
-
// Keychain exports
|
|
20
|
-
export const setCredential = keychain.setCredential;
|
|
21
|
-
export const getCredential = keychain.getCredential;
|
|
22
|
-
export const hasCredential = keychain.hasCredential;
|
|
23
|
-
export const listCredentials = keychain.listCredentials;
|
|
24
|
-
export const clearAllCredentials = keychain.clearAllCredentials;
|
|
25
|
-
export const isPlatformSupported = keychain.isPlatformSupported;
|
|
26
|
-
export const isMultilineCredential = keychain.isMultilineCredential;
|
|
27
|
-
export const parseCredentialsFile = keychain.parseCredentialsFile;
|
|
28
|
-
export const CREDENTIAL_KEYS = keychain.CREDENTIAL_KEYS;
|
|
29
|
-
export const CREDENTIAL_GROUPS = keychain.CREDENTIAL_GROUPS;
|
|
30
|
-
export const CREDENTIAL_DESCRIPTIONS = keychain.CREDENTIAL_DESCRIPTIONS;
|
|
31
|
-
export const MULTILINE_CREDENTIALS = keychain.MULTILINE_CREDENTIALS;
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -113,3 +113,4 @@ Your local WordPress site should now be accessible at the hostname you configure
|
|
|
113
113
|
- ✅ Smart initialization for plugins, themes, and mu-plugins
|
|
114
114
|
- ✅ Volume mapping for live code sync
|
|
115
115
|
- ✅ Xdebug support for step debugging
|
|
116
|
+
- ✅ WordPress environment detection (`WP_ENVIRONMENT_TYPE` set to `local`)
|
package/.buwp-local.example.json
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"image": "ghcr.io/bu-ist/bu-wp-docker-mod_shib:arm64-latest",
|
|
3
|
-
"hostname": "wordpress.local",
|
|
4
|
-
"multisite": true,
|
|
5
|
-
"services": {
|
|
6
|
-
"redis": true,
|
|
7
|
-
"s3proxy": true,
|
|
8
|
-
"shibboleth": true
|
|
9
|
-
},
|
|
10
|
-
"ports": {
|
|
11
|
-
"http": 80,
|
|
12
|
-
"https": 443,
|
|
13
|
-
"db": 3306,
|
|
14
|
-
"redis": 6379
|
|
15
|
-
},
|
|
16
|
-
"mappings": [
|
|
17
|
-
{
|
|
18
|
-
"local": "./",
|
|
19
|
-
"container": "/var/www/html/wp-content/plugins/my-plugin",
|
|
20
|
-
"comment": "Map current directory to a plugin location"
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
"env": {
|
|
24
|
-
"WP_DEBUG": true,
|
|
25
|
-
"XDEBUG": false
|
|
26
|
-
}
|
|
27
|
-
}
|
package/.env.local.example
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# BU WordPress Local Development Environment Variables
|
|
2
|
-
# Copy this file to .env.local and fill in your actual credentials
|
|
3
|
-
# NEVER commit .env.local to version control!
|
|
4
|
-
|
|
5
|
-
# Database Credentials
|
|
6
|
-
WORDPRESS_DB_PASSWORD=password
|
|
7
|
-
DB_ROOT_PASSWORD=rootpassword
|
|
8
|
-
|
|
9
|
-
# Shibboleth Configuration (if enabled)
|
|
10
|
-
SP_ENTITY_ID=https://your-sp-entity-id
|
|
11
|
-
IDP_ENTITY_ID=https://shib-test.bu.edu/idp/shibboleth
|
|
12
|
-
SHIB_IDP_LOGOUT=https://shib-test.bu.edu/idp/logout.jsp
|
|
13
|
-
SHIB_SP_KEY=your-private-key-here
|
|
14
|
-
SHIB_SP_CERT=your-certificate-here
|
|
15
|
-
|
|
16
|
-
# AWS S3 Configuration (if enabled)
|
|
17
|
-
S3_UPLOADS_BUCKET=your-bucket-name
|
|
18
|
-
S3_UPLOADS_REGION=us-east-1
|
|
19
|
-
S3_UPLOADS_ACCESS_KEY_ID=AKIA...
|
|
20
|
-
S3_UPLOADS_SECRET_ACCESS_KEY=your-secret-key
|
|
21
|
-
S3_ACCESS_RULES_TABLE=your-access-rules-table
|
|
22
|
-
|
|
23
|
-
# OLAP Configuration (if using S3 Object Lambda)
|
|
24
|
-
OLAP=your-olap-name
|
|
25
|
-
OLAP_ACCT_NBR=123456789
|
|
26
|
-
OLAP_REGION=us-east-1
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
# v0.5.0 Phase 3: Hybrid Secure Temp File Integration
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
Completed implementation of credential loading from macOS keychain into Docker Compose via secure temporary environment files. This is the final integration step of v0.5.0 keychain feature.
|
|
5
|
-
|
|
6
|
-
## What Was Implemented
|
|
7
|
-
|
|
8
|
-
### 1. **Credential Loading Functions** (`lib/config.js`)
|
|
9
|
-
|
|
10
|
-
Added three new exported functions:
|
|
11
|
-
|
|
12
|
-
#### `loadKeychainCredentials()`
|
|
13
|
-
- Retrieves all 15 stored credentials from macOS keychain
|
|
14
|
-
- Returns empty object on non-macOS platforms (graceful degradation)
|
|
15
|
-
- Checks `isPlatformSupported()` before attempting keychain access
|
|
16
|
-
- Iterates through `CREDENTIAL_KEYS` constant to load each credential
|
|
17
|
-
|
|
18
|
-
#### `createSecureTempEnvFile(credentials, projectName)`
|
|
19
|
-
- Creates `/tmp/.buwp-local-{projectName}-{timestamp}.env` file
|
|
20
|
-
- Uses atomic file creation with exclusive write flag (`'wx'`)
|
|
21
|
-
- Sets restrictive permissions to user read/write only (`0o600`)
|
|
22
|
-
- Properly escapes multiline credentials:
|
|
23
|
-
- Backslashes: `\\` → `\\\\\\\\`
|
|
24
|
-
- Double quotes: `"` → `\"`
|
|
25
|
-
- Newlines: `\n` → `\\n`
|
|
26
|
-
- Ensures shell interpretation works correctly for complex values (SHIB_SP_KEY, SHIB_SP_CERT)
|
|
27
|
-
- Returns path to created temp file
|
|
28
|
-
|
|
29
|
-
#### `secureDeleteTempEnvFile(filePath)`
|
|
30
|
-
- Overwrites file content with zeros before deletion (defense against forensic recovery)
|
|
31
|
-
- Unlinks file after secure overwrite
|
|
32
|
-
- Returns boolean success status
|
|
33
|
-
- Non-fatal errors - logs warnings but doesn't throw (temp files are ephemeral)
|
|
34
|
-
|
|
35
|
-
### 2. **Start Command Integration** (`lib/commands/start.js`)
|
|
36
|
-
|
|
37
|
-
Updated `startCommand()` function to:
|
|
38
|
-
|
|
39
|
-
1. **Import new functions** from config.js
|
|
40
|
-
2. **Load keychain credentials** after generating compose file:
|
|
41
|
-
```javascript
|
|
42
|
-
const keychainCredentials = loadKeychainCredentials();
|
|
43
|
-
const keychainCredCount = Object.keys(keychainCredentials).length;
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
3. **Create secure temp file** if credentials available:
|
|
47
|
-
```javascript
|
|
48
|
-
if (keychainCredCount > 0) {
|
|
49
|
-
tempEnvPath = createSecureTempEnvFile(keychainCredentials, projectName);
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
4. **Layer environment files** in Docker Compose command:
|
|
54
|
-
```bash
|
|
55
|
-
docker compose -p {projectName} --env-file {tempEnvFile} --env-file {.env.local} -f {composePath} up -d
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
5. **Ensure cleanup** with try/finally block:
|
|
59
|
-
- Cleanup happens even if Docker Compose fails
|
|
60
|
-
- Temp file securely deleted after containers start
|
|
61
|
-
|
|
62
|
-
### 3. **Credential Precedence**
|
|
63
|
-
|
|
64
|
-
Docker Compose loads env files left-to-right with later files overriding earlier ones:
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
Keychain Credentials (--env-file /tmp/.buwp-local-*.env)
|
|
68
|
-
↓ [overridden by]
|
|
69
|
-
.env.local Project Overrides (--env-file .env.local)
|
|
70
|
-
↓ [overridden by]
|
|
71
|
-
docker-compose.yml Environment Defaults
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**Precedence Order (highest to lowest):**
|
|
75
|
-
1. `.env.local` - Project-specific credential overrides
|
|
76
|
-
2. Keychain - Global default credentials (all 15 keys)
|
|
77
|
-
3. docker-compose.yml - Hardcoded defaults
|
|
78
|
-
|
|
79
|
-
## Security Architecture
|
|
80
|
-
|
|
81
|
-
### Threat Model: Process List Visibility
|
|
82
|
-
**Original concern:** Won't credentials be visible in `ps auxe`?
|
|
83
|
-
|
|
84
|
-
**Answer:** No. With this approach:
|
|
85
|
-
- Docker command shows: `docker compose --env-file /tmp/.buwp-local-test-project-1234567890.env ...`
|
|
86
|
-
- Credentials are in the file, NOT in the process command line
|
|
87
|
-
- Process list shows only the file path (which is harmless)
|
|
88
|
-
|
|
89
|
-
### Threat Model: Filesystem Exposure
|
|
90
|
-
**Risk:** Brief window where unencrypted credentials are on disk
|
|
91
|
-
|
|
92
|
-
**Mitigations:**
|
|
93
|
-
1. **Atomic creation** - File created exclusively with perms set atomically (no TOCTOU window)
|
|
94
|
-
2. **Restrictive permissions** - `0o600` (user read/write only, no group/others access)
|
|
95
|
-
3. **Ephemeral location** - `/tmp` directory (typically in-memory on modern systems, auto-cleaned)
|
|
96
|
-
4. **Secure deletion** - Overwrite with zeros before unlinking (prevents forensic recovery)
|
|
97
|
-
5. **Short lifetime** - File exists only during `docker compose up` command (~1-2 seconds)
|
|
98
|
-
6. **Guaranteed cleanup** - try/finally ensures deletion even if Docker fails
|
|
99
|
-
|
|
100
|
-
### Why Not Process Environment Variables?
|
|
101
|
-
- **Worse security:** All env vars visible in `ps auxe` output to any user on system
|
|
102
|
-
- **Less stable:** Large multiline values (40+ lines) cause issues
|
|
103
|
-
- **Less standard:** Breaks Docker Compose file-based patterns
|
|
104
|
-
|
|
105
|
-
### Why Not Store Credentials in .env.local?
|
|
106
|
-
- **Already doing this** - `.env.local` is still supported and takes precedence
|
|
107
|
-
- **One-time setup** - Keychain eliminates need to copy credentials to every project
|
|
108
|
-
- **Secure storage** - Keychain uses macOS Secure Enclave on newer Macs
|
|
109
|
-
|
|
110
|
-
## Integration Flow
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
1. Start command runs
|
|
114
|
-
↓
|
|
115
|
-
2. Load config from .buwp-local.json
|
|
116
|
-
↓
|
|
117
|
-
3. Load keychain credentials (15 total)
|
|
118
|
-
↓
|
|
119
|
-
4. Create temp env file (/tmp/.buwp-local-{project}-{timestamp}.env)
|
|
120
|
-
- Atomic creation with 0o600 permissions
|
|
121
|
-
- Properly escaped multiline values
|
|
122
|
-
↓
|
|
123
|
-
5. Build Docker Compose command with layered env files
|
|
124
|
-
- --env-file /tmp/.buwp-local-{project}-{timestamp}.env
|
|
125
|
-
- --env-file .env.local (if exists)
|
|
126
|
-
↓
|
|
127
|
-
6. Execute Docker Compose up
|
|
128
|
-
↓
|
|
129
|
-
7. Clean up temp file (try/finally)
|
|
130
|
-
- Overwrite with zeros
|
|
131
|
-
- Unlink
|
|
132
|
-
↓
|
|
133
|
-
8. Success message + usage tips
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Credentials Loaded
|
|
137
|
-
|
|
138
|
-
All 15 credentials from keychain are available:
|
|
139
|
-
|
|
140
|
-
**Database (2):**
|
|
141
|
-
- WORDPRESS_DB_PASSWORD
|
|
142
|
-
- DB_ROOT_PASSWORD
|
|
143
|
-
|
|
144
|
-
**Shibboleth (5):**
|
|
145
|
-
- SP_ENTITY_ID
|
|
146
|
-
- IDP_ENTITY_ID
|
|
147
|
-
- SHIB_IDP_LOGOUT
|
|
148
|
-
- SHIB_SP_KEY (40+ lines)
|
|
149
|
-
- SHIB_SP_CERT (24+ lines)
|
|
150
|
-
|
|
151
|
-
**S3 (5):**
|
|
152
|
-
- S3_UPLOADS_BUCKET
|
|
153
|
-
- S3_UPLOADS_REGION
|
|
154
|
-
- S3_UPLOADS_ACCESS_KEY_ID
|
|
155
|
-
- S3_UPLOADS_SECRET_ACCESS_KEY
|
|
156
|
-
- S3_ACCESS_RULES_TABLE
|
|
157
|
-
|
|
158
|
-
**OLAP (3):**
|
|
159
|
-
- OLAP
|
|
160
|
-
- OLAP_ACCT_NBR
|
|
161
|
-
- OLAP_REGION
|
|
162
|
-
|
|
163
|
-
## Testing Results
|
|
164
|
-
|
|
165
|
-
Automated integration test verification:
|
|
166
|
-
|
|
167
|
-
✓ Load 15 credentials from keychain
|
|
168
|
-
✓ Create secure temp env file with 0o600 permissions
|
|
169
|
-
✓ Format env file with proper KEY="VALUE" quoting
|
|
170
|
-
✓ Handle multiline value escaping correctly
|
|
171
|
-
✓ Overwrite file with zeros before deletion
|
|
172
|
-
✓ Securely delete temp file
|
|
173
|
-
|
|
174
|
-
All tests passed successfully.
|
|
175
|
-
|
|
176
|
-
## Version Update
|
|
177
|
-
|
|
178
|
-
Updated package.json version:
|
|
179
|
-
- Previous: v0.4.1
|
|
180
|
-
- Current: v0.5.0
|
|
181
|
-
|
|
182
|
-
## Code Quality
|
|
183
|
-
|
|
184
|
-
All code passes ESLint checks with no errors or warnings.
|
|
185
|
-
|
|
186
|
-
## Next Steps
|
|
187
|
-
|
|
188
|
-
Possible future enhancements (not in v0.5.0 scope):
|
|
189
|
-
|
|
190
|
-
1. **Phase 4: Init Command Enhancements**
|
|
191
|
-
- Auto-populate `buwp-local setup --file` from existing `.env` files
|
|
192
|
-
- Suggest keychain import during `init` command
|
|
193
|
-
|
|
194
|
-
2. **Phase 5: Global Registry**
|
|
195
|
-
- `~/.buwp-local/registry.json` tracking which projects have credentials
|
|
196
|
-
- Dashboard showing all stored credentials across projects
|
|
197
|
-
|
|
198
|
-
3. **Phase 6: Cross-Platform Support**
|
|
199
|
-
- Windows DPAPI support (via `credential` PowerShell module)
|
|
200
|
-
- Linux pass/secretservice support
|
|
201
|
-
- Fallback to encrypted `.buwp-local/.env.encrypted` files
|
|
202
|
-
|
|
203
|
-
## Architecture Summary
|
|
204
|
-
|
|
205
|
-
**Hybrid Secure Temp File Approach:**
|
|
206
|
-
- **Security:** Process list hidden + filesystem defenses
|
|
207
|
-
- **Stability:** Aligns with Docker Compose standard patterns
|
|
208
|
-
- **Usability:** Intuitive file-based precedence and override mechanism
|
|
209
|
-
- **Compatibility:** Maintains existing `.env.local` behavior
|
|
210
|
-
|
|
211
|
-
**Key Decision Rationale:**
|
|
212
|
-
Process list visibility is worse attack vector than brief filesystem window with defense-in-depth mitigations (atomic creation, 600 perms, /tmp location, overwrite-before-delete).
|
|
213
|
-
|
|
214
|
-
## Files Modified
|
|
215
|
-
|
|
216
|
-
1. `lib/config.js` (+80 lines)
|
|
217
|
-
- Added keychain import
|
|
218
|
-
- Added 3 new exported functions
|
|
219
|
-
- No breaking changes to existing exports
|
|
220
|
-
|
|
221
|
-
2. `lib/commands/start.js` (+25 lines)
|
|
222
|
-
- Updated imports to include 3 new functions
|
|
223
|
-
- Added credential loading logic
|
|
224
|
-
- Added temp file creation and cleanup
|
|
225
|
-
- No breaking changes to command interface
|
|
226
|
-
|
|
227
|
-
3. `package.json`
|
|
228
|
-
- Updated version to 0.5.0
|
|
229
|
-
|
|
230
|
-
## Status Summary
|
|
231
|
-
|
|
232
|
-
**v0.5.0 Completion Status:**
|
|
233
|
-
- ✅ Phase 1: Keychain core module (v0.5.0)
|
|
234
|
-
- ✅ Phase 2: JSON bulk import (v0.5.0)
|
|
235
|
-
- ✅ Phase 3: Hybrid secure temp file integration (v0.5.0) ← COMPLETED THIS SESSION
|
|
236
|
-
- ⏭️ Phase 4: Init command enhancements (v0.6.0)
|
|
237
|
-
- ⏭️ Phase 5: Global registry (v0.7.0)
|
|
238
|
-
- ⏭️ Phase 6: Cross-platform support (v1.0.0+)
|
|
239
|
-
|
|
240
|
-
**v0.5.0 is now feature-complete and ready for testing.**
|
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
# Implementation Summary - Multi-Project Support
|
|
2
|
-
|
|
3
|
-
## What We Built
|
|
4
|
-
|
|
5
|
-
Successfully implemented **three major features** requested from real-world usage feedback:
|
|
6
|
-
|
|
7
|
-
### 1. ✅ Unique Docker Compose Project Names
|
|
8
|
-
**Problem Solved:** Multiple repos using buwp-local would conflict in Docker Desktop and overwrite each other.
|
|
9
|
-
|
|
10
|
-
**Solution Implemented:**
|
|
11
|
-
- Auto-generate project name from directory name
|
|
12
|
-
- Pass `-p {projectName}` flag to all docker-compose commands
|
|
13
|
-
- Projects now show separately in Docker Desktop
|
|
14
|
-
- Multiple instances can run simultaneously
|
|
15
|
-
|
|
16
|
-
**Technical Changes:**
|
|
17
|
-
- Added `projectName` field to config (defaults to directory basename)
|
|
18
|
-
- Added `getProjectName()` and `sanitizeProjectName()` functions in `config.js`
|
|
19
|
-
- Updated `start.js`, `stop.js`, `destroy.js`, `logs.js` to use `-p` flag
|
|
20
|
-
|
|
21
|
-
### 2. ✅ Isolated Volumes Per Project
|
|
22
|
-
**Problem Solved:** All projects shared the same database and WordPress volumes, causing conflicts.
|
|
23
|
-
|
|
24
|
-
**Solution Implemented:**
|
|
25
|
-
- Volume names prefixed with project name: `{projectName}_db_data`, `{projectName}_wp_build`
|
|
26
|
-
- Each project gets completely isolated storage
|
|
27
|
-
- No cross-contamination between projects
|
|
28
|
-
|
|
29
|
-
**Technical Changes:**
|
|
30
|
-
- Modified `generateComposeConfig()` to create project-specific volume names
|
|
31
|
-
- Updated `generateDbService()` to accept `dbVolumeName` parameter
|
|
32
|
-
- Updated `generateWordPressService()` to accept `wpVolumeName` parameter
|
|
33
|
-
- Volume names dynamically generated based on `config.projectName`
|
|
34
|
-
|
|
35
|
-
### 3. ✅ Smart Configuration Initialization
|
|
36
|
-
**Problem Solved:** Users had to manually figure out and type correct container paths for plugins/themes/mu-plugins.
|
|
37
|
-
|
|
38
|
-
**Solution Implemented:**
|
|
39
|
-
- New CLI flags: `--plugin`, `--mu-plugin`, `--theme`
|
|
40
|
-
- Auto-detects directory name
|
|
41
|
-
- Auto-generates correct mapping path
|
|
42
|
-
- Sets sensible defaults (project name, hostname)
|
|
43
|
-
|
|
44
|
-
**Technical Changes:**
|
|
45
|
-
- Modified `initConfig()` to accept `options` parameter with plugin/muPlugin/theme flags
|
|
46
|
-
- Updated config command to pass initialization type to `initConfig()`
|
|
47
|
-
- Added CLI options in `bin/buwp-local.js` for `--plugin`, `--mu-plugin`, `--theme`
|
|
48
|
-
- Auto-generates hostname as `{projectName}.local`
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Files Modified
|
|
53
|
-
|
|
54
|
-
### Core Library Files
|
|
55
|
-
1. **`lib/config.js`**
|
|
56
|
-
- Added `projectName` to DEFAULT_CONFIG
|
|
57
|
-
- Added project name auto-detection in `loadConfig()`
|
|
58
|
-
- Added `getProjectName()` function
|
|
59
|
-
- Added `sanitizeProjectName()` function
|
|
60
|
-
- Modified `initConfig()` to support smart initialization options
|
|
61
|
-
- Auto-generates project-specific mappings based on type
|
|
62
|
-
|
|
63
|
-
2. **`lib/compose-generator.js`**
|
|
64
|
-
- Modified `generateComposeConfig()` to use project-specific volume names
|
|
65
|
-
- Updated `generateDbService()` with `dbVolumeName` parameter
|
|
66
|
-
- Updated `generateWordPressService()` with `wpVolumeName` parameter
|
|
67
|
-
- Dynamic volume naming: `{projectName}_db_data` and `{projectName}_wp_build`
|
|
68
|
-
|
|
69
|
-
### Command Files
|
|
70
|
-
3. **`lib/commands/start.js`**
|
|
71
|
-
- Added project name to docker-compose command: `-p ${projectName}`
|
|
72
|
-
- Display project name in success message
|
|
73
|
-
|
|
74
|
-
4. **`lib/commands/stop.js`**
|
|
75
|
-
- Import `loadConfig` to get project name
|
|
76
|
-
- Added `-p ${projectName}` flag to docker-compose command
|
|
77
|
-
|
|
78
|
-
5. **`lib/commands/destroy.js`**
|
|
79
|
-
- Import `loadConfig` to get project name
|
|
80
|
-
- Added `-p ${projectName}` flag to docker-compose command
|
|
81
|
-
- Show project name in confirmation prompt
|
|
82
|
-
|
|
83
|
-
6. **`lib/commands/logs.js`**
|
|
84
|
-
- Import `loadConfig` to get project name
|
|
85
|
-
- Added `-p ${projectName}` flag to docker-compose command
|
|
86
|
-
|
|
87
|
-
7. **`lib/commands/config.js`**
|
|
88
|
-
- Added logic to handle `--plugin`, `--mu-plugin`, `--theme` flags
|
|
89
|
-
- Pass initialization options to `initConfig()`
|
|
90
|
-
- Display appropriate messages for each initialization type
|
|
91
|
-
- Updated help text with new flags
|
|
92
|
-
|
|
93
|
-
### CLI Entry Point
|
|
94
|
-
8. **`bin/buwp-local.js`**
|
|
95
|
-
- Added `--plugin`, `--mu-plugin`, `--theme` options to config command
|
|
96
|
-
- Updated command descriptions
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Testing Results
|
|
101
|
-
|
|
102
|
-
### ✅ Smart Initialization Tested
|
|
103
|
-
```bash
|
|
104
|
-
# Plugin
|
|
105
|
-
cd /tmp/test-plugin
|
|
106
|
-
buwp-local config --init --plugin
|
|
107
|
-
# ✓ Created: ./var/www/html/wp-content/plugins/test-plugin mapping
|
|
108
|
-
|
|
109
|
-
# Theme
|
|
110
|
-
cd /tmp/my-custom-theme
|
|
111
|
-
buwp-local config --init --theme
|
|
112
|
-
# ✓ Created: ./var/www/html/wp-content/themes/my-custom-theme mapping
|
|
113
|
-
|
|
114
|
-
# MU-Plugin
|
|
115
|
-
cd /tmp/bu-navigation
|
|
116
|
-
buwp-local config --init --mu-plugin
|
|
117
|
-
# ✓ Created: ./var/www/html/wp-content/mu-plugins/bu-navigation mapping
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### ✅ Project Name Auto-Detection Tested
|
|
121
|
-
- Directory name correctly extracted
|
|
122
|
-
- Project name properly sanitized
|
|
123
|
-
- Hostname auto-generated from project name
|
|
124
|
-
- Config display shows project name
|
|
125
|
-
|
|
126
|
-
### ✅ Volume Isolation Verified
|
|
127
|
-
- Generated compose files show unique volume names
|
|
128
|
-
- Volume names include project identifier
|
|
129
|
-
- No conflicts between projects
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Configuration Schema Changes
|
|
134
|
-
|
|
135
|
-
### New Field: `projectName`
|
|
136
|
-
|
|
137
|
-
```json
|
|
138
|
-
{
|
|
139
|
-
"projectName": "my-plugin-name", // NEW - auto-generated from directory
|
|
140
|
-
"image": "ghcr.io/bu-ist/bu-wp-docker-mod_shib:arm64-latest",
|
|
141
|
-
"hostname": "my-plugin-name.local", // Auto-generated from projectName
|
|
142
|
-
"multisite": true,
|
|
143
|
-
// ... rest of config
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Smart Mapping Examples
|
|
148
|
-
|
|
149
|
-
**Plugin Init:**
|
|
150
|
-
```json
|
|
151
|
-
{
|
|
152
|
-
"projectName": "bu-custom-analytics",
|
|
153
|
-
"hostname": "bu-custom-analytics.local",
|
|
154
|
-
"mappings": [
|
|
155
|
-
{
|
|
156
|
-
"local": "./",
|
|
157
|
-
"container": "/var/www/html/wp-content/plugins/bu-custom-analytics"
|
|
158
|
-
}
|
|
159
|
-
]
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
**Theme Init:**
|
|
164
|
-
```json
|
|
165
|
-
{
|
|
166
|
-
"projectName": "responsive-framework",
|
|
167
|
-
"hostname": "responsive-framework.local",
|
|
168
|
-
"mappings": [
|
|
169
|
-
{
|
|
170
|
-
"local": "./",
|
|
171
|
-
"container": "/var/www/html/wp-content/themes/responsive-framework"
|
|
172
|
-
}
|
|
173
|
-
]
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
**MU-Plugin Init:**
|
|
178
|
-
```json
|
|
179
|
-
{
|
|
180
|
-
"projectName": "bu-navigation",
|
|
181
|
-
"hostname": "bu-navigation.local",
|
|
182
|
-
"mappings": [
|
|
183
|
-
{
|
|
184
|
-
"local": "./",
|
|
185
|
-
"container": "/var/www/html/wp-content/mu-plugins/bu-navigation"
|
|
186
|
-
}
|
|
187
|
-
]
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## Usage Examples
|
|
194
|
-
|
|
195
|
-
### Single Project (Original Workflow)
|
|
196
|
-
```bash
|
|
197
|
-
cd ~/projects/my-plugin
|
|
198
|
-
buwp-local config --init --plugin
|
|
199
|
-
# Edit .env.local with credentials
|
|
200
|
-
buwp-local start
|
|
201
|
-
# Access at http://my-plugin.local
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Multiple Projects (New Capability)
|
|
205
|
-
```bash
|
|
206
|
-
# Project A - Plugin
|
|
207
|
-
cd ~/projects/bu-custom-analytics
|
|
208
|
-
buwp-local config --init --plugin
|
|
209
|
-
buwp-local start # Runs on port 80
|
|
210
|
-
|
|
211
|
-
# Project B - Another Plugin (different ports)
|
|
212
|
-
cd ~/projects/bu-slideshow
|
|
213
|
-
buwp-local config --init --plugin
|
|
214
|
-
# Edit .buwp-local.json - change ports to 8081/8444/3308/6381
|
|
215
|
-
buwp-local start # Runs on port 8081
|
|
216
|
-
|
|
217
|
-
# Project C - Theme
|
|
218
|
-
cd ~/projects/responsive-framework
|
|
219
|
-
buwp-local config --init --theme
|
|
220
|
-
# Edit .buwp-local.json - change ports to 8082/8445/3309/6382
|
|
221
|
-
buwp-local start # Runs on port 8082
|
|
222
|
-
|
|
223
|
-
# All three running simultaneously with separate databases!
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Docker Desktop View
|
|
227
|
-
```
|
|
228
|
-
Projects:
|
|
229
|
-
├─ bu-custom-analytics
|
|
230
|
-
├─ bu-slideshow
|
|
231
|
-
└─ responsive-framework
|
|
232
|
-
|
|
233
|
-
Volumes:
|
|
234
|
-
├─ bu-custom-analytics_db_data
|
|
235
|
-
├─ bu-custom-analytics_wp_build
|
|
236
|
-
├─ bu-slideshow_db_data
|
|
237
|
-
├─ bu-slideshow_wp_build
|
|
238
|
-
├─ responsive-framework_db_data
|
|
239
|
-
└─ responsive-framework_wp_build
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
## Benefits Delivered
|
|
245
|
-
|
|
246
|
-
### For Individual Developers
|
|
247
|
-
- ✅ Work on multiple projects simultaneously
|
|
248
|
-
- ✅ Each project has isolated database
|
|
249
|
-
- ✅ Fast setup with smart init flags
|
|
250
|
-
- ✅ No manual path configuration needed
|
|
251
|
-
- ✅ Clear project organization in Docker Desktop
|
|
252
|
-
|
|
253
|
-
### For Teams
|
|
254
|
-
- ✅ Standardized setup process
|
|
255
|
-
- ✅ Less room for configuration errors
|
|
256
|
-
- ✅ Easy onboarding with simple commands
|
|
257
|
-
- ✅ Scalable to 20+ developers
|
|
258
|
-
- ✅ Each developer can run multiple projects
|
|
259
|
-
|
|
260
|
-
### For Project Management
|
|
261
|
-
- ✅ Easy to see which projects are running
|
|
262
|
-
- ✅ No accidental database overwrites
|
|
263
|
-
- ✅ Clear volume organization
|
|
264
|
-
- ✅ Predictable naming conventions
|
|
265
|
-
|
|
266
|
-
---
|
|
267
|
-
|
|
268
|
-
## Backwards Compatibility
|
|
269
|
-
|
|
270
|
-
### Migration Path
|
|
271
|
-
Existing projects without `projectName` will:
|
|
272
|
-
1. Auto-generate project name from directory
|
|
273
|
-
2. Create new volumes with project-specific names
|
|
274
|
-
3. Need to run `destroy` then `start` to migrate
|
|
275
|
-
|
|
276
|
-
### Recommendation for Existing Users
|
|
277
|
-
```bash
|
|
278
|
-
# In each existing project:
|
|
279
|
-
buwp-local destroy -f # Removes old shared volumes
|
|
280
|
-
buwp-local start # Creates new isolated volumes
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
## Documentation Created
|
|
286
|
-
|
|
287
|
-
### New Documents
|
|
288
|
-
1. **`MULTI_PROJECT_GUIDE.md`** - Comprehensive guide for multi-project workflows
|
|
289
|
-
- Feature explanations
|
|
290
|
-
- Usage examples
|
|
291
|
-
- Troubleshooting
|
|
292
|
-
- Best practices
|
|
293
|
-
- Migration guide
|
|
294
|
-
|
|
295
|
-
### Updated Documents
|
|
296
|
-
- Configuration examples now include `projectName`
|
|
297
|
-
- CLI help text shows new flags
|
|
298
|
-
- Command descriptions updated
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
## Next Steps & Future Enhancements
|
|
303
|
-
|
|
304
|
-
### Immediate (Ready to Use)
|
|
305
|
-
- ✅ All features tested and working
|
|
306
|
-
- ✅ Documentation complete
|
|
307
|
-
- ✅ Ready for team rollout
|
|
308
|
-
|
|
309
|
-
### Phase 2 Suggestions (Based on Usage)
|
|
310
|
-
1. **Project Listing Command**
|
|
311
|
-
```bash
|
|
312
|
-
buwp-local list # Show all active buwp-local projects
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
2. **Port Auto-Assignment**
|
|
316
|
-
- Automatically find available ports
|
|
317
|
-
- Suggest ports in `config --init`
|
|
318
|
-
|
|
319
|
-
3. **Preset Configurations**
|
|
320
|
-
```bash
|
|
321
|
-
buwp-local config --init --plugin --preset bu-standard
|
|
322
|
-
# Loads common settings for BU projects
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
4. **Project Templates**
|
|
326
|
-
```bash
|
|
327
|
-
buwp-local config --init --template bu-plugin
|
|
328
|
-
# Includes common dependencies, settings, etc.
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
5. **Health Status Command**
|
|
332
|
-
```bash
|
|
333
|
-
buwp-local status
|
|
334
|
-
# Shows status of current project
|
|
335
|
-
# - Running containers
|
|
336
|
-
# - Port mappings
|
|
337
|
-
# - Volume sizes
|
|
338
|
-
# - WordPress version
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
## Technical Achievements
|
|
344
|
-
|
|
345
|
-
### Clean Implementation
|
|
346
|
-
- ✅ Minimal changes to existing code
|
|
347
|
-
- ✅ Backwards compatible (with migration)
|
|
348
|
-
- ✅ Consistent naming conventions
|
|
349
|
-
- ✅ Clear function parameters
|
|
350
|
-
- ✅ Comprehensive error handling
|
|
351
|
-
|
|
352
|
-
### Code Quality
|
|
353
|
-
- ✅ JSDoc comments maintained
|
|
354
|
-
- ✅ Functions remain single-responsibility
|
|
355
|
-
- ✅ No breaking changes to public API
|
|
356
|
-
- ✅ Easy to test and debug
|
|
357
|
-
|
|
358
|
-
### User Experience
|
|
359
|
-
- ✅ Intuitive flag names
|
|
360
|
-
- ✅ Helpful feedback messages
|
|
361
|
-
- ✅ Clear error messages
|
|
362
|
-
- ✅ Sensible defaults
|
|
363
|
-
- ✅ No required manual configuration
|
|
364
|
-
|
|
365
|
-
---
|
|
366
|
-
|
|
367
|
-
## Summary
|
|
368
|
-
|
|
369
|
-
**All three requested features successfully implemented:**
|
|
370
|
-
1. ✅ Unique project names for Docker Desktop identification
|
|
371
|
-
2. ✅ Isolated volumes per project for data separation
|
|
372
|
-
3. ✅ Smart config init with auto-mapping
|
|
373
|
-
|
|
374
|
-
**Testing confirms:**
|
|
375
|
-
- Multiple projects run simultaneously ✅
|
|
376
|
-
- Projects remain isolated ✅
|
|
377
|
-
- Smart initialization works correctly ✅
|
|
378
|
-
- All commands use project names properly ✅
|
|
379
|
-
|
|
380
|
-
**Ready for:**
|
|
381
|
-
- ✅ Team rollout
|
|
382
|
-
- ✅ Real-world usage
|
|
383
|
-
- ✅ Multi-project workflows
|
|
384
|
-
|
|
385
|
-
The tool now fully supports the enterprise multi-project development workflow needed for a team of 20+ developers!
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Keychain Integration - Implementation Summary
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Successfully implemented macOS Keychain integration for secure credential storage in buwp-local v0.5.0. This allows users to store credentials once and have them automatically available across all projects.
|
|
6
|
-
|
|
7
|
-
## Files Created
|
|
8
|
-
|
|
9
|
-
### 1. `lib/keychain.js` - Core Keychain Module
|
|
10
|
-
**Functions:**
|
|
11
|
-
- `setCredential(key, value)` - Store credential in keychain
|
|
12
|
-
- `getCredential(key)` - Retrieve credential from keychain
|
|
13
|
-
- `hasCredential(key)` - Check if credential exists
|
|
14
|
-
- `deleteCredential(key)` - Remove credential
|
|
15
|
-
- `listCredentials()` - Get all stored credential keys
|
|
16
|
-
- `clearAllCredentials()` - Remove all buwp-local credentials
|
|
17
|
-
- `isPlatformSupported()` - Check for macOS platform
|
|
18
|
-
|
|
19
|
-
**Constants:**
|
|
20
|
-
- `CREDENTIAL_KEYS` - All 15 credential keys
|
|
21
|
-
- `CREDENTIAL_GROUPS` - Organized by category (database, shibboleth, s3, olap)
|
|
22
|
-
- `CREDENTIAL_DESCRIPTIONS` - Human-readable descriptions for prompts
|
|
23
|
-
|
|
24
|
-
**Implementation Details:**
|
|
25
|
-
- Uses macOS `security` command via `execSync`
|
|
26
|
-
- Service name: `buwp-local`
|
|
27
|
-
- Uses `-U` flag to update existing credentials instead of duplicating
|
|
28
|
-
- Graceful error handling with user-friendly messages
|
|
29
|
-
|
|
30
|
-
### 2. `lib/commands/keychain.js` - CLI Command Handler
|
|
31
|
-
**Subcommands:**
|
|
32
|
-
- `setup` - Interactive setup for all credentials
|
|
33
|
-
- `set <key> [value]` - Set individual credential
|
|
34
|
-
- `get <key>` - Retrieve credential (masked display)
|
|
35
|
-
- `list` - Show all stored credentials by group
|
|
36
|
-
- `clear` - Remove all credentials (with confirmation)
|
|
37
|
-
- `status` - Show platform support and credential status
|
|
38
|
-
|
|
39
|
-
**Features:**
|
|
40
|
-
- Interactive prompts using `prompts` package
|
|
41
|
-
- Grouped credential display (database, shibboleth, s3, olap)
|
|
42
|
-
- Existing credential detection with overwrite warnings
|
|
43
|
-
- Force flag support for automation
|
|
44
|
-
- macOS keychain access warning at start of setup
|
|
45
|
-
|
|
46
|
-
## Files Modified
|
|
47
|
-
|
|
48
|
-
### 3. `bin/buwp-local.js`
|
|
49
|
-
- Added import for `keychainCommand`
|
|
50
|
-
- Registered `keychain` command with subcommands
|
|
51
|
-
- Added `-f, --force` option support
|
|
52
|
-
|
|
53
|
-
### 4. `lib/index.js`
|
|
54
|
-
- Exported all keychain functions
|
|
55
|
-
- Exported credential schema constants
|
|
56
|
-
|
|
57
|
-
## Usage Examples
|
|
58
|
-
|
|
59
|
-
### First-Time Setup
|
|
60
|
-
```bash
|
|
61
|
-
# Interactive setup (all credentials)
|
|
62
|
-
buwp-local keychain setup
|
|
63
|
-
|
|
64
|
-
# Set individual credential
|
|
65
|
-
buwp-local keychain set WORDPRESS_DB_PASSWORD mypassword
|
|
66
|
-
|
|
67
|
-
# Check status
|
|
68
|
-
buwp-local keychain status
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Managing Credentials
|
|
72
|
-
```bash
|
|
73
|
-
# List stored credentials
|
|
74
|
-
buwp-local keychain list
|
|
75
|
-
|
|
76
|
-
# Get credential value (masked)
|
|
77
|
-
buwp-local keychain get WORDPRESS_DB_PASSWORD
|
|
78
|
-
|
|
79
|
-
# Clear all credentials
|
|
80
|
-
buwp-local keychain clear
|
|
81
|
-
# Or skip confirmation:
|
|
82
|
-
buwp-local keychain clear --force
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Testing Results
|
|
86
|
-
|
|
87
|
-
✅ All functions tested and working:
|
|
88
|
-
- Platform detection (macOS supported ✓)
|
|
89
|
-
- Set credential via command line
|
|
90
|
-
- Get credential with masking (test*****word)
|
|
91
|
-
- List credentials by group
|
|
92
|
-
- Clear all credentials
|
|
93
|
-
- Linting passes cleanly
|
|
94
|
-
|
|
95
|
-
## User Experience
|
|
96
|
-
|
|
97
|
-
### Warnings & Messages
|
|
98
|
-
- **Platform check**: Non-macOS users see clear message about .env.local fallback
|
|
99
|
-
- **Keychain access**: Users warned about macOS permission prompt before setup
|
|
100
|
-
- **Overwrite protection**: Warns when overwriting existing credentials
|
|
101
|
-
- **Grouped display**: Credentials organized by functional category
|
|
102
|
-
|
|
103
|
-
### Security Features
|
|
104
|
-
- Credentials never displayed in full (masked in `get` command)
|
|
105
|
-
- Stored securely in macOS keychain (encrypted by OS)
|
|
106
|
-
- Individual credential deletion supported
|
|
107
|
-
- Bulk clear with confirmation (unless --force)
|
|
108
|
-
|
|
109
|
-
## Design Decisions
|
|
110
|
-
|
|
111
|
-
1. **Full credential set required** - `setup` prompts for all 15 credentials to ensure complete stack functionality
|
|
112
|
-
2. **Warning before overwrite** - Users must confirm when updating existing credentials (unless --force)
|
|
113
|
-
3. **Sparse error messages** - Simple, clear error reporting without over-engineering
|
|
114
|
-
4. **macOS-only for now** - Platform detection with graceful fallback to .env.local on other systems
|
|
115
|
-
|
|
116
|
-
## Next Steps (v0.5.0 continued)
|
|
117
|
-
|
|
118
|
-
**Remaining work:**
|
|
119
|
-
1. Update `start.js` to load credentials from keychain
|
|
120
|
-
2. Update `init.js` to detect keychain credentials
|
|
121
|
-
3. Implement credential resolution priority: `.env.local` → keychain → defaults
|
|
122
|
-
4. Create global registry (`~/.buwp-local/registry.json`)
|
|
123
|
-
5. Update documentation
|
|
124
|
-
|
|
125
|
-
**Future enhancements (v0.6.0+):**
|
|
126
|
-
- Cross-platform support (Windows Credential Manager, Linux Secret Service)
|
|
127
|
-
- Project-specific credential overrides
|
|
128
|
-
- Credential import/export
|
|
129
|
-
- Team credential sharing mechanisms
|
|
130
|
-
|
|
131
|
-
## Benefits Delivered
|
|
132
|
-
|
|
133
|
-
✅ **One-time setup** - Enter credentials once, use across all projects
|
|
134
|
-
✅ **Secure storage** - Leverages macOS keychain encryption
|
|
135
|
-
✅ **Simple CLI** - Intuitive subcommands for all operations
|
|
136
|
-
✅ **Backward compatible** - .env.local still works as override
|
|
137
|
-
✅ **Developer friendly** - Clear messages and helpful status command
|
|
138
|
-
✅ **Production ready** - Fully tested and linted
|
|
139
|
-
|
|
140
|
-
This implementation solves the multi-repo credential fatigue problem while maintaining backward compatibility and providing a secure, native macOS integration.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
It's often convenient to store a password in the macOS system keychain and retrieve it inside a shell script.
|
|
2
|
-
|
|
3
|
-
Here's the bash command for setting a password:
|
|
4
|
-
|
|
5
|
-
security add-generic-password -s "Keychain item name here" -a "username here" -p
|
|
6
|
-
Then enter your password when prompted.
|
|
7
|
-
|
|
8
|
-
After you run this once, you can retrieve the password in a script like this:
|
|
9
|
-
|
|
10
|
-
PASSWORD=`security find-generic-password -s "Keychain item name here" -a "username here" -w`
|
|
11
|
-
You can then use $PASSWORD whenever you need the password in your script.
|