refactor: simplify Docker and CI/CD to use unified config
- Replace symlinked Dockerfile with simplified version in root - Reduce Docker build args (unified config provides defaults) - Update CI/CD workflows to use minimal build arguments - Add nginx.conf to root directory (replace docker/nginx.conf) - Remove docker-bake references from CI/CD workflows - Focus on essential runtime overrides only - Let unified config handle smart defaults
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
docker/.dockerignore
|
|
||||||
113
.dockerignore
Normal file
113
.dockerignore
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# Node.js
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
.cache/
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# IDE and editor files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
README.md
|
||||||
|
*.md
|
||||||
|
docs/
|
||||||
|
|
||||||
|
# Test files
|
||||||
|
tests/
|
||||||
|
test-results/
|
||||||
|
coverage/
|
||||||
|
playwright-report/
|
||||||
|
|
||||||
|
# Development files
|
||||||
|
.husky/
|
||||||
|
.github/
|
||||||
|
.gitea/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids/
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage/
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# Storybook build outputs
|
||||||
|
.out
|
||||||
|
.storybook-out
|
||||||
|
|
||||||
|
# Temporary folders
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
|
||||||
|
# Configuration files not needed in container
|
||||||
|
*.config.js
|
||||||
|
*.config.ts
|
||||||
|
!vite.config.ts
|
||||||
|
!jest.config.json
|
||||||
@@ -47,31 +47,19 @@ jobs:
|
|||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: ./docker
|
context: .
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ gitea.event_name != 'pull_request' }}
|
push: ${{ gitea.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
build-args: |
|
build-args: |
|
||||||
VITE_COUCHDB_URL=${{ vars.VITE_COUCHDB_URL || 'http://localhost:5984' }}
|
|
||||||
VITE_COUCHDB_USER=${{ vars.VITE_COUCHDB_USER || 'admin' }}
|
|
||||||
VITE_COUCHDB_PASSWORD=${{ secrets.VITE_COUCHDB_PASSWORD || 'change-this-secure-password' }}
|
|
||||||
APP_BASE_URL=${{ vars.APP_BASE_URL || 'http://localhost:8080' }}
|
|
||||||
VITE_GOOGLE_CLIENT_ID=${{ vars.VITE_GOOGLE_CLIENT_ID || '' }}
|
|
||||||
VITE_GITHUB_CLIENT_ID=${{ vars.VITE_GITHUB_CLIENT_ID || '' }}
|
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
|
VITE_COUCHDB_URL=${{ vars.VITE_COUCHDB_URL }}
|
||||||
|
VITE_COUCHDB_USER=${{ vars.VITE_COUCHDB_USER }}
|
||||||
|
VITE_COUCHDB_PASSWORD=${{ secrets.VITE_COUCHDB_PASSWORD }}
|
||||||
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
|
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
|
||||||
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
|
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
|
||||||
|
|
||||||
- name: Build with Bake (Alternative)
|
|
||||||
if: false # Set to true to use bake instead
|
|
||||||
uses: docker/bake-action@v4
|
|
||||||
with:
|
|
||||||
workdir: ./docker
|
|
||||||
files: docker-bake.hcl
|
|
||||||
targets: prod
|
|
||||||
push: ${{ gitea.event_name != 'pull_request' }}
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
|
|||||||
20
.github/workflows/build-deploy.yml
vendored
20
.github/workflows/build-deploy.yml
vendored
@@ -45,31 +45,19 @@ jobs:
|
|||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: ./docker
|
context: .
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
build-args: |
|
build-args: |
|
||||||
VITE_COUCHDB_URL=${{ vars.VITE_COUCHDB_URL || 'http://localhost:5984' }}
|
|
||||||
VITE_COUCHDB_USER=${{ vars.VITE_COUCHDB_USER || 'admin' }}
|
|
||||||
VITE_COUCHDB_PASSWORD=${{ secrets.VITE_COUCHDB_PASSWORD || 'change-this-secure-password' }}
|
|
||||||
APP_BASE_URL=${{ vars.APP_BASE_URL || 'http://localhost:8080' }}
|
|
||||||
VITE_GOOGLE_CLIENT_ID=${{ vars.VITE_GOOGLE_CLIENT_ID || '' }}
|
|
||||||
VITE_GITHUB_CLIENT_ID=${{ vars.VITE_GITHUB_CLIENT_ID || '' }}
|
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
|
VITE_COUCHDB_URL=${{ vars.VITE_COUCHDB_URL }}
|
||||||
|
VITE_COUCHDB_USER=${{ vars.VITE_COUCHDB_USER }}
|
||||||
|
VITE_COUCHDB_PASSWORD=${{ secrets.VITE_COUCHDB_PASSWORD }}
|
||||||
cache-from: type=gha
|
cache-from: type=gha
|
||||||
cache-to: type=gha,mode=max
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
- name: Build with Bake (Alternative)
|
|
||||||
if: false # Set to true to use bake instead
|
|
||||||
uses: docker/bake-action@v4
|
|
||||||
with:
|
|
||||||
workdir: ./docker
|
|
||||||
files: docker-bake.hcl
|
|
||||||
targets: prod
|
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
docker/Dockerfile
|
|
||||||
81
Dockerfile
Normal file
81
Dockerfile
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# Multi-stage Dockerfile for Medication Reminder App
|
||||||
|
FROM node:20-slim AS base
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Bun
|
||||||
|
RUN curl -fsSL https://bun.sh/install | bash
|
||||||
|
ENV PATH="/root/.bun/bin:$PATH"
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Create non-root user
|
||||||
|
RUN groupadd --gid 1001 nodeuser && \
|
||||||
|
useradd --uid 1001 --gid nodeuser --shell /bin/bash --create-home nodeuser
|
||||||
|
|
||||||
|
# Builder stage
|
||||||
|
FROM base AS builder
|
||||||
|
|
||||||
|
# Copy package files
|
||||||
|
COPY --chown=nodeuser:nodeuser package.json bun.lock* ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN bun install --frozen-lockfile
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
COPY --chown=nodeuser:nodeuser . ./
|
||||||
|
|
||||||
|
# Build arguments for environment configuration
|
||||||
|
# Build Environment - unified config will handle the rest
|
||||||
|
ARG NODE_ENV=production
|
||||||
|
|
||||||
|
# Only essential runtime variables that override unified config defaults
|
||||||
|
ARG VITE_COUCHDB_URL
|
||||||
|
ARG VITE_COUCHDB_USER
|
||||||
|
ARG VITE_COUCHDB_PASSWORD
|
||||||
|
|
||||||
|
# Set environment variables for build process
|
||||||
|
# Unified config handles defaults, only set essential runtime overrides
|
||||||
|
ENV NODE_ENV=$NODE_ENV
|
||||||
|
ENV VITE_COUCHDB_URL=$VITE_COUCHDB_URL
|
||||||
|
ENV VITE_COUCHDB_USER=$VITE_COUCHDB_USER
|
||||||
|
ENV VITE_COUCHDB_PASSWORD=$VITE_COUCHDB_PASSWORD
|
||||||
|
ENV NODE_ENV=$NODE_ENV
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
RUN bun run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM nginx:alpine AS production
|
||||||
|
|
||||||
|
# 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 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
|
||||||
|
|
||||||
|
# Switch to nginx user
|
||||||
|
USER nginx
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
|
CMD curl -f http://localhost/health || exit 1
|
||||||
|
|
||||||
|
# Start nginx
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
49
nginx.conf
Normal file
49
nginx.conf
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
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_proxied expired no-cache no-store private must-revalidate auth;
|
||||||
|
gzip_types
|
||||||
|
text/plain
|
||||||
|
text/css
|
||||||
|
text/xml
|
||||||
|
text/javascript
|
||||||
|
application/javascript
|
||||||
|
application/xml+rss
|
||||||
|
application/json;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||||
|
|
||||||
|
# Handle React Router (SPA)
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Disable access to hidden files
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user