Initial commit: Complete NodeJS-native setup
- Migrated from Python pre-commit to NodeJS-native solution - Reorganized documentation structure - Set up Husky + lint-staged for efficient pre-commit hooks - Fixed Dockerfile healthcheck issue - Added comprehensive documentation index
This commit is contained in:
78
docker/.dockerignore
Normal file
78
docker/.dockerignore
Normal file
@@ -0,0 +1,78 @@
|
||||
# Dependencies
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Build output
|
||||
dist
|
||||
build
|
||||
|
||||
# Environment files (security)
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Development files
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# Version control
|
||||
.git
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
README_*.md
|
||||
CHANGELOG.md
|
||||
CONTRIBUTING.md
|
||||
LICENSE
|
||||
docs/
|
||||
|
||||
# Docker files (avoid recursion)
|
||||
Dockerfile
|
||||
docker-compose.yaml
|
||||
.dockerignore
|
||||
|
||||
# Scripts and testing (not needed in container)
|
||||
scripts/
|
||||
tests/
|
||||
coverage/
|
||||
**/__tests__
|
||||
**/*.test.*
|
||||
**/*.spec.*
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
.tmp
|
||||
|
||||
# CouchDB data
|
||||
couchdb-data/
|
||||
|
||||
# Scripts (not needed in container)
|
||||
setup.sh
|
||||
deploy.sh
|
||||
deploy-k8s.sh
|
||||
validate-env.sh
|
||||
validate-deployment.sh
|
||||
|
||||
# Kubernetes manifests
|
||||
k8s/
|
||||
81
docker/Dockerfile
Normal file
81
docker/Dockerfile
Normal file
@@ -0,0 +1,81 @@
|
||||
# check=skip=SecretsUsedInArgOrEnv
|
||||
# Build stage
|
||||
FROM oven/bun:alpine AS builder
|
||||
|
||||
# Install system dependencies for native modules
|
||||
RUN apk add --no-cache python3 make g++
|
||||
|
||||
# Create non-root user for security
|
||||
RUN addgroup -g 1001 -S nodeuser && adduser -S nodeuser -u 1001 -G nodeuser
|
||||
|
||||
# Create and set permissions for the working directory
|
||||
RUN mkdir -p /app && chown -R nodeuser:nodeuser /app
|
||||
WORKDIR /app
|
||||
USER nodeuser
|
||||
|
||||
# Copy package files first for better Docker layer caching
|
||||
COPY --chown=nodeuser:nodeuser package.json ./
|
||||
COPY --chown=nodeuser:nodeuser bun.lock ./
|
||||
|
||||
# Install dependencies
|
||||
RUN bun install --frozen-lockfile
|
||||
|
||||
# Copy source code
|
||||
COPY --chown=nodeuser:nodeuser . ./
|
||||
|
||||
# Build arguments for environment configuration
|
||||
# CouchDB Configuration
|
||||
ARG VITE_COUCHDB_URL=http://localhost:5984
|
||||
ARG VITE_COUCHDB_USER=admin
|
||||
ARG VITE_COUCHDB_PASSWORD=change-this-secure-password
|
||||
|
||||
# Application Configuration
|
||||
ARG APP_BASE_URL=http://localhost:5173
|
||||
|
||||
# OAuth Configuration (Optional)
|
||||
ARG VITE_GOOGLE_CLIENT_ID=""
|
||||
ARG VITE_GITHUB_CLIENT_ID=""
|
||||
|
||||
# Build Environment
|
||||
ARG NODE_ENV=production
|
||||
|
||||
# Set environment variables for build process
|
||||
# These are embedded into the static build at compile time
|
||||
ENV VITE_COUCHDB_URL=$VITE_COUCHDB_URL
|
||||
ENV VITE_COUCHDB_USER=$VITE_COUCHDB_USER
|
||||
ENV VITE_COUCHDB_PASSWORD=$VITE_COUCHDB_PASSWORD
|
||||
ENV APP_BASE_URL=$APP_BASE_URL
|
||||
ENV VITE_GOOGLE_CLIENT_ID=$VITE_GOOGLE_CLIENT_ID
|
||||
ENV VITE_GITHUB_CLIENT_ID=$VITE_GITHUB_CLIENT_ID
|
||||
ENV NODE_ENV=$NODE_ENV
|
||||
|
||||
# Build the application
|
||||
RUN bun run build
|
||||
|
||||
# Production stage - serve with nginx
|
||||
FROM nginx:alpine
|
||||
|
||||
# Install curl for health checks
|
||||
RUN apk add --no-cache curl
|
||||
|
||||
# Copy built files from builder stage
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# Copy nginx configuration
|
||||
COPY --from=builder /app/docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Set proper permissions for nginx
|
||||
RUN chown -R nginx:nginx /usr/share/nginx/html && \
|
||||
chown -R nginx:nginx /var/cache/nginx && \
|
||||
chown -R nginx:nginx /var/log/nginx && \
|
||||
chown -R nginx:nginx /etc/nginx/conf.d
|
||||
|
||||
# Add health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost/ || exit 1
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Start nginx (runs as nginx user by default in alpine)
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
76
docker/README.md
Normal file
76
docker/README.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# 🐳 Docker Configuration
|
||||
|
||||
This directory contains all Docker and containerization-related files for RxMinder.
|
||||
|
||||
## Files
|
||||
|
||||
- **`Dockerfile`** - Multi-stage Docker build configuration with buildx support
|
||||
- **`docker-compose.yaml`** - Service orchestration with multi-platform support
|
||||
- **`docker-bake.hcl`** - Advanced buildx configuration for multi-platform builds
|
||||
- **`nginx.conf`** - Production web server configuration
|
||||
- **`.dockerignore`** - Files and directories to exclude from Docker build context
|
||||
|
||||
## Docker Buildx Support
|
||||
|
||||
This project now supports Docker Buildx for multi-platform builds (AMD64 and ARM64).
|
||||
|
||||
### Quick Start with Buildx
|
||||
|
||||
```bash
|
||||
# Setup buildx builder (run once)
|
||||
../scripts/buildx-helper.sh setup
|
||||
|
||||
# Build for local platform only (faster for development)
|
||||
../scripts/buildx-helper.sh build-local
|
||||
|
||||
# Build for multiple platforms
|
||||
../scripts/buildx-helper.sh build-multi
|
||||
|
||||
# Build and push to registry
|
||||
../scripts/buildx-helper.sh push docker.io/username latest
|
||||
|
||||
# Build using Docker Bake (advanced)
|
||||
../scripts/buildx-helper.sh bake
|
||||
```
|
||||
|
||||
### Manual Buildx Commands
|
||||
|
||||
```bash
|
||||
# Create and use buildx builder
|
||||
docker buildx create --name rxminder-builder --driver docker-container --bootstrap --use
|
||||
|
||||
# Build for multiple platforms
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t rxminder:latest --load .
|
||||
|
||||
# Build with bake file
|
||||
docker buildx bake -f docker-bake.hcl
|
||||
```
|
||||
|
||||
## Traditional Usage
|
||||
|
||||
From the project root directory:
|
||||
|
||||
```bash
|
||||
# Build and start services
|
||||
docker compose -f docker/docker-compose.yaml up -d
|
||||
|
||||
# View logs
|
||||
docker compose -f docker/docker-compose.yaml logs
|
||||
|
||||
# Stop services
|
||||
docker compose -f docker/docker-compose.yaml down
|
||||
```
|
||||
|
||||
## Build Process
|
||||
|
||||
The Dockerfile uses a multi-stage build:
|
||||
|
||||
1. **Builder stage**: Installs dependencies and builds the React app
|
||||
2. **Production stage**: Serves the built app with nginx
|
||||
|
||||
## Services
|
||||
|
||||
- **frontend**: React application served by nginx
|
||||
- **couchdb**: Database for medication and user data
|
||||
|
||||
Both services include health checks and proper security configurations.
|
||||
101
docker/docker-bake.hcl
Normal file
101
docker/docker-bake.hcl
Normal file
@@ -0,0 +1,101 @@
|
||||
# Docker Bake file for advanced multi-platform builds
|
||||
# Usage: docker buildx bake -f docker-bake.hcl
|
||||
|
||||
variable "TAG" {
|
||||
default = "latest"
|
||||
}
|
||||
|
||||
variable "REGISTRY" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "VITE_COUCHDB_URL" {
|
||||
default = "http://localhost:5984"
|
||||
}
|
||||
|
||||
variable "VITE_COUCHDB_USER" {
|
||||
default = "admin"
|
||||
}
|
||||
|
||||
variable "VITE_COUCHDB_PASSWORD" {
|
||||
default = "change-this-secure-password"
|
||||
}
|
||||
|
||||
variable "APP_BASE_URL" {
|
||||
default = "http://localhost:8080"
|
||||
}
|
||||
|
||||
variable "VITE_GOOGLE_CLIENT_ID" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "VITE_GITHUB_CLIENT_ID" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
group "default" {
|
||||
targets = ["app"]
|
||||
}
|
||||
|
||||
target "app" {
|
||||
dockerfile = "Dockerfile"
|
||||
context = "."
|
||||
platforms = [
|
||||
"linux/amd64",
|
||||
"linux/arm64"
|
||||
]
|
||||
|
||||
tags = [
|
||||
"${REGISTRY}rxminder:${TAG}",
|
||||
"${REGISTRY}rxminder:latest"
|
||||
]
|
||||
|
||||
args = {
|
||||
# CouchDB Configuration
|
||||
VITE_COUCHDB_URL = "${VITE_COUCHDB_URL}"
|
||||
VITE_COUCHDB_USER = "${VITE_COUCHDB_USER}"
|
||||
VITE_COUCHDB_PASSWORD = "${VITE_COUCHDB_PASSWORD}"
|
||||
|
||||
# Application Configuration
|
||||
APP_BASE_URL = "${APP_BASE_URL}"
|
||||
|
||||
# OAuth Configuration (Optional)
|
||||
VITE_GOOGLE_CLIENT_ID = "${VITE_GOOGLE_CLIENT_ID}"
|
||||
VITE_GITHUB_CLIENT_ID = "${VITE_GITHUB_CLIENT_ID}"
|
||||
|
||||
# Build environment
|
||||
NODE_ENV = "production"
|
||||
}
|
||||
|
||||
# Advanced buildx features
|
||||
cache-from = [
|
||||
"type=gha",
|
||||
"type=registry,ref=${REGISTRY}rxminder:buildcache"
|
||||
]
|
||||
|
||||
cache-to = [
|
||||
"type=gha,mode=max",
|
||||
"type=registry,ref=${REGISTRY}rxminder:buildcache,mode=max"
|
||||
]
|
||||
|
||||
# Attestations for supply chain security
|
||||
attest = [
|
||||
"type=provenance,mode=max",
|
||||
"type=sbom"
|
||||
]
|
||||
}
|
||||
|
||||
# Development target for faster local builds
|
||||
target "dev" {
|
||||
inherits = ["app"]
|
||||
platforms = ["linux/amd64"]
|
||||
tags = ["rxminder:dev"]
|
||||
cache-from = ["type=gha"]
|
||||
cache-to = ["type=gha,mode=max"]
|
||||
}
|
||||
|
||||
# Production target with registry push
|
||||
target "prod" {
|
||||
inherits = ["app"]
|
||||
output = ["type=registry"]
|
||||
}
|
||||
65
docker/docker-compose.yaml
Normal file
65
docker/docker-compose.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
services:
|
||||
# Frontend service
|
||||
frontend:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
# CouchDB Configuration
|
||||
- VITE_COUCHDB_URL=${VITE_COUCHDB_URL:-http://couchdb:5984}
|
||||
- VITE_COUCHDB_USER=${VITE_COUCHDB_USER:-admin}
|
||||
- VITE_COUCHDB_PASSWORD=${VITE_COUCHDB_PASSWORD:-change-this-secure-password}
|
||||
# Application Configuration
|
||||
- APP_BASE_URL=${APP_BASE_URL:-http://localhost:8080}
|
||||
# OAuth Configuration (Optional)
|
||||
- VITE_GOOGLE_CLIENT_ID=${VITE_GOOGLE_CLIENT_ID:-}
|
||||
- VITE_GITHUB_CLIENT_ID=${VITE_GITHUB_CLIENT_ID:-}
|
||||
# Build Environment
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
# Enable buildx for multi-platform builds
|
||||
platforms:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
ports:
|
||||
- '8080:80'
|
||||
depends_on:
|
||||
couchdb:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
# Health check for the frontend container
|
||||
healthcheck:
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost/']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
labels:
|
||||
- 'monitoring=true'
|
||||
- 'service=frontend'
|
||||
|
||||
# CouchDB service
|
||||
couchdb:
|
||||
image: couchdb:3.3.2
|
||||
volumes:
|
||||
- ./couchdb-data:/opt/couchdb/data
|
||||
environment:
|
||||
- COUCHDB_USER=${COUCHDB_USER:-admin}
|
||||
- COUCHDB_PASSWORD=${COUCHDB_PASSWORD:-change-this-secure-password}
|
||||
ports:
|
||||
- '5984:5984'
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:5984/_up']
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
labels:
|
||||
- 'monitoring=true'
|
||||
- 'service=couchdb'
|
||||
|
||||
# Redis service (commented out as per requirements)
|
||||
# redis:
|
||||
# image: redis:alpine
|
||||
# restart: unless-stopped
|
||||
# labels:
|
||||
# - "monitoring=true"
|
||||
# - "service=redis"
|
||||
36
docker/nginx.conf
Normal file
36
docker/nginx.conf
Normal file
@@ -0,0 +1,36 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Enable gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
|
||||
|
||||
# Handle client-side routing
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin";
|
||||
|
||||
# Health check endpoint
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user