Compare commits
3 Commits
ed511b1e3c
...
d7390a3a80
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7390a3a80 | ||
|
|
4a84c08a2b | ||
|
|
d3a14a2b31 |
@@ -35,7 +35,9 @@
|
|||||||
"Bash(git commit:*)",
|
"Bash(git commit:*)",
|
||||||
"Bash(git merge:*)",
|
"Bash(git merge:*)",
|
||||||
"Bash(git rm:*)",
|
"Bash(git rm:*)",
|
||||||
"Bash(git checkout:*)"
|
"Bash(git checkout:*)",
|
||||||
|
"Bash(git push:*)",
|
||||||
|
"Bash(Start-Sleep -Seconds 10)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -87,3 +87,10 @@ tmp/
|
|||||||
temp/
|
temp/
|
||||||
*.tmp
|
*.tmp
|
||||||
.claude/settings.local.json
|
.claude/settings.local.json
|
||||||
|
|
||||||
|
# Node/NPM
|
||||||
|
frontend/node_modules/
|
||||||
|
frontend/.angular/
|
||||||
|
frontend/dist/
|
||||||
|
# Keep .npmrc but ignore sensitive auth info
|
||||||
|
# The active .npmrc will be generated from .npmrc.public or .npmrc.artifactory
|
||||||
|
|||||||
43
Dockerfile
43
Dockerfile
@@ -1,15 +1,49 @@
|
|||||||
|
# Multi-stage build: First stage builds Angular frontend
|
||||||
|
FROM node:18-alpine as frontend-builder
|
||||||
|
|
||||||
|
# Build argument to select npm registry (public or artifactory)
|
||||||
|
ARG NPM_REGISTRY=public
|
||||||
|
ARG ARTIFACTORY_AUTH_TOKEN=""
|
||||||
|
|
||||||
|
# Install dependencies for native modules
|
||||||
|
RUN apk add --no-cache python3 make g++
|
||||||
|
|
||||||
|
WORKDIR /frontend
|
||||||
|
|
||||||
|
# Copy package files and registry configs
|
||||||
|
COPY frontend/package*.json ./
|
||||||
|
COPY frontend/.npmrc.${NPM_REGISTRY} ./.npmrc
|
||||||
|
|
||||||
|
# If using artifactory and auth token is provided, configure it
|
||||||
|
RUN if [ "$NPM_REGISTRY" = "artifactory" ] && [ -n "$ARTIFACTORY_AUTH_TOKEN" ]; then \
|
||||||
|
echo "Configuring Artifactory authentication..."; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean install dependencies
|
||||||
|
RUN npm ci --force
|
||||||
|
|
||||||
|
# Copy frontend source
|
||||||
|
COPY frontend/src ./src
|
||||||
|
COPY frontend/public ./public
|
||||||
|
COPY frontend/angular.json ./
|
||||||
|
COPY frontend/tsconfig*.json ./
|
||||||
|
|
||||||
|
# Build the Angular app for production
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Second stage: Python backend with Angular static files
|
||||||
FROM python:3.11-alpine
|
FROM python:3.11-alpine
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install system dependencies for Alpine
|
# Install system dependencies for Alpine
|
||||||
# Alpine uses apk instead of apt-get and is lighter/faster
|
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
gcc \
|
gcc \
|
||||||
musl-dev \
|
musl-dev \
|
||||||
postgresql-dev \
|
postgresql-dev \
|
||||||
postgresql-client \
|
postgresql-client \
|
||||||
linux-headers
|
linux-headers \
|
||||||
|
curl
|
||||||
|
|
||||||
# Copy requirements and install Python dependencies
|
# Copy requirements and install Python dependencies
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
@@ -21,6 +55,9 @@ COPY utils/ ./utils/
|
|||||||
COPY alembic/ ./alembic/
|
COPY alembic/ ./alembic/
|
||||||
COPY alembic.ini .
|
COPY alembic.ini .
|
||||||
|
|
||||||
|
# Copy Angular build from frontend-builder stage
|
||||||
|
COPY --from=frontend-builder /frontend/dist/frontend/browser ./static
|
||||||
|
|
||||||
# Create non-root user (Alpine uses adduser instead of useradd)
|
# Create non-root user (Alpine uses adduser instead of useradd)
|
||||||
RUN adduser -D -u 1000 appuser && chown -R appuser:appuser /app
|
RUN adduser -D -u 1000 appuser && chown -R appuser:appuser /app
|
||||||
USER appuser
|
USER appuser
|
||||||
@@ -30,7 +67,7 @@ EXPOSE 8000
|
|||||||
|
|
||||||
# Health check
|
# Health check
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
CMD python -c "import requests; requests.get('http://localhost:8000/health')"
|
CMD curl -f http://localhost:8000/health
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ RUN npm run build --verbose
|
|||||||
# Production image with nginx
|
# Production image with nginx
|
||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
|
|
||||||
# Copy built Angular app
|
# Copy built Angular app from the browser subdirectory
|
||||||
COPY --from=frontend-builder /frontend/dist/frontend /usr/share/nginx/html
|
COPY --from=frontend-builder /frontend/dist/frontend/browser /usr/share/nginx/html
|
||||||
|
|
||||||
# Copy nginx configuration
|
# Copy nginx configuration
|
||||||
COPY nginx.conf /etc/nginx/nginx.conf
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -269,6 +269,23 @@ Store compiled binaries, test data files, or any binary artifacts with full meta
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
### NPM Registry Configuration
|
||||||
|
|
||||||
|
The frontend supports working with multiple npm registries (public npm vs corporate Artifactory). See [frontend/README-REGISTRY.md](frontend/README-REGISTRY.md) for detailed instructions.
|
||||||
|
|
||||||
|
**Quick switch:**
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Use public npm (default)
|
||||||
|
npm run registry:public
|
||||||
|
npm ci --force
|
||||||
|
|
||||||
|
# Use Artifactory
|
||||||
|
npm run registry:artifactory
|
||||||
|
npm ci --force
|
||||||
|
```
|
||||||
|
|
||||||
### Running Tests
|
### Running Tests
|
||||||
```bash
|
```bash
|
||||||
pytest tests/ -v
|
pytest tests/ -v
|
||||||
|
|||||||
55
app/main.py
55
app/main.py
@@ -1,5 +1,7 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from fastapi.responses import FileResponse
|
||||||
from app.api.artifacts import router as artifacts_router
|
from app.api.artifacts import router as artifacts_router
|
||||||
from app.api.seed import router as seed_router
|
from app.api.seed import router as seed_router
|
||||||
from app.api.tags import router as tags_router
|
from app.api.tags import router as tags_router
|
||||||
@@ -7,6 +9,7 @@ from app.database import init_db
|
|||||||
from app.config import settings
|
from app.config import settings
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
# Configure logging
|
# Configure logging
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@@ -39,7 +42,8 @@ app.include_router(artifacts_router)
|
|||||||
app.include_router(seed_router)
|
app.include_router(seed_router)
|
||||||
app.include_router(tags_router)
|
app.include_router(tags_router)
|
||||||
|
|
||||||
# Note: Frontend is now served separately as an Angular application
|
# Static files configuration - will be set up after routes
|
||||||
|
static_dir = Path("/app/static")
|
||||||
|
|
||||||
|
|
||||||
@app.on_event("startup")
|
@app.on_event("startup")
|
||||||
@@ -65,16 +69,20 @@ async def api_root():
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
async def ui_root():
|
async def serve_angular_app():
|
||||||
"""API root - Frontend is served separately"""
|
"""Serve Angular app index.html"""
|
||||||
return {
|
static_dir = Path("/app/static")
|
||||||
"message": "Test Artifact Data Lake API",
|
if static_dir.exists():
|
||||||
"version": "1.0.0",
|
return FileResponse(static_dir / "index.html")
|
||||||
"docs": "/docs",
|
else:
|
||||||
"frontend": "Frontend is served separately on port 4200 (development) or via reverse proxy (production)",
|
# Fallback if static files not found
|
||||||
"deployment_mode": settings.deployment_mode,
|
return {
|
||||||
"storage_backend": settings.storage_backend
|
"message": "Test Artifact Data Lake API",
|
||||||
}
|
"version": "1.0.0",
|
||||||
|
"docs": "/docs",
|
||||||
|
"deployment_mode": settings.deployment_mode,
|
||||||
|
"storage_backend": settings.storage_backend
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/health")
|
@app.get("/health")
|
||||||
@@ -83,6 +91,31 @@ async def health_check():
|
|||||||
return {"status": "healthy"}
|
return {"status": "healthy"}
|
||||||
|
|
||||||
|
|
||||||
|
# Catch-all route for Angular client-side routing
|
||||||
|
# This must be last to not interfere with API routes
|
||||||
|
@app.get("/{full_path:path}")
|
||||||
|
async def catch_all(full_path: str):
|
||||||
|
"""Serve Angular app for all non-API routes (SPA routing)"""
|
||||||
|
if static_dir.exists():
|
||||||
|
# Check if the requested path is a file in the static directory
|
||||||
|
file_path = static_dir / full_path
|
||||||
|
if file_path.is_file() and file_path.exists():
|
||||||
|
# Determine media type based on file extension
|
||||||
|
media_type = None
|
||||||
|
if file_path.suffix == ".js":
|
||||||
|
media_type = "application/javascript"
|
||||||
|
elif file_path.suffix == ".css":
|
||||||
|
media_type = "text/css"
|
||||||
|
elif file_path.suffix in [".png", ".jpg", ".jpeg", ".gif", ".svg", ".ico"]:
|
||||||
|
media_type = f"image/{file_path.suffix[1:]}"
|
||||||
|
return FileResponse(file_path, media_type=media_type)
|
||||||
|
# Otherwise, serve index.html for client-side routing
|
||||||
|
index_path = static_dir / "index.html"
|
||||||
|
if index_path.exists():
|
||||||
|
return FileResponse(index_path, media_type="text/html")
|
||||||
|
return {"error": "Static files not found"}
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ services:
|
|||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
|
||||||
api:
|
app:
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
@@ -52,13 +52,11 @@ services:
|
|||||||
minio:
|
minio:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:8000/health')"]
|
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
||||||
interval: 30s
|
interval: 10s
|
||||||
timeout: 10s
|
timeout: 5s
|
||||||
retries: 3
|
retries: 5
|
||||||
|
start_period: 40s
|
||||||
# Frontend service removed from default compose - use dev-start.sh for development
|
|
||||||
# For production with built frontend, use: docker-compose -f docker-compose.production.yml up
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres_data:
|
postgres_data:
|
||||||
|
|||||||
1
frontend/.npmrc
Normal file
1
frontend/.npmrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
registry=https://registry.npmjs.org/
|
||||||
11
frontend/.npmrc.artifactory
Normal file
11
frontend/.npmrc.artifactory
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Replace YOUR_ARTIFACTORY_URL with your actual Artifactory URL
|
||||||
|
registry=https://YOUR_ARTIFACTORY_URL/artifactory/api/npm/npm-virtual/
|
||||||
|
|
||||||
|
# If authentication is required, uncomment and configure:
|
||||||
|
# //YOUR_ARTIFACTORY_URL/artifactory/api/npm/npm-virtual/:_auth=${ARTIFACTORY_AUTH_TOKEN}
|
||||||
|
# //YOUR_ARTIFACTORY_URL/artifactory/api/npm/npm-virtual/:always-auth=true
|
||||||
|
|
||||||
|
# Alternative: username/password (less secure, not recommended)
|
||||||
|
# //YOUR_ARTIFACTORY_URL/artifactory/api/npm/npm-virtual/:username=${ARTIFACTORY_USERNAME}
|
||||||
|
# //YOUR_ARTIFACTORY_URL/artifactory/api/npm/npm-virtual/:_password=${ARTIFACTORY_PASSWORD}
|
||||||
|
# //YOUR_ARTIFACTORY_URL/artifactory/api/npm/npm-virtual/:email=your-email@company.com
|
||||||
1
frontend/.npmrc.public
Normal file
1
frontend/.npmrc.public
Normal file
@@ -0,0 +1 @@
|
|||||||
|
registry=https://registry.npmjs.org/
|
||||||
192
frontend/README-REGISTRY.md
Normal file
192
frontend/README-REGISTRY.md
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
# NPM Registry Configuration
|
||||||
|
|
||||||
|
This project supports working with two different npm registries:
|
||||||
|
1. **Public registry** - registry.npmjs.org (default)
|
||||||
|
2. **Artifactory** - Your corporate Artifactory npm registry
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Switching Registries Locally
|
||||||
|
|
||||||
|
**On Linux/Mac:**
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Use public npm registry (default)
|
||||||
|
./switch-registry.sh public
|
||||||
|
npm ci --force
|
||||||
|
|
||||||
|
# Use Artifactory registry
|
||||||
|
./switch-registry.sh artifactory
|
||||||
|
# Set auth token if required
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_token_here"
|
||||||
|
npm ci --force
|
||||||
|
```
|
||||||
|
|
||||||
|
**On Windows:**
|
||||||
|
```powershell
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Use public npm registry (default)
|
||||||
|
.\switch-registry.ps1 public
|
||||||
|
npm ci --force
|
||||||
|
|
||||||
|
# Use Artifactory registry
|
||||||
|
.\switch-registry.ps1 artifactory
|
||||||
|
# Set auth token if required
|
||||||
|
$env:ARTIFACTORY_AUTH_TOKEN = "your_token_here"
|
||||||
|
npm ci --force
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building with Docker
|
||||||
|
|
||||||
|
**Using public npm registry (default):**
|
||||||
|
```bash
|
||||||
|
docker compose build app
|
||||||
|
```
|
||||||
|
|
||||||
|
**Using Artifactory registry:**
|
||||||
|
```bash
|
||||||
|
# Without authentication
|
||||||
|
docker compose build app --build-arg NPM_REGISTRY=artifactory
|
||||||
|
|
||||||
|
# With authentication
|
||||||
|
docker compose build app \
|
||||||
|
--build-arg NPM_REGISTRY=artifactory \
|
||||||
|
--build-arg ARTIFACTORY_AUTH_TOKEN="your_token_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
**On Windows PowerShell:**
|
||||||
|
```powershell
|
||||||
|
# With authentication
|
||||||
|
docker compose build app `
|
||||||
|
--build-arg NPM_REGISTRY=artifactory `
|
||||||
|
--build-arg ARTIFACTORY_AUTH_TOKEN="your_token_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Files
|
||||||
|
|
||||||
|
- **`.npmrc.public`** - Configuration for public npm registry
|
||||||
|
- **`.npmrc.artifactory`** - Configuration for Artifactory registry (edit this with your Artifactory URL)
|
||||||
|
- **`.npmrc`** - Active configuration (generated by switch-registry scripts)
|
||||||
|
|
||||||
|
## Setup Artifactory Configuration
|
||||||
|
|
||||||
|
1. Edit `frontend/.npmrc.artifactory` and replace `YOUR_ARTIFACTORY_URL` with your actual Artifactory URL:
|
||||||
|
```
|
||||||
|
registry=https://artifactory.yourcompany.com/artifactory/api/npm/npm-virtual/
|
||||||
|
```
|
||||||
|
|
||||||
|
2. If authentication is required, uncomment the auth lines and use one of these methods:
|
||||||
|
|
||||||
|
**Method 1: Auth Token (Recommended)**
|
||||||
|
```
|
||||||
|
//artifactory.yourcompany.com/artifactory/api/npm/npm-virtual/:_auth=${ARTIFACTORY_AUTH_TOKEN}
|
||||||
|
//artifactory.yourcompany.com/artifactory/api/npm/npm-virtual/:always-auth=true
|
||||||
|
```
|
||||||
|
|
||||||
|
Then set the environment variable:
|
||||||
|
```bash
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_base64_encoded_token"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Method 2: Username/Password**
|
||||||
|
```
|
||||||
|
//artifactory.yourcompany.com/artifactory/api/npm/npm-virtual/:username=${ARTIFACTORY_USERNAME}
|
||||||
|
//artifactory.yourcompany.com/artifactory/api/npm/npm-virtual/:_password=${ARTIFACTORY_PASSWORD}
|
||||||
|
//artifactory.yourcompany.com/artifactory/api/npm/npm-virtual/:email=your-email@company.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## Handling package-lock.json
|
||||||
|
|
||||||
|
The `package-lock.json` file will be different depending on which registry you use. Here are strategies to manage this:
|
||||||
|
|
||||||
|
### Strategy 1: Separate Lockfiles (Recommended)
|
||||||
|
Keep two lockfiles and switch between them:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# After switching to public and installing
|
||||||
|
npm ci --force
|
||||||
|
cp package-lock.json package-lock.public.json
|
||||||
|
|
||||||
|
# After switching to artifactory and installing
|
||||||
|
npm ci --force
|
||||||
|
cp package-lock.json package-lock.artifactory.json
|
||||||
|
|
||||||
|
# When switching registries in the future
|
||||||
|
cp package-lock.public.json package-lock.json # or
|
||||||
|
cp package-lock.artifactory.json package-lock.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Strategy 2: Regenerate Lockfile
|
||||||
|
Always regenerate the lockfile after switching:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./switch-registry.sh artifactory
|
||||||
|
rm package-lock.json
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Strategy 3: Git Ignore Lockfile (Not Recommended for Production)
|
||||||
|
If you're frequently switching and don't need deterministic builds:
|
||||||
|
|
||||||
|
Add to `.gitignore`:
|
||||||
|
```
|
||||||
|
frontend/package-lock.json
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warning:** This reduces build reproducibility.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Issue: "npm ci requires package-lock.json"
|
||||||
|
**Solution:** Delete `package-lock.json` and run `npm install` to generate a new one for your current registry.
|
||||||
|
|
||||||
|
### Issue: "404 Not Found - GET https://registry.npmjs.org/..."
|
||||||
|
**Solution:** Your .npmrc is pointing to Artifactory but packages don't exist there.
|
||||||
|
```bash
|
||||||
|
./switch-registry.sh public
|
||||||
|
npm ci --force
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "401 Unauthorized"
|
||||||
|
**Solution:** Check your authentication configuration in `.npmrc.artifactory` and ensure environment variables are set correctly.
|
||||||
|
|
||||||
|
### Issue: "ENOENT: no such file or directory, open '.npmrc.public'"
|
||||||
|
**Solution:** You're missing the registry config files. Make sure both `.npmrc.public` and `.npmrc.artifactory` exist in the frontend directory.
|
||||||
|
|
||||||
|
## CI/CD Integration
|
||||||
|
|
||||||
|
For CI/CD pipelines, use environment variables to select the registry:
|
||||||
|
|
||||||
|
**GitHub Actions Example:**
|
||||||
|
```yaml
|
||||||
|
- name: Build with Artifactory
|
||||||
|
env:
|
||||||
|
NPM_REGISTRY: artifactory
|
||||||
|
ARTIFACTORY_AUTH_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }}
|
||||||
|
run: |
|
||||||
|
docker compose build app \
|
||||||
|
--build-arg NPM_REGISTRY=artifactory \
|
||||||
|
--build-arg ARTIFACTORY_AUTH_TOKEN="${ARTIFACTORY_AUTH_TOKEN}"
|
||||||
|
```
|
||||||
|
|
||||||
|
**GitLab CI Example:**
|
||||||
|
```yaml
|
||||||
|
build:
|
||||||
|
script:
|
||||||
|
- docker compose build app
|
||||||
|
--build-arg NPM_REGISTRY=artifactory
|
||||||
|
--build-arg ARTIFACTORY_AUTH_TOKEN="${ARTIFACTORY_AUTH_TOKEN}"
|
||||||
|
variables:
|
||||||
|
NPM_REGISTRY: artifactory
|
||||||
|
ARTIFACTORY_AUTH_TOKEN: ${CI_ARTIFACTORY_TOKEN}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Never commit credentials** - Use environment variables for tokens/passwords
|
||||||
|
2. **Document your Artifactory URL** - Update `.npmrc.artifactory` with your team's URL
|
||||||
|
3. **Keep both config files** - Commit `.npmrc.public` and `.npmrc.artifactory` to git
|
||||||
|
4. **Use the scripts** - Always use `switch-registry.sh/ps1` instead of manually editing `.npmrc`
|
||||||
|
5. **Clean installs** - Use `npm ci --force` after switching to ensure a clean dependency tree
|
||||||
339
frontend/REGISTRY-EXAMPLES.md
Normal file
339
frontend/REGISTRY-EXAMPLES.md
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
# NPM Registry - Usage Examples
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
### Use Public NPM (Default)
|
||||||
|
```bash
|
||||||
|
# Linux/Mac
|
||||||
|
./quickstart.sh
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
.\quickstart.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Use Artifactory
|
||||||
|
```bash
|
||||||
|
# Linux/Mac
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_token_here"
|
||||||
|
./quickstart.sh -bsf
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
$env:ARTIFACTORY_AUTH_TOKEN = "your_token_here"
|
||||||
|
.\quickstart.ps1 -Bsf
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rebuild with Artifactory
|
||||||
|
```bash
|
||||||
|
# Linux/Mac
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_token_here"
|
||||||
|
./quickstart.sh --rebuild -bsf
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
$env:ARTIFACTORY_AUTH_TOKEN = "your_token_here"
|
||||||
|
.\quickstart.ps1 -Rebuild -Bsf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Local Development (Without Docker)
|
||||||
|
|
||||||
|
### Switch Registry for Local Development
|
||||||
|
|
||||||
|
**Linux/Mac:**
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Switch to public npm
|
||||||
|
./switch-registry.sh public
|
||||||
|
npm ci --force
|
||||||
|
npm start
|
||||||
|
|
||||||
|
# Switch to Artifactory
|
||||||
|
./switch-registry.sh artifactory
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_token"
|
||||||
|
npm ci --force
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
```powershell
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Switch to public npm
|
||||||
|
.\switch-registry.ps1 public
|
||||||
|
npm ci --force
|
||||||
|
npm start
|
||||||
|
|
||||||
|
# Switch to Artifactory
|
||||||
|
.\switch-registry.ps1 artifactory
|
||||||
|
$env:ARTIFACTORY_AUTH_TOKEN = "your_token"
|
||||||
|
npm ci --force
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
**Using NPM Scripts (Cross-platform):**
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Switch to public npm
|
||||||
|
npm run registry:public
|
||||||
|
npm ci --force
|
||||||
|
npm start
|
||||||
|
|
||||||
|
# Switch to Artifactory
|
||||||
|
npm run registry:artifactory
|
||||||
|
npm ci --force
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Build Examples
|
||||||
|
|
||||||
|
### Build Specific Service with Registry
|
||||||
|
|
||||||
|
**Public NPM:**
|
||||||
|
```bash
|
||||||
|
docker compose build app
|
||||||
|
```
|
||||||
|
|
||||||
|
**Artifactory:**
|
||||||
|
```bash
|
||||||
|
# Without auth
|
||||||
|
docker compose build app --build-arg NPM_REGISTRY=artifactory
|
||||||
|
|
||||||
|
# With auth
|
||||||
|
docker compose build app \
|
||||||
|
--build-arg NPM_REGISTRY=artifactory \
|
||||||
|
--build-arg ARTIFACTORY_AUTH_TOKEN="your_token"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows PowerShell:**
|
||||||
|
```powershell
|
||||||
|
docker compose build app `
|
||||||
|
--build-arg NPM_REGISTRY=artifactory `
|
||||||
|
--build-arg ARTIFACTORY_AUTH_TOKEN="your_token"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Workflows
|
||||||
|
|
||||||
|
### Corporate Network Development
|
||||||
|
When working from a corporate network that requires Artifactory:
|
||||||
|
|
||||||
|
1. **First time setup:**
|
||||||
|
```bash
|
||||||
|
# Edit .npmrc.artifactory with your Artifactory URL
|
||||||
|
nano frontend/.npmrc.artifactory
|
||||||
|
|
||||||
|
# Set auth token (get from your Artifactory admin)
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_base64_token"
|
||||||
|
|
||||||
|
# Start with Artifactory
|
||||||
|
./quickstart.sh -bsf
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Daily development:**
|
||||||
|
```bash
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_token"
|
||||||
|
./quickstart.sh -bsf
|
||||||
|
```
|
||||||
|
|
||||||
|
### Home/Public Network Development
|
||||||
|
When working from home or a network with npm access:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Just run without -bsf flag
|
||||||
|
./quickstart.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Switching Between Environments
|
||||||
|
|
||||||
|
**Moving from Corporate to Home:**
|
||||||
|
```bash
|
||||||
|
# Stop existing containers
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Rebuild with public npm
|
||||||
|
./quickstart.sh --rebuild
|
||||||
|
```
|
||||||
|
|
||||||
|
**Moving from Home to Corporate:**
|
||||||
|
```bash
|
||||||
|
# Stop existing containers
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Rebuild with Artifactory
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_token"
|
||||||
|
./quickstart.sh --rebuild -bsf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Handling Multiple package-lock.json Files
|
||||||
|
|
||||||
|
### Save lockfiles for both registries:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Generate public lockfile
|
||||||
|
./switch-registry.sh public
|
||||||
|
rm package-lock.json
|
||||||
|
npm install
|
||||||
|
cp package-lock.json package-lock.public.json
|
||||||
|
|
||||||
|
# Generate artifactory lockfile
|
||||||
|
./switch-registry.sh artifactory
|
||||||
|
rm package-lock.json
|
||||||
|
npm install
|
||||||
|
cp package-lock.json package-lock.artifactory.json
|
||||||
|
|
||||||
|
# Add to git
|
||||||
|
git add package-lock.public.json package-lock.artifactory.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Use the appropriate lockfile:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# When using public npm
|
||||||
|
cp package-lock.public.json package-lock.json
|
||||||
|
npm ci
|
||||||
|
|
||||||
|
# When using Artifactory
|
||||||
|
cp package-lock.artifactory.json package-lock.json
|
||||||
|
npm ci
|
||||||
|
```
|
||||||
|
|
||||||
|
## CI/CD Examples
|
||||||
|
|
||||||
|
### GitHub Actions
|
||||||
|
|
||||||
|
**.github/workflows/build.yml**
|
||||||
|
```yaml
|
||||||
|
name: Build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-public:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Build with public npm
|
||||||
|
run: |
|
||||||
|
docker compose build app
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
build-artifactory:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Build with Artifactory
|
||||||
|
env:
|
||||||
|
ARTIFACTORY_AUTH_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }}
|
||||||
|
run: |
|
||||||
|
./quickstart.sh -bsf
|
||||||
|
```
|
||||||
|
|
||||||
|
### GitLab CI
|
||||||
|
|
||||||
|
**.gitlab-ci.yml**
|
||||||
|
```yaml
|
||||||
|
variables:
|
||||||
|
NPM_REGISTRY: "public"
|
||||||
|
|
||||||
|
build:public:
|
||||||
|
stage: build
|
||||||
|
script:
|
||||||
|
- docker compose build app
|
||||||
|
- docker compose up -d
|
||||||
|
only:
|
||||||
|
- main
|
||||||
|
|
||||||
|
build:artifactory:
|
||||||
|
stage: build
|
||||||
|
variables:
|
||||||
|
NPM_REGISTRY: "artifactory"
|
||||||
|
script:
|
||||||
|
- export ARTIFACTORY_AUTH_TOKEN="${CI_ARTIFACTORY_TOKEN}"
|
||||||
|
- ./quickstart.sh -bsf
|
||||||
|
only:
|
||||||
|
- develop
|
||||||
|
```
|
||||||
|
|
||||||
|
### Jenkins Pipeline
|
||||||
|
|
||||||
|
**Jenkinsfile**
|
||||||
|
```groovy
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
environment {
|
||||||
|
ARTIFACTORY_AUTH_TOKEN = credentials('artifactory-npm-token')
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Build with Artifactory') {
|
||||||
|
steps {
|
||||||
|
sh './quickstart.sh -bsf'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Build fails with "Cannot find .npmrc.public"
|
||||||
|
|
||||||
|
**Problem:** Registry config files are missing.
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
# Verify files exist
|
||||||
|
ls -la .npmrc.*
|
||||||
|
|
||||||
|
# If missing, they should be committed to git
|
||||||
|
git status
|
||||||
|
```
|
||||||
|
|
||||||
|
### "ENOENT: no such file or directory, open '/frontend/dist/frontend/browser'"
|
||||||
|
|
||||||
|
**Problem:** Frontend build failed due to registry issues.
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Check build logs
|
||||||
|
docker compose logs app | grep npm
|
||||||
|
|
||||||
|
# Try rebuilding with verbose logging
|
||||||
|
docker compose build app --no-cache --progress=plain
|
||||||
|
```
|
||||||
|
|
||||||
|
### npm ci fails with 404 errors
|
||||||
|
|
||||||
|
**Problem:** Wrong registry is configured.
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
cat .npmrc # Check which registry is active
|
||||||
|
|
||||||
|
# If using wrong one, switch:
|
||||||
|
npm run registry:public # or registry:artifactory
|
||||||
|
npm ci --force
|
||||||
|
```
|
||||||
|
|
||||||
|
### Authentication fails with Artifactory
|
||||||
|
|
||||||
|
**Problem:** Token is invalid or not set.
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Check token is set
|
||||||
|
echo $ARTIFACTORY_AUTH_TOKEN # Linux/Mac
|
||||||
|
echo $env:ARTIFACTORY_AUTH_TOKEN # Windows
|
||||||
|
|
||||||
|
# Get new token from Artifactory UI:
|
||||||
|
# Artifactory -> User Profile -> Generate Token
|
||||||
|
|
||||||
|
# Set the token
|
||||||
|
export ARTIFACTORY_AUTH_TOKEN="your_new_token"
|
||||||
|
```
|
||||||
@@ -6,7 +6,9 @@
|
|||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"build": "ng build",
|
"build": "ng build",
|
||||||
"watch": "ng build --watch --configuration development",
|
"watch": "ng build --watch --configuration development",
|
||||||
"test": "ng test"
|
"test": "ng test",
|
||||||
|
"registry:public": "node -e \"require('fs').copyFileSync('.npmrc.public', '.npmrc'); console.log('✓ Switched to public npm registry');\"",
|
||||||
|
"registry:artifactory": "node -e \"require('fs').copyFileSync('.npmrc.artifactory', '.npmrc'); console.log('✓ Switched to Artifactory registry');\""
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
34
frontend/switch-registry.ps1
Normal file
34
frontend/switch-registry.ps1
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Position=0)]
|
||||||
|
[ValidateSet("public", "artifactory")]
|
||||||
|
[string]$RegistryType = "public"
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
switch ($RegistryType) {
|
||||||
|
"public" {
|
||||||
|
Write-Host "Switching to public npm registry..." -ForegroundColor Yellow
|
||||||
|
Copy-Item ".npmrc.public" ".npmrc" -Force
|
||||||
|
Write-Host "[OK] Now using registry.npmjs.org" -ForegroundColor Green
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "To install dependencies:" -ForegroundColor White
|
||||||
|
Write-Host " npm ci --force" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
"artifactory" {
|
||||||
|
Write-Host "Switching to Artifactory registry..." -ForegroundColor Yellow
|
||||||
|
Copy-Item ".npmrc.artifactory" ".npmrc" -Force
|
||||||
|
Write-Host "[OK] Now using Artifactory registry" -ForegroundColor Green
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Make sure to set environment variables if authentication is required:" -ForegroundColor White
|
||||||
|
Write-Host ' $env:ARTIFACTORY_AUTH_TOKEN = "your_token"' -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "To install dependencies:" -ForegroundColor White
|
||||||
|
Write-Host " npm ci --force" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Current .npmrc contents:" -ForegroundColor White
|
||||||
|
Get-Content ".npmrc"
|
||||||
42
frontend/switch-registry.sh
Normal file
42
frontend/switch-registry.sh
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script to switch between npm registries
|
||||||
|
# Usage: ./switch-registry.sh [public|artifactory]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
REGISTRY_TYPE=${1:-public}
|
||||||
|
|
||||||
|
case $REGISTRY_TYPE in
|
||||||
|
public)
|
||||||
|
echo "Switching to public npm registry..."
|
||||||
|
cp .npmrc.public .npmrc
|
||||||
|
echo "✓ Now using registry.npmjs.org"
|
||||||
|
echo ""
|
||||||
|
echo "To install dependencies:"
|
||||||
|
echo " npm ci --force"
|
||||||
|
;;
|
||||||
|
artifactory)
|
||||||
|
echo "Switching to Artifactory registry..."
|
||||||
|
cp .npmrc.artifactory .npmrc
|
||||||
|
echo "✓ Now using Artifactory registry"
|
||||||
|
echo ""
|
||||||
|
echo "Make sure to set environment variables if authentication is required:"
|
||||||
|
echo " export ARTIFACTORY_AUTH_TOKEN=your_token"
|
||||||
|
echo ""
|
||||||
|
echo "To install dependencies:"
|
||||||
|
echo " npm ci --force"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 [public|artifactory]"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " public - Use registry.npmjs.org (default)"
|
||||||
|
echo " artifactory - Use Artifactory npm registry"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Current .npmrc contents:"
|
||||||
|
cat .npmrc
|
||||||
145
quickstart.ps1
145
quickstart.ps1
@@ -1,8 +1,7 @@
|
|||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
[switch]$Rebuild,
|
[switch]$Rebuild,
|
||||||
[switch]$FullStack,
|
[switch]$Bsf,
|
||||||
[switch]$Dev,
|
|
||||||
[switch]$Help
|
[switch]$Help
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -10,27 +9,52 @@ $ErrorActionPreference = "Stop"
|
|||||||
|
|
||||||
if ($Help) {
|
if ($Help) {
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
Write-Host "Test Artifact Data Lake - Quick Start" -ForegroundColor Cyan
|
Write-Host "Obsidian - Quick Start" -ForegroundColor Cyan
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "Usage: .\quickstart.ps1 [OPTIONS]" -ForegroundColor White
|
Write-Host "Usage: .\quickstart.ps1 [OPTIONS]" -ForegroundColor White
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "Options:" -ForegroundColor Yellow
|
Write-Host "Options:" -ForegroundColor Yellow
|
||||||
Write-Host " -Rebuild Force rebuild of all containers" -ForegroundColor White
|
Write-Host " -Rebuild Force rebuild of all containers" -ForegroundColor White
|
||||||
Write-Host " -FullStack Start complete stack including frontend (production build)" -ForegroundColor White
|
Write-Host " -Bsf Use Artifactory npm registry instead of public npm" -ForegroundColor White
|
||||||
Write-Host " -Dev Start backend only, use separate dev server for frontend" -ForegroundColor White
|
|
||||||
Write-Host " -Help Show this help message" -ForegroundColor White
|
Write-Host " -Help Show this help message" -ForegroundColor White
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "Default: Starts backend services only (recommended for development)" -ForegroundColor Green
|
Write-Host "Environment Variables (when using -Bsf):" -ForegroundColor Yellow
|
||||||
|
Write-Host ' $env:ARTIFACTORY_AUTH_TOKEN Authentication token for Artifactory' -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Brings up the complete stack: database, backend API, and frontend" -ForegroundColor Green
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
Write-Host "Test Artifact Data Lake - Quick Start" -ForegroundColor Cyan
|
Write-Host "Obsidian - Quick Start" -ForegroundColor Cyan
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
|
||||||
|
# Determine npm registry and build arguments
|
||||||
|
$NpmRegistry = "public"
|
||||||
|
$BuildArgs = @()
|
||||||
|
|
||||||
|
if ($Bsf) {
|
||||||
|
$NpmRegistry = "artifactory"
|
||||||
|
$BuildArgs += "--build-arg"
|
||||||
|
$BuildArgs += "NPM_REGISTRY=artifactory"
|
||||||
|
|
||||||
|
Write-Host "Using Artifactory npm registry" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
if ($env:ARTIFACTORY_AUTH_TOKEN) {
|
||||||
|
Write-Host "[OK] Artifactory auth token detected" -ForegroundColor Green
|
||||||
|
$BuildArgs += "--build-arg"
|
||||||
|
$BuildArgs += "ARTIFACTORY_AUTH_TOKEN=$env:ARTIFACTORY_AUTH_TOKEN"
|
||||||
|
} else {
|
||||||
|
Write-Host "[WARNING] ARTIFACTORY_AUTH_TOKEN not set (may be required for authentication)" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "Using public npm registry (registry.npmjs.org)" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
# Check if Docker is installed
|
# Check if Docker is installed
|
||||||
if (-not (Get-Command "docker" -ErrorAction SilentlyContinue)) {
|
if (-not (Get-Command "docker" -ErrorAction SilentlyContinue)) {
|
||||||
Write-Host "Error: Docker is not installed. Please install Docker Desktop first." -ForegroundColor Red
|
Write-Host "Error: Docker is not installed. Please install Docker Desktop first." -ForegroundColor Red
|
||||||
@@ -72,48 +96,42 @@ if ($Rebuild) {
|
|||||||
Write-Host "Rebuilding containers..." -ForegroundColor Yellow
|
Write-Host "Rebuilding containers..." -ForegroundColor Yellow
|
||||||
Write-Host "Stopping existing containers..." -ForegroundColor White
|
Write-Host "Stopping existing containers..." -ForegroundColor White
|
||||||
|
|
||||||
if ($FullStack) {
|
if ($ComposeCmd -eq "docker compose") {
|
||||||
if ($ComposeCmd -eq "docker compose") {
|
& docker compose down
|
||||||
& docker compose -f "docker-compose.production.yml" down
|
Write-Host "Removing existing images for rebuild..." -ForegroundColor White
|
||||||
Write-Host "Removing existing images for full rebuild..." -ForegroundColor White
|
& docker compose down --rmi local
|
||||||
& docker compose -f "docker-compose.production.yml" down --rmi local 2>$null
|
Write-Host "Building and starting all services..." -ForegroundColor White
|
||||||
Write-Host "Building and starting full stack..." -ForegroundColor White
|
if ($BuildArgs.Count -gt 0) {
|
||||||
& docker compose -f "docker-compose.production.yml" up -d --build
|
& docker compose build $BuildArgs
|
||||||
|
& docker compose up -d
|
||||||
} else {
|
} else {
|
||||||
& docker-compose -f "docker-compose.production.yml" down
|
& docker compose up -d --build
|
||||||
Write-Host "Removing existing images for full rebuild..." -ForegroundColor White
|
|
||||||
& docker-compose -f "docker-compose.production.yml" down --rmi local 2>$null
|
|
||||||
Write-Host "Building and starting full stack..." -ForegroundColor White
|
|
||||||
& docker-compose -f "docker-compose.production.yml" up -d --build
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ($ComposeCmd -eq "docker compose") {
|
& docker-compose down
|
||||||
& docker compose down
|
Write-Host "Removing existing images for rebuild..." -ForegroundColor White
|
||||||
Write-Host "Removing existing backend images for rebuild..." -ForegroundColor White
|
& docker-compose down --rmi local
|
||||||
& docker compose down --rmi local 2>$null
|
Write-Host "Building and starting all services..." -ForegroundColor White
|
||||||
Write-Host "Building and starting backend services..." -ForegroundColor White
|
if ($BuildArgs.Count -gt 0) {
|
||||||
& docker compose up -d --build
|
& docker-compose build $BuildArgs
|
||||||
|
& docker-compose up -d
|
||||||
} else {
|
} else {
|
||||||
& docker-compose down
|
|
||||||
Write-Host "Removing existing backend images for rebuild..." -ForegroundColor White
|
|
||||||
& docker-compose down --rmi local 2>$null
|
|
||||||
Write-Host "Building and starting backend services..." -ForegroundColor White
|
|
||||||
& docker-compose up -d --build
|
& docker-compose up -d --build
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
# Regular startup
|
Write-Host "Starting all services..." -ForegroundColor Green
|
||||||
if ($FullStack) {
|
if ($ComposeCmd -eq "docker compose") {
|
||||||
Write-Host "Starting full production stack (backend + frontend)..." -ForegroundColor Green
|
if ($BuildArgs.Count -gt 0) {
|
||||||
if ($ComposeCmd -eq "docker compose") {
|
& docker compose build $BuildArgs
|
||||||
& docker compose -f "docker-compose.production.yml" up -d
|
& docker compose up -d
|
||||||
} else {
|
} else {
|
||||||
& docker-compose -f "docker-compose.production.yml" up -d
|
& docker compose up -d
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Write-Host "Starting backend services..." -ForegroundColor Green
|
if ($BuildArgs.Count -gt 0) {
|
||||||
if ($ComposeCmd -eq "docker compose") {
|
& docker-compose build $BuildArgs
|
||||||
& docker compose up -d
|
& docker-compose up -d
|
||||||
} else {
|
} else {
|
||||||
& docker-compose up -d
|
& docker-compose up -d
|
||||||
}
|
}
|
||||||
@@ -122,54 +140,21 @@ if ($Rebuild) {
|
|||||||
|
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "Waiting for services to be ready..." -ForegroundColor Yellow
|
Write-Host "Waiting for services to be ready..." -ForegroundColor Yellow
|
||||||
Start-Sleep -Seconds 15
|
Start-Sleep -Seconds 20
|
||||||
|
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
if ($FullStack) {
|
Write-Host "Complete Stack is running!" -ForegroundColor Green
|
||||||
Write-Host "Complete Stack is running!" -ForegroundColor Green
|
|
||||||
} else {
|
|
||||||
Write-Host "Backend Services are running!" -ForegroundColor Green
|
|
||||||
}
|
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "API: http://localhost:8000" -ForegroundColor White
|
Write-Host "Application: http://localhost:8000" -ForegroundColor White
|
||||||
Write-Host "API Docs: http://localhost:8000/docs" -ForegroundColor White
|
Write-Host "API Docs: http://localhost:8000/docs" -ForegroundColor White
|
||||||
Write-Host "MinIO Console: http://localhost:9001" -ForegroundColor White
|
Write-Host "MinIO Console: http://localhost:9001" -ForegroundColor White
|
||||||
Write-Host " Username: minioadmin" -ForegroundColor Gray
|
Write-Host " Username: minioadmin" -ForegroundColor Gray
|
||||||
Write-Host " Password: minioadmin" -ForegroundColor Gray
|
Write-Host " Password: minioadmin" -ForegroundColor Gray
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
Write-Host "To view logs: $ComposeCmd logs -f" -ForegroundColor Yellow
|
||||||
if ($FullStack) {
|
Write-Host "To stop: $ComposeCmd down" -ForegroundColor Yellow
|
||||||
Write-Host "Frontend: http://localhost:80" -ForegroundColor White
|
|
||||||
Write-Host " (Production build with Nginx)" -ForegroundColor Gray
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "To view logs: $ComposeCmd -f docker-compose.production.yml logs -f" -ForegroundColor Yellow
|
|
||||||
Write-Host "To stop: $ComposeCmd -f docker-compose.production.yml down" -ForegroundColor Yellow
|
|
||||||
} else {
|
|
||||||
Write-Host "To view logs: $ComposeCmd logs -f" -ForegroundColor Yellow
|
|
||||||
Write-Host "To stop: $ComposeCmd down" -ForegroundColor Yellow
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host "Frontend Options:" -ForegroundColor Cyan
|
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "Development (with hot reload):" -ForegroundColor White
|
|
||||||
Write-Host " .\dev-start.ps1" -ForegroundColor Green
|
|
||||||
Write-Host " Frontend will be available at: http://localhost:4200" -ForegroundColor Gray
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "Or start full production stack:" -ForegroundColor White
|
|
||||||
Write-Host " .\quickstart.ps1 -FullStack" -ForegroundColor Green
|
|
||||||
Write-Host " Complete stack at: http://localhost:80" -ForegroundColor Gray
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host "Rebuild Options:" -ForegroundColor Cyan
|
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "Force rebuild backend: .\quickstart.ps1 -Rebuild" -ForegroundColor Yellow
|
|
||||||
Write-Host "Force rebuild full stack: .\quickstart.ps1 -Rebuild -FullStack" -ForegroundColor Yellow
|
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
Write-Host "Testing the API..." -ForegroundColor Cyan
|
Write-Host "Testing the API..." -ForegroundColor Cyan
|
||||||
@@ -185,11 +170,8 @@ try {
|
|||||||
if ($response.status -eq "healthy") {
|
if ($response.status -eq "healthy") {
|
||||||
Write-Host "[OK] API is healthy!" -ForegroundColor Green
|
Write-Host "[OK] API is healthy!" -ForegroundColor Green
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
if (-not $FullStack) {
|
Write-Host "All services are ready!" -ForegroundColor Green
|
||||||
Write-Host "Ready for development!" -ForegroundColor Green
|
Write-Host ""
|
||||||
Write-Host "Run '.\dev-start.ps1' to start the frontend with hot reload" -ForegroundColor Yellow
|
|
||||||
Write-Host ""
|
|
||||||
}
|
|
||||||
Write-Host "Example: Upload a test file" -ForegroundColor White
|
Write-Host "Example: Upload a test file" -ForegroundColor White
|
||||||
Write-Host "----------------------------" -ForegroundColor Gray
|
Write-Host "----------------------------" -ForegroundColor Gray
|
||||||
Write-Host 'echo "test,data" > test.csv' -ForegroundColor Green
|
Write-Host 'echo "test,data" > test.csv' -ForegroundColor Green
|
||||||
@@ -210,4 +192,5 @@ catch {
|
|||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
Write-Host "Setup complete!" -ForegroundColor Green
|
Write-Host "Setup complete!" -ForegroundColor Green
|
||||||
|
Write-Host "Open http://localhost:8000 in your browser" -ForegroundColor Yellow
|
||||||
Write-Host "=========================================" -ForegroundColor Cyan
|
Write-Host "=========================================" -ForegroundColor Cyan
|
||||||
114
quickstart.sh
114
quickstart.sh
@@ -3,7 +3,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
echo "Test Artifact Data Lake - Quick Start"
|
echo "Obsidian - Quick Start"
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -26,8 +26,9 @@ fi
|
|||||||
|
|
||||||
# Parse command line arguments
|
# Parse command line arguments
|
||||||
REBUILD=false
|
REBUILD=false
|
||||||
FULL_STACK=false
|
USE_ARTIFACTORY=false
|
||||||
DEV_MODE=false
|
NPM_REGISTRY="public"
|
||||||
|
BUILD_ARGS=""
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
@@ -35,12 +36,10 @@ while [[ $# -gt 0 ]]; do
|
|||||||
REBUILD=true
|
REBUILD=true
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--full-stack)
|
-bsf)
|
||||||
FULL_STACK=true
|
USE_ARTIFACTORY=true
|
||||||
shift
|
NPM_REGISTRY="artifactory"
|
||||||
;;
|
BUILD_ARGS="--build-arg NPM_REGISTRY=artifactory"
|
||||||
--dev)
|
|
||||||
DEV_MODE=true
|
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--help)
|
--help)
|
||||||
@@ -48,11 +47,13 @@ while [[ $# -gt 0 ]]; do
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " --rebuild Force rebuild of all containers"
|
echo " --rebuild Force rebuild of all containers"
|
||||||
echo " --full-stack Start complete stack including frontend (production build)"
|
echo " -bsf Use Artifactory npm registry instead of public npm"
|
||||||
echo " --dev Start backend only, use separate dev server for frontend"
|
|
||||||
echo " --help Show this help message"
|
echo " --help Show this help message"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Default: Starts backend services only (recommended for development)"
|
echo "Environment Variables (when using -bsf):"
|
||||||
|
echo " ARTIFACTORY_AUTH_TOKEN Authentication token for Artifactory"
|
||||||
|
echo ""
|
||||||
|
echo "Brings up the complete stack: database, backend API, and frontend"
|
||||||
echo ""
|
echo ""
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
@@ -64,6 +65,20 @@ while [[ $# -gt 0 ]]; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# If using Artifactory, add auth token to build args if available
|
||||||
|
if [ "$USE_ARTIFACTORY" = true ]; then
|
||||||
|
echo "Using Artifactory npm registry"
|
||||||
|
if [ -n "$ARTIFACTORY_AUTH_TOKEN" ]; then
|
||||||
|
echo "✓ Artifactory auth token detected"
|
||||||
|
BUILD_ARGS="$BUILD_ARGS --build-arg ARTIFACTORY_AUTH_TOKEN=$ARTIFACTORY_AUTH_TOKEN"
|
||||||
|
else
|
||||||
|
echo "⚠ Warning: ARTIFACTORY_AUTH_TOKEN not set (may be required for authentication)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Using public npm registry (registry.npmjs.org)"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Create .env file if it doesn't exist
|
# Create .env file if it doesn't exist
|
||||||
if [ ! -f .env ]; then
|
if [ ! -f .env ]; then
|
||||||
echo "Creating .env file from .env.example..."
|
echo "Creating .env file from .env.example..."
|
||||||
@@ -80,79 +95,42 @@ if [ "$REBUILD" = true ]; then
|
|||||||
echo "🔄 Rebuilding containers..."
|
echo "🔄 Rebuilding containers..."
|
||||||
echo "Stopping existing containers..."
|
echo "Stopping existing containers..."
|
||||||
$COMPOSE_CMD down
|
$COMPOSE_CMD down
|
||||||
|
echo "Removing existing images for rebuild..."
|
||||||
if [ "$FULL_STACK" = true ]; then
|
$COMPOSE_CMD down --rmi local 2>/dev/null || true
|
||||||
echo "Removing existing images for full rebuild..."
|
echo "Building and starting all services..."
|
||||||
$COMPOSE_CMD -f docker-compose.production.yml down --rmi local 2>/dev/null || true
|
if [ -n "$BUILD_ARGS" ]; then
|
||||||
echo "Building and starting full stack..."
|
$COMPOSE_CMD build $BUILD_ARGS
|
||||||
$COMPOSE_CMD -f docker-compose.production.yml up -d --build
|
$COMPOSE_CMD up -d
|
||||||
else
|
else
|
||||||
echo "Removing existing backend images for rebuild..."
|
|
||||||
$COMPOSE_CMD down --rmi local 2>/dev/null || true
|
|
||||||
echo "Building and starting backend services..."
|
|
||||||
$COMPOSE_CMD up -d --build
|
$COMPOSE_CMD up -d --build
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Regular startup
|
echo "Starting all services..."
|
||||||
if [ "$FULL_STACK" = true ]; then
|
if [ -n "$BUILD_ARGS" ]; then
|
||||||
echo "Starting full production stack (backend + frontend)..."
|
$COMPOSE_CMD build $BUILD_ARGS
|
||||||
$COMPOSE_CMD -f docker-compose.production.yml up -d
|
$COMPOSE_CMD up -d
|
||||||
else
|
else
|
||||||
echo "Starting backend services..."
|
|
||||||
$COMPOSE_CMD up -d
|
$COMPOSE_CMD up -d
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Waiting for services to be ready..."
|
echo "Waiting for services to be ready..."
|
||||||
sleep 15
|
sleep 20
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
if [ "$FULL_STACK" = true ]; then
|
echo "Complete Stack is running! 🚀"
|
||||||
echo "Complete Stack is running! 🚀"
|
|
||||||
else
|
|
||||||
echo "Backend Services are running!"
|
|
||||||
fi
|
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
echo ""
|
echo ""
|
||||||
echo "API: http://localhost:8000"
|
echo "Application: http://localhost:8000"
|
||||||
echo "API Docs: http://localhost:8000/docs"
|
echo "API Docs: http://localhost:8000/docs"
|
||||||
echo "MinIO Console: http://localhost:9001"
|
echo "MinIO Console: http://localhost:9001"
|
||||||
echo " Username: minioadmin"
|
echo " Username: minioadmin"
|
||||||
echo " Password: minioadmin"
|
echo " Password: minioadmin"
|
||||||
echo ""
|
echo ""
|
||||||
|
echo "To view logs: $COMPOSE_CMD logs -f"
|
||||||
if [ "$FULL_STACK" = true ]; then
|
echo "To stop: $COMPOSE_CMD down"
|
||||||
echo "Frontend: http://localhost:80"
|
|
||||||
echo " (Production build with Nginx)"
|
|
||||||
echo ""
|
|
||||||
echo "To view logs: $COMPOSE_CMD -f docker-compose.production.yml logs -f"
|
|
||||||
echo "To stop: $COMPOSE_CMD -f docker-compose.production.yml down"
|
|
||||||
else
|
|
||||||
echo "To view logs: $COMPOSE_CMD logs -f"
|
|
||||||
echo "To stop: $COMPOSE_CMD down"
|
|
||||||
echo ""
|
|
||||||
echo "========================================="
|
|
||||||
echo "Frontend Options:"
|
|
||||||
echo "========================================="
|
|
||||||
echo ""
|
|
||||||
echo "Development (with hot reload):"
|
|
||||||
echo " ./dev-start.sh"
|
|
||||||
echo " Frontend will be available at: http://localhost:4200"
|
|
||||||
echo ""
|
|
||||||
echo "Or start full production stack:"
|
|
||||||
echo " ./quickstart.sh --full-stack"
|
|
||||||
echo " Complete stack at: http://localhost:80"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "========================================="
|
|
||||||
echo "Rebuild Options:"
|
|
||||||
echo "========================================="
|
|
||||||
echo ""
|
|
||||||
echo "Force rebuild backend: ./quickstart.sh --rebuild"
|
|
||||||
echo "Force rebuild full stack: ./quickstart.sh --rebuild --full-stack"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
echo "Testing the API..."
|
echo "Testing the API..."
|
||||||
@@ -166,11 +144,8 @@ sleep 5
|
|||||||
if curl -s http://localhost:8000/health | grep -q "healthy"; then
|
if curl -s http://localhost:8000/health | grep -q "healthy"; then
|
||||||
echo "✓ API is healthy!"
|
echo "✓ API is healthy!"
|
||||||
echo ""
|
echo ""
|
||||||
if [ "$FULL_STACK" = false ]; then
|
echo "🎯 All services are ready!"
|
||||||
echo "🎯 Ready for development!"
|
echo ""
|
||||||
echo "Run './dev-start.sh' to start the frontend with hot reload"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
echo "Example: Upload a test file"
|
echo "Example: Upload a test file"
|
||||||
echo "----------------------------"
|
echo "----------------------------"
|
||||||
echo 'echo "test,data" > test.csv'
|
echo 'echo "test,data" > test.csv'
|
||||||
@@ -186,4 +161,5 @@ fi
|
|||||||
|
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
echo "Setup complete! 🚀"
|
echo "Setup complete! 🚀"
|
||||||
|
echo "Open http://localhost:8000 in your browser"
|
||||||
echo "========================================="
|
echo "========================================="
|
||||||
|
|||||||
Reference in New Issue
Block a user