Add Docker containerization support
Features: - Multi-stage Dockerfile for optimized production builds - Docker Compose configuration with health checks - Health check endpoint for container monitoring - Production environment configuration template - Comprehensive deployment guide for Mac Mini - Docker ignore file for efficient build context - Security: Non-root user, proper signal handling - Persistence: Data directory volume mounting - Performance: Alpine Linux base, optimized layers - Future-ready: MongoDB service configuration (commented) Deployment: - Simple 'docker-compose up' deployment - Automatic health monitoring and restart policies - Persistent data storage with volume mounts - Port configuration and environment customization - Complete troubleshooting and management guide
This commit is contained in:
parent
4920db6c51
commit
6038535896
7 changed files with 398 additions and 0 deletions
58
.dockerignore
Normal file
58
.dockerignore
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
# Docker ignore file for Etsy Finance Tracker
|
||||||
|
# Excludes unnecessary files from Docker build context
|
||||||
|
|
||||||
|
# Node modules - will be installed in container
|
||||||
|
node_modules/
|
||||||
|
client/node_modules/
|
||||||
|
server/node_modules/
|
||||||
|
|
||||||
|
# Build outputs - will be created in container
|
||||||
|
client/dist/
|
||||||
|
server/dist/
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Development files
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
*.md
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
# Environment and config files
|
||||||
|
.env*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Data files - these should be mounted as volumes
|
||||||
|
data/
|
||||||
|
!data/README.md
|
||||||
|
|
||||||
|
# IDE and editor files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Test and coverage
|
||||||
|
coverage/
|
||||||
|
test-results/
|
||||||
|
.nyc_output/
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
*.tmp
|
||||||
|
|
||||||
|
# Mac specific
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -14,6 +14,7 @@ build/
|
||||||
.env.development.local
|
.env.development.local
|
||||||
.env.test.local
|
.env.test.local
|
||||||
.env.production.local
|
.env.production.local
|
||||||
|
server/.env
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
|
|
|
||||||
183
DOCKER_DEPLOYMENT.md
Normal file
183
DOCKER_DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
# Docker Deployment Guide for Mac Mini
|
||||||
|
|
||||||
|
This guide will help you deploy the Etsy Finance Tracker on your Mac Mini using Docker.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. **Install Docker Desktop** on your Mac Mini:
|
||||||
|
```bash
|
||||||
|
# Option 1: Download from Docker website
|
||||||
|
# Go to https://docs.docker.com/desktop/mac/install/
|
||||||
|
|
||||||
|
# Option 2: Install with Homebrew (if available)
|
||||||
|
brew install --cask docker
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install Git** (if not already installed):
|
||||||
|
```bash
|
||||||
|
brew install git
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment Steps
|
||||||
|
|
||||||
|
### 1. Clone the Repository
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/dlawler489/etsy-finance-tracker.git
|
||||||
|
cd etsy-finance-tracker
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Prepare Your Data
|
||||||
|
```bash
|
||||||
|
# Create the data directory structure
|
||||||
|
mkdir -p data/{csv,pdf,spreadsheets}
|
||||||
|
|
||||||
|
# Copy your business files to the data directory
|
||||||
|
# Example:
|
||||||
|
# cp ~/Documents/BusinessData/*.csv data/csv/
|
||||||
|
# cp ~/Documents/BusinessData/*.pdf data/pdf/
|
||||||
|
# cp ~/Documents/BusinessData/*.xlsx data/spreadsheets/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configure Environment (Optional)
|
||||||
|
```bash
|
||||||
|
# Copy the production environment template
|
||||||
|
cp server/.env.production server/.env
|
||||||
|
|
||||||
|
# Edit the environment file if needed
|
||||||
|
nano server/.env
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Build and Run with Docker Compose
|
||||||
|
```bash
|
||||||
|
# Build and start the application
|
||||||
|
docker-compose up --build -d
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
docker-compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Access Your Application
|
||||||
|
- **Web Interface**: http://localhost:3000
|
||||||
|
- **API Health Check**: http://localhost:3000/health
|
||||||
|
|
||||||
|
## Management Commands
|
||||||
|
|
||||||
|
### Start/Stop the Application
|
||||||
|
```bash
|
||||||
|
# Start
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# Stop
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# Restart
|
||||||
|
docker-compose restart
|
||||||
|
```
|
||||||
|
|
||||||
|
### View Logs
|
||||||
|
```bash
|
||||||
|
# All services
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# Specific service
|
||||||
|
docker-compose logs -f etsy-tracker
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update the Application
|
||||||
|
```bash
|
||||||
|
# Pull latest code
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Rebuild and restart
|
||||||
|
docker-compose down
|
||||||
|
docker-compose up --build -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup Your Data
|
||||||
|
```bash
|
||||||
|
# Your business data in the data/ directory is automatically persisted
|
||||||
|
# To backup:
|
||||||
|
tar -czf etsy-tracker-backup-$(date +%Y%m%d).tar.gz data/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Check Application Health
|
||||||
|
```bash
|
||||||
|
# Test the health endpoint
|
||||||
|
curl http://localhost:3000/health
|
||||||
|
|
||||||
|
# Check container logs
|
||||||
|
docker-compose logs etsy-tracker
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Port Already in Use**:
|
||||||
|
```bash
|
||||||
|
# Change port in docker-compose.yml
|
||||||
|
ports:
|
||||||
|
- "3001:3000" # Change 3000 to 3001
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Permission Issues**:
|
||||||
|
```bash
|
||||||
|
# Fix data directory permissions
|
||||||
|
sudo chown -R $(whoami):$(whoami) data/
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Memory Issues**:
|
||||||
|
```bash
|
||||||
|
# Add memory limits to docker-compose.yml
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512M
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
Your deployment will look like this:
|
||||||
|
```
|
||||||
|
etsy-finance-tracker/
|
||||||
|
├── data/ # Your business data (persistent)
|
||||||
|
│ ├── csv/ # CSV files
|
||||||
|
│ ├── pdf/ # PDF documents
|
||||||
|
│ └── spreadsheets/ # Excel files
|
||||||
|
├── docker-compose.yml # Container orchestration
|
||||||
|
├── Dockerfile # Container configuration
|
||||||
|
└── ... (application code)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
- The `data/` directory contains your sensitive business files
|
||||||
|
- This directory is mounted as a volume and persists between container restarts
|
||||||
|
- Never commit the `data/` directory to git
|
||||||
|
- Change default passwords in `.env` file for production use
|
||||||
|
|
||||||
|
## Performance Optimization
|
||||||
|
|
||||||
|
For better performance on Mac Mini:
|
||||||
|
|
||||||
|
1. **Allocate more resources to Docker Desktop**:
|
||||||
|
- Open Docker Desktop preferences
|
||||||
|
- Go to Resources → Advanced
|
||||||
|
- Increase Memory to at least 4GB
|
||||||
|
- Increase CPU to at least 2 cores
|
||||||
|
|
||||||
|
2. **Enable BuildKit** for faster builds:
|
||||||
|
```bash
|
||||||
|
export DOCKER_BUILDKIT=1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
If you encounter issues:
|
||||||
|
1. Check the logs: `docker-compose logs`
|
||||||
|
2. Verify Docker is running: `docker version`
|
||||||
|
3. Check port availability: `lsof -i :3000`
|
||||||
|
4. Review the troubleshooting section above
|
||||||
61
Dockerfile
Normal file
61
Dockerfile
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
# Multi-stage build for production-ready Etsy Finance Tracker
|
||||||
|
|
||||||
|
# Stage 1: Build the React client
|
||||||
|
FROM node:18-alpine AS client-build
|
||||||
|
WORKDIR /app/client
|
||||||
|
|
||||||
|
# Copy client package files
|
||||||
|
COPY client/package*.json ./
|
||||||
|
RUN npm ci --only=production
|
||||||
|
|
||||||
|
# Copy client source and build
|
||||||
|
COPY client/ ./
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Stage 2: Build the Node.js server
|
||||||
|
FROM node:18-alpine AS server-build
|
||||||
|
WORKDIR /app/server
|
||||||
|
|
||||||
|
# Copy server package files
|
||||||
|
COPY server/package*.json ./
|
||||||
|
RUN npm ci --only=production
|
||||||
|
|
||||||
|
# Copy server source and build
|
||||||
|
COPY server/ ./
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Stage 3: Production runtime
|
||||||
|
FROM node:18-alpine AS production
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dumb-init for proper signal handling and curl for health checks
|
||||||
|
RUN apk add --no-cache dumb-init curl
|
||||||
|
|
||||||
|
# Create non-root user for security
|
||||||
|
RUN addgroup -g 1001 -S nodejs
|
||||||
|
RUN adduser -S nodejs -u 1001
|
||||||
|
|
||||||
|
# Copy built server
|
||||||
|
COPY --from=server-build --chown=nodejs:nodejs /app/server/dist ./server/
|
||||||
|
COPY --from=server-build --chown=nodejs:nodejs /app/server/node_modules ./server/node_modules/
|
||||||
|
COPY --from=server-build --chown=nodejs:nodejs /app/server/package*.json ./server/
|
||||||
|
|
||||||
|
# Copy built client
|
||||||
|
COPY --from=client-build --chown=nodejs:nodejs /app/client/dist ./client/dist/
|
||||||
|
|
||||||
|
# Create data directory for persistent storage
|
||||||
|
RUN mkdir -p /app/data && chown nodejs:nodejs /app/data
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
|
USER nodejs
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:3000/health || exit 1
|
||||||
|
|
||||||
|
# Start the application
|
||||||
|
ENTRYPOINT ["dumb-init", "--"]
|
||||||
|
CMD ["node", "server/index.js"]
|
||||||
51
docker-compose.yml
Normal file
51
docker-compose.yml
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# Etsy Finance Tracker Application
|
||||||
|
etsy-tracker:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: etsy-finance-tracker
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=3000
|
||||||
|
volumes:
|
||||||
|
# Mount data directory for persistent storage
|
||||||
|
- ./data:/app/data
|
||||||
|
# Optional: Mount uploads directory if needed
|
||||||
|
- etsy_uploads:/app/uploads
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- etsy-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
# Optional: MongoDB for future database needs
|
||||||
|
# mongodb:
|
||||||
|
# image: mongo:6.0
|
||||||
|
# container_name: etsy-mongo
|
||||||
|
# ports:
|
||||||
|
# - "27017:27017"
|
||||||
|
# environment:
|
||||||
|
# MONGO_INITDB_ROOT_USERNAME: admin
|
||||||
|
# MONGO_INITDB_ROOT_PASSWORD: changeme
|
||||||
|
# volumes:
|
||||||
|
# - etsy_mongodb_data:/data/db
|
||||||
|
# networks:
|
||||||
|
# - etsy-network
|
||||||
|
# restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
etsy_uploads:
|
||||||
|
# etsy_mongodb_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
etsy-network:
|
||||||
|
driver: bridge
|
||||||
34
server/.env.production
Normal file
34
server/.env.production
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Production Environment Configuration
|
||||||
|
# Copy this file to .env and customize for your deployment
|
||||||
|
|
||||||
|
# Application
|
||||||
|
NODE_ENV=production
|
||||||
|
PORT=3000
|
||||||
|
|
||||||
|
# Client Configuration
|
||||||
|
CLIENT_URL=http://localhost:3000
|
||||||
|
|
||||||
|
# Database (when using MongoDB)
|
||||||
|
# MONGODB_URI=mongodb://mongodb:27017/etsy-tracker
|
||||||
|
# DB_NAME=etsy-tracker
|
||||||
|
|
||||||
|
# JWT Configuration
|
||||||
|
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
|
||||||
|
JWT_EXPIRES_IN=7d
|
||||||
|
|
||||||
|
# CORS Configuration
|
||||||
|
ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
|
||||||
|
|
||||||
|
# File Upload Limits
|
||||||
|
MAX_FILE_SIZE=10mb
|
||||||
|
UPLOAD_PATH=/app/uploads
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
LOG_LEVEL=info
|
||||||
|
|
||||||
|
# Rate Limiting
|
||||||
|
RATE_LIMIT_WINDOW_MS=900000
|
||||||
|
RATE_LIMIT_MAX_REQUESTS=100
|
||||||
|
|
||||||
|
# Security
|
||||||
|
BCRYPT_SALT_ROUNDS=12
|
||||||
|
|
@ -44,6 +44,16 @@ app.use(express.urlencoded({ extended: true }));
|
||||||
// Logging middleware
|
// Logging middleware
|
||||||
app.use(morgan('combined'));
|
app.use(morgan('combined'));
|
||||||
|
|
||||||
|
// Health check endpoint for Docker
|
||||||
|
app.get('/health', (req, res) => {
|
||||||
|
res.status(200).json({
|
||||||
|
status: 'OK',
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
uptime: process.uptime(),
|
||||||
|
service: 'Etsy Finance Tracker API'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Database connection (temporarily disabled for development)
|
// Database connection (temporarily disabled for development)
|
||||||
// mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/etsy-tracker')
|
// mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/etsy-tracker')
|
||||||
// .then(() => console.log('Connected to MongoDB'))
|
// .then(() => console.log('Connected to MongoDB'))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue