mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-24 08:45:10 +00:00
Add zerops.yml with deployment specs.
This commit is contained in:
parent
ea00b0ec9d
commit
831c3716e4
8 changed files with 991 additions and 0 deletions
195
HYBRID_DEPLOYMENT.md
Normal file
195
HYBRID_DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
# Hybrid Deployment Guide: Apps in Image + Persistent Volumes
|
||||
|
||||
This configuration implements the best of both worlds:
|
||||
- **Apps baked into Docker image** for consistency and fast deployments
|
||||
- **Site data in persistent volumes** for data safety and persistence
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### What's in the Image (Built once, reusable):
|
||||
- ✅ Frappe and ERPNext applications
|
||||
- ✅ All Python dependencies
|
||||
- ✅ Custom apps (if configured)
|
||||
- ✅ Basic directory structure
|
||||
|
||||
### What's in Persistent Volumes:
|
||||
- ✅ Site configurations (`sites/[site-name]/site_config.json`)
|
||||
- ✅ Uploaded files (`sites/[site-name]/public/files/`)
|
||||
- ✅ Private files (`sites/[site-name]/private/files/`)
|
||||
- ✅ Site-specific customizations
|
||||
- ✅ Database backups
|
||||
- ✅ Application logs
|
||||
|
||||
## Deployment Steps
|
||||
|
||||
### 1. Set Required Environment Secrets in Zerops
|
||||
|
||||
```bash
|
||||
# In Zerops Dashboard > Project > Environment Variables
|
||||
db_password=YourSecureDbPassword123
|
||||
admin_password=YourAdminPassword123
|
||||
site_name=your-domain.com
|
||||
```
|
||||
|
||||
### 2. Deploy the Configuration
|
||||
|
||||
1. Import the `zerops.yml` file to Zerops
|
||||
2. Zerops will build all services using `Dockerfile.zerops`
|
||||
3. Each service will run the initialization script on startup
|
||||
4. Site will be automatically created if it doesn't exist
|
||||
|
||||
### 3. Automatic Initialization Process
|
||||
|
||||
On first deployment, each container will:
|
||||
|
||||
1. **Build Phase** (runs once during image creation):
|
||||
- Install Frappe/ERPNext apps into image
|
||||
- Copy initialization scripts
|
||||
- Set proper permissions
|
||||
|
||||
2. **Runtime Phase** (runs on every container start):
|
||||
- **Backend service**: Full site initialization (creates site, installs ERPNext)
|
||||
- **Other services**: Light initialization (just checks if site exists)
|
||||
- Configure database and Redis connections
|
||||
- Wait for database to be ready (backend only)
|
||||
- Set proper permissions and configurations
|
||||
|
||||
## Benefits of This Approach
|
||||
|
||||
### ✅ **Container Restart Resilience**
|
||||
- Site data survives container restarts/crashes
|
||||
- No manual intervention required
|
||||
- Fast recovery times
|
||||
|
||||
### ✅ **Consistent App Deployments**
|
||||
- Apps are identical across all containers
|
||||
- No version drift between services
|
||||
- Easy to update apps (rebuild image)
|
||||
|
||||
### ✅ **Zero-Downtime Updates**
|
||||
- App updates: rebuild image, rolling update
|
||||
- Site data preserved during updates
|
||||
- Database migrations handled automatically
|
||||
|
||||
### ✅ **Backup & Recovery**
|
||||
- Simple volume snapshots for site data
|
||||
- Database backups work seamlessly
|
||||
- Easy disaster recovery
|
||||
|
||||
### ✅ **Scalability**
|
||||
- New containers start with same apps
|
||||
- Shared persistent volume for site data
|
||||
- Auto-scaling works out of the box
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
/home/frappe/frappe-bench/
|
||||
├── apps/ # Apps (in image)
|
||||
│ ├── frappe/ # Frappe framework
|
||||
│ └── erpnext/ # ERPNext app
|
||||
├── sites/ # Site data (persistent volume)
|
||||
│ ├── apps.txt # List of installed apps
|
||||
│ ├── common_site_config.json
|
||||
│ └── your-domain.com/ # Your site directory
|
||||
│ ├── site_config.json
|
||||
│ ├── public/files/ # Uploaded files
|
||||
│ └── private/files/ # Private files
|
||||
└── logs/ # Application logs (persistent volume)
|
||||
```
|
||||
|
||||
## Common Operations
|
||||
|
||||
### Adding New Custom Apps
|
||||
|
||||
1. **Update `Dockerfile.zerops`**:
|
||||
```dockerfile
|
||||
RUN bench get-app --branch main custom_app https://github.com/user/custom_app.git
|
||||
```
|
||||
|
||||
2. **Redeploy services** (Zerops will rebuild image)
|
||||
|
||||
3. **Install app on site** (automatic or manual):
|
||||
```bash
|
||||
bench --site your-domain.com install-app custom_app
|
||||
```
|
||||
|
||||
### Updating Frappe/ERPNext Version
|
||||
|
||||
1. **Update version in `Dockerfile.zerops`**:
|
||||
```dockerfile
|
||||
FROM frappe/erpnext:v16.0.0
|
||||
```
|
||||
|
||||
2. **Update `zerops.yml` environment**:
|
||||
```yaml
|
||||
ERPNEXT_VERSION: v16.0.0
|
||||
```
|
||||
|
||||
3. **Redeploy** - migrations run automatically
|
||||
|
||||
### Manual Site Operations
|
||||
|
||||
Access any service terminal in Zerops dashboard:
|
||||
|
||||
```bash
|
||||
# Navigate to bench directory
|
||||
cd /home/frappe/frappe-bench
|
||||
|
||||
# Run migrations
|
||||
bench --site your-domain.com migrate
|
||||
|
||||
# Create new site
|
||||
bench new-site newsite.com --install-app erpnext
|
||||
|
||||
# Install custom app
|
||||
bench --site your-domain.com install-app custom_app
|
||||
|
||||
# Backup site
|
||||
bench --site your-domain.com backup --with-files
|
||||
|
||||
# Console access
|
||||
bench --site your-domain.com console
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Site Not Created Automatically
|
||||
- Check environment variables are set correctly
|
||||
- Check database connectivity
|
||||
- Review container logs in Zerops dashboard
|
||||
- Manually run: `/home/frappe/init-site.sh`
|
||||
|
||||
### Permission Issues
|
||||
- Persistent volumes should be owned by `frappe:frappe`
|
||||
- Run: `chown -R frappe:frappe /home/frappe/frappe-bench/sites`
|
||||
|
||||
### App Installation Issues
|
||||
- Verify apps are in the image: `ls /home/frappe/frappe-bench/apps`
|
||||
- Check apps.txt: `cat /home/frappe/frappe-bench/sites/apps.txt`
|
||||
- Manually install: `bench --site [site] install-app [app]`
|
||||
|
||||
### Database Connection Issues
|
||||
- Verify database service is running
|
||||
- Check environment variables
|
||||
- Test connection: `mysql -h$DB_HOST -P$DB_PORT -uroot -p$DB_PASSWORD`
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Health Checks
|
||||
- All services have health checks configured
|
||||
- Monitor in Zerops dashboard
|
||||
- Backend: `/api/method/ping`
|
||||
- WebSocket: `/socket.io/`
|
||||
|
||||
### Logs
|
||||
- Application logs in persistent volume: `/home/frappe/frappe-bench/logs`
|
||||
- Container logs in Zerops dashboard
|
||||
- Database logs in MariaDB service logs
|
||||
|
||||
### Performance
|
||||
- Monitor resource usage in Zerops dashboard
|
||||
- Auto-scaling configured based on CPU/memory
|
||||
- Adjust container limits as needed
|
||||
|
||||
This hybrid approach gives you the reliability of persistent data with the consistency of containerized applications!
|
||||
159
ZEROPS_DEPLOYMENT.md
Normal file
159
ZEROPS_DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
# Deploying Frappe/ERPNext on Zerops
|
||||
|
||||
This repository contains the Zerops configuration file (`zerops.yml`) to deploy Frappe/ERPNext on the Zerops platform.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The deployment consists of the following services:
|
||||
|
||||
- **MariaDB** (`db`) - Database service (HA mode)
|
||||
- **Redis Cache** (`redis-cache`) - Caching layer
|
||||
- **Redis Queue** (`redis-queue`) - Background job queue
|
||||
- **Backend** (`backend`) - Main Frappe application server
|
||||
- **Frontend** (`frontend`) - Nginx reverse proxy
|
||||
- **WebSocket** (`websocket`) - Real-time communication server
|
||||
- **Queue Workers** (`queue-short`, `queue-long`) - Background job processors
|
||||
- **Scheduler** (`scheduler`) - Cron job scheduler
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. A Zerops account - [Sign up here](https://zerops.io)
|
||||
2. Access to this GitHub repository
|
||||
3. Basic knowledge of Frappe/ERPNext
|
||||
|
||||
## Deployment Steps
|
||||
|
||||
### 1. Import Project to Zerops
|
||||
|
||||
1. Log into your Zerops dashboard
|
||||
2. Click "Import project"
|
||||
3. Select "Import from Git repository"
|
||||
4. Enter the repository URL: `https://github.com/UhrinDavid/frappe_docker`
|
||||
5. Select the `zerops.yml` file
|
||||
6. Click "Import project"
|
||||
|
||||
### 2. Configure Environment Secrets
|
||||
|
||||
Before deployment, you need to set the following environment secrets in Zerops:
|
||||
|
||||
#### Required Secrets:
|
||||
- `db_password` - Password for MariaDB database (choose a strong password)
|
||||
- `site_name` - Your site domain name (e.g., `mycompany.example.com`)
|
||||
|
||||
#### Optional Secrets:
|
||||
- `ERPNEXT_VERSION` - ERPNext version (default: v15.84.0)
|
||||
|
||||
To set secrets:
|
||||
1. Go to your project in Zerops dashboard
|
||||
2. Navigate to each service
|
||||
3. Go to "Environment variables" section
|
||||
4. Add the required secrets
|
||||
|
||||
### 3. Deploy the Services
|
||||
|
||||
1. Zerops will automatically start building and deploying all services
|
||||
2. Monitor the build progress in the Zerops dashboard
|
||||
3. Wait for all services to reach "Running" status
|
||||
|
||||
### 4. Post-Deployment Setup
|
||||
|
||||
Once all services are running, you need to initialize your Frappe site:
|
||||
|
||||
1. Access the backend service terminal in Zerops dashboard
|
||||
2. Create your first site:
|
||||
```bash
|
||||
bench new-site your-site-name --db-root-password <db_password>
|
||||
```
|
||||
|
||||
3. Install ERPNext:
|
||||
```bash
|
||||
bench --site your-site-name install-app erpnext
|
||||
```
|
||||
|
||||
4. Set the site as default:
|
||||
```bash
|
||||
bench use your-site-name
|
||||
```
|
||||
|
||||
5. Create an admin user:
|
||||
```bash
|
||||
bench --site your-site-name add-user admin administrator --password <admin-password>
|
||||
```
|
||||
|
||||
### 5. Access Your Application
|
||||
|
||||
Your Frappe/ERPNext instance will be available at the domain provided by Zerops for the `frontend` service.
|
||||
|
||||
## Configuration Details
|
||||
|
||||
### Resource Allocation
|
||||
|
||||
- **Backend**: 1-3 containers, autoscaling enabled
|
||||
- **Frontend**: 1-2 containers
|
||||
- **WebSocket**: 1-2 containers
|
||||
- **Queue Workers**: 1-3 containers (short), 1-2 containers (long)
|
||||
- **Scheduler**: 1 container (fixed)
|
||||
- **Databases**: HA mode for production reliability
|
||||
|
||||
### Health Checks
|
||||
|
||||
All services include health checks to ensure proper operation:
|
||||
- Backend: `/api/method/ping`
|
||||
- Frontend: `/api/method/ping`
|
||||
- WebSocket: `/socket.io/`
|
||||
|
||||
### Autoscaling
|
||||
|
||||
Backend and queue workers have autoscaling configured based on:
|
||||
- CPU usage threshold: 70%
|
||||
- Memory usage threshold: 80%
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Services not starting**: Check environment variables are set correctly
|
||||
2. **Database connection errors**: Verify `db_password` secret is set
|
||||
3. **Site access issues**: Ensure `site_name` matches your domain
|
||||
|
||||
### Logs
|
||||
|
||||
Access service logs through the Zerops dashboard:
|
||||
1. Go to your project
|
||||
2. Select the service
|
||||
3. Navigate to "Runtime logs"
|
||||
|
||||
### Manual Commands
|
||||
|
||||
To run manual bench commands:
|
||||
1. Access the backend service terminal
|
||||
2. Navigate to `/home/frappe/frappe-bench`
|
||||
3. Run your bench commands
|
||||
|
||||
## Customization
|
||||
|
||||
### Custom Apps
|
||||
|
||||
To add custom Frappe apps:
|
||||
1. Modify the Dockerfile to include your apps
|
||||
2. Update the `zerops.yml` build configuration
|
||||
3. Redeploy the services
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Additional environment variables can be added in the `zerops.yml` file under the `envSecrets` section for each service.
|
||||
|
||||
### Scaling
|
||||
|
||||
Adjust the `minContainers` and `maxContainers` values in `zerops.yml` based on your traffic requirements.
|
||||
|
||||
## Support
|
||||
|
||||
For issues specific to:
|
||||
- Zerops platform: [Zerops Documentation](https://docs.zerops.io)
|
||||
- Frappe/ERPNext: [Frappe Documentation](https://docs.frappe.io)
|
||||
- This deployment setup: Create an issue in this repository
|
||||
|
||||
## License
|
||||
|
||||
This configuration is provided under the same license as the original frappe_docker repository.
|
||||
81
scripts/init-frappe-site.sh
Normal file
81
scripts/init-frappe-site.sh
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Frappe Site Initialization Script for Production Deployment
|
||||
# This script runs before the main service starts to ensure the site exists and is configured
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔧 Initializing Frappe site..."
|
||||
|
||||
# Configuration from environment variables
|
||||
SITE_NAME=${FRAPPE_SITE_NAME_HEADER:-"localhost"}
|
||||
DB_PASSWORD=${DB_PASSWORD:-"admin"}
|
||||
ADMIN_PASSWORD=${ADMIN_PASSWORD:-"admin"}
|
||||
DB_HOST=${DB_HOST:-"db"}
|
||||
DB_PORT=${DB_PORT:-"3306"}
|
||||
|
||||
echo "📋 Configuration: Site Name: $SITE_NAME, Database Host: $DB_HOST:$DB_PORT"
|
||||
|
||||
# Navigate to frappe bench directory
|
||||
cd /home/frappe/frappe-bench
|
||||
|
||||
# Configure database and Redis connections
|
||||
echo "🔗 Configuring connections..."
|
||||
bench set-config -g db_host "$DB_HOST" || echo "DB host config already set"
|
||||
bench set-config -gp db_port "$DB_PORT" || echo "DB port config already set"
|
||||
bench set-config -g redis_cache "redis://${REDIS_CACHE}:6379" || echo "Redis cache config already set"
|
||||
bench set-config -g redis_queue "redis://${REDIS_QUEUE}:6379" || echo "Redis queue config already set"
|
||||
bench set-config -g redis_socketio "redis://${REDIS_QUEUE}:6379" || echo "Redis socketio config already set"
|
||||
bench set-config -gp socketio_port "${SOCKETIO_PORT}" || echo "Socketio port config already set"
|
||||
|
||||
# Wait for database to be ready
|
||||
echo "⏳ Waiting for database to be ready..."
|
||||
for i in {1..30}; do
|
||||
if mysql -h"$DB_HOST" -P"$DB_PORT" -uroot -p"$DB_PASSWORD" -e "SELECT 1;" >/dev/null 2>&1; then
|
||||
echo "✅ Database is ready!"
|
||||
break
|
||||
fi
|
||||
echo " Attempt $i/30: Database not ready, waiting 5 seconds..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# Check if site exists in persistent volume
|
||||
if [ -d "sites/$SITE_NAME" ]; then
|
||||
echo "✅ Site '$SITE_NAME' already exists, updating configuration"
|
||||
bench --site "$SITE_NAME" set-config db_host "$DB_HOST"
|
||||
bench --site "$SITE_NAME" set-config db_port "$DB_PORT"
|
||||
bench use "$SITE_NAME" || echo "Site already set as default"
|
||||
else
|
||||
echo "🏗️ Creating new site: $SITE_NAME"
|
||||
if bench new-site "$SITE_NAME" \
|
||||
--db-root-password "$DB_PASSWORD" \
|
||||
--admin-password "$ADMIN_PASSWORD" \
|
||||
--install-app erpnext \
|
||||
--set-default; then
|
||||
echo "✅ Site created successfully!"
|
||||
|
||||
# Install custom XML importer app
|
||||
echo "📦 Installing XML Importer app..."
|
||||
bench get-app --branch main erpnext_xml_importer https://github.com/UhrinDavid/erpnext_xml_importer.git || echo "⚠️ Failed to download XML importer"
|
||||
bench --site "$SITE_NAME" install-app erpnext_xml_importer || echo "⚠️ XML importer app installation failed"
|
||||
|
||||
bench --site "$SITE_NAME" set-config developer_mode 0
|
||||
bench --site "$SITE_NAME" set-config maintenance_mode 0
|
||||
echo "🎉 Site '$SITE_NAME' is ready with XML Importer!"
|
||||
else
|
||||
echo "❌ Failed to create site. Checking if it exists..."
|
||||
if [ -d "sites/$SITE_NAME" ]; then
|
||||
echo "⚠️ Site directory exists but creation failed. Using existing site."
|
||||
bench use "$SITE_NAME" || echo "Could not set as default"
|
||||
else
|
||||
echo "💥 Site creation failed completely. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure proper ownership of sites directory
|
||||
chown -R frappe:frappe sites/ || echo "Could not change ownership"
|
||||
chmod -R 755 sites/ || echo "Could not change permissions"
|
||||
|
||||
echo "✅ Site initialization completed successfully!"
|
||||
20
scripts/init-service.sh
Normal file
20
scripts/init-service.sh
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Simple service initialization for Frappe services
|
||||
# This script runs on services that don't need to create sites
|
||||
|
||||
set -e
|
||||
|
||||
SERVICE_NAME=${1:-"frappe-service"}
|
||||
|
||||
echo "🔧 Initializing $SERVICE_NAME..."
|
||||
cd /home/frappe/frappe-bench
|
||||
|
||||
# Basic configuration (site creation handled by backend service)
|
||||
if [ -f sites/common_site_config.json ] && [ -n "${FRAPPE_SITE_NAME_HEADER}" ]; then
|
||||
if [ -d "sites/${FRAPPE_SITE_NAME_HEADER}" ]; then
|
||||
bench use "${FRAPPE_SITE_NAME_HEADER}" || echo "Site will be set by backend"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ $SERVICE_NAME ready"
|
||||
99
scripts/init-site.sh
Normal file
99
scripts/init-site.sh
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Frappe Site Initialization Script for Zerops
|
||||
# This script runs on container start to ensure the site exists
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔧 Initializing Frappe site..."
|
||||
|
||||
# Configuration from environment variables
|
||||
SITE_NAME=${FRAPPE_SITE_NAME_HEADER:-"localhost"}
|
||||
DB_PASSWORD=${DB_PASSWORD:-"admin"}
|
||||
ADMIN_PASSWORD=${ADMIN_PASSWORD:-"admin"}
|
||||
DB_HOST=${DB_HOST:-"db"}
|
||||
DB_PORT=${DB_PORT:-"3306"}
|
||||
|
||||
echo "📋 Configuration:"
|
||||
echo " Site Name: $SITE_NAME"
|
||||
echo " Database Host: $DB_HOST:$DB_PORT"
|
||||
|
||||
# Navigate to frappe bench directory
|
||||
cd /home/frappe/frappe-bench
|
||||
|
||||
# Ensure sites directory exists and has proper permissions
|
||||
mkdir -p sites
|
||||
chown -R frappe:frappe sites || true
|
||||
|
||||
# Configure database and Redis connections
|
||||
echo "🔗 Configuring connections..."
|
||||
bench set-config -g db_host "$DB_HOST" || echo "DB host config already set"
|
||||
bench set-config -gp db_port "$DB_PORT" || echo "DB port config already set"
|
||||
bench set-config -g redis_cache "redis://${REDIS_CACHE}:6379" || echo "Redis cache config already set"
|
||||
bench set-config -g redis_queue "redis://${REDIS_QUEUE}:6379" || echo "Redis queue config already set"
|
||||
bench set-config -g redis_socketio "redis://${REDIS_QUEUE}:6379" || echo "Redis socketio config already set"
|
||||
bench set-config -gp socketio_port "${SOCKETIO_PORT}" || echo "Socketio port config already set"
|
||||
|
||||
# Wait for database to be ready
|
||||
echo "⏳ Waiting for database to be ready..."
|
||||
for i in {1..30}; do
|
||||
if mysql -h"$DB_HOST" -P"$DB_PORT" -uroot -p"$DB_PASSWORD" -e "SELECT 1;" >/dev/null 2>&1; then
|
||||
echo "✅ Database is ready!"
|
||||
break
|
||||
fi
|
||||
echo " Attempt $i/30: Database not ready, waiting 5 seconds..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# Check if site already exists in persistent volume
|
||||
if [ -d "sites/$SITE_NAME" ]; then
|
||||
echo "✅ Site '$SITE_NAME' already exists, skipping creation"
|
||||
|
||||
# Ensure site is in the current bench context
|
||||
if [ -f "sites/$SITE_NAME/site_config.json" ]; then
|
||||
echo "🔧 Updating site configuration..."
|
||||
bench --site "$SITE_NAME" set-config db_host "$DB_HOST"
|
||||
bench --site "$SITE_NAME" set-config db_port "$DB_PORT"
|
||||
bench use "$SITE_NAME" || echo "Site already set as default"
|
||||
fi
|
||||
else
|
||||
echo "🏗️ Creating new site: $SITE_NAME"
|
||||
|
||||
# Create the site with ERPNext
|
||||
if bench new-site "$SITE_NAME" \
|
||||
--db-root-password "$DB_PASSWORD" \
|
||||
--admin-password "$ADMIN_PASSWORD" \
|
||||
--install-app erpnext \
|
||||
--set-default; then
|
||||
|
||||
echo "✅ Site created successfully!"
|
||||
|
||||
# Additional site configuration
|
||||
bench --site "$SITE_NAME" set-config developer_mode 0
|
||||
bench --site "$SITE_NAME" set-config maintenance_mode 0
|
||||
|
||||
echo "🎉 Site '$SITE_NAME' is ready!"
|
||||
else
|
||||
echo "❌ Failed to create site. Checking if it exists..."
|
||||
if [ -d "sites/$SITE_NAME" ]; then
|
||||
echo "⚠️ Site directory exists but creation failed. Using existing site."
|
||||
bench use "$SITE_NAME" || echo "Could not set as default"
|
||||
else
|
||||
echo "💥 Site creation failed completely. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure proper ownership of sites directory
|
||||
chown -R frappe:frappe sites/ || echo "Could not change ownership"
|
||||
chmod -R 755 sites/ || echo "Could not change permissions"
|
||||
|
||||
# Final verification
|
||||
if [ -d "sites/$SITE_NAME" ]; then
|
||||
echo "✅ Site initialization completed successfully!"
|
||||
echo "🌐 Site '$SITE_NAME' is ready to serve traffic"
|
||||
else
|
||||
echo "❌ Site initialization failed!"
|
||||
exit 1
|
||||
fi
|
||||
75
scripts/setup-frappe.sh
Normal file
75
scripts/setup-frappe.sh
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Frappe/ERPNext Initial Setup Script for Zerops
|
||||
# This script should be run after the services are deployed and running
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Starting Frappe/ERPNext setup on Zerops..."
|
||||
|
||||
# Check if required environment variables are set
|
||||
if [ -z "$SITE_NAME" ]; then
|
||||
echo "❌ Error: SITE_NAME environment variable is required"
|
||||
echo " Set it to your domain name (e.g., mycompany.example.com)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$DB_PASSWORD" ]; then
|
||||
echo "❌ Error: DB_PASSWORD environment variable is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$ADMIN_PASSWORD" ]; then
|
||||
echo "❌ Error: ADMIN_PASSWORD environment variable is required"
|
||||
echo " This will be the password for the ERPNext admin user"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📋 Configuration:"
|
||||
echo " Site Name: $SITE_NAME"
|
||||
echo " Database Host: ${DB_HOST:-db}"
|
||||
echo " Admin Email: ${ADMIN_EMAIL:-administrator@$SITE_NAME}"
|
||||
|
||||
# Navigate to frappe bench directory
|
||||
cd /home/frappe/frappe-bench
|
||||
|
||||
echo "🏗️ Creating new site: $SITE_NAME"
|
||||
bench new-site "$SITE_NAME" \
|
||||
--db-root-password "$DB_PASSWORD" \
|
||||
--admin-password "$ADMIN_PASSWORD" \
|
||||
--set-default
|
||||
|
||||
echo "📦 Installing ERPNext application..."
|
||||
bench --site "$SITE_NAME" install-app erpnext
|
||||
|
||||
echo "👤 Setting up admin user..."
|
||||
if [ -n "$ADMIN_EMAIL" ]; then
|
||||
bench --site "$SITE_NAME" set-admin-password "$ADMIN_PASSWORD"
|
||||
fi
|
||||
|
||||
echo "🔧 Final configuration..."
|
||||
# Set site as default
|
||||
bench use "$SITE_NAME"
|
||||
|
||||
# Clear cache
|
||||
bench --site "$SITE_NAME" clear-cache
|
||||
|
||||
# Migrate database (in case there are any pending migrations)
|
||||
bench --site "$SITE_NAME" migrate
|
||||
|
||||
echo "✅ Setup completed successfully!"
|
||||
echo ""
|
||||
echo "🌐 Your ERPNext site is ready at: $SITE_NAME"
|
||||
echo "👤 Admin login: administrator"
|
||||
echo "🔑 Admin password: [as set in ADMIN_PASSWORD]"
|
||||
echo ""
|
||||
echo "📚 Next steps:"
|
||||
echo " 1. Configure your domain to point to this Zerops service"
|
||||
echo " 2. Access your site and complete the setup wizard"
|
||||
echo " 3. Configure SSL certificates if needed"
|
||||
echo ""
|
||||
echo "🔧 Useful commands:"
|
||||
echo " - bench restart: Restart all processes"
|
||||
echo " - bench --site $SITE_NAME console: Open Python console"
|
||||
echo " - bench --site $SITE_NAME migrate: Run database migrations"
|
||||
echo " - bench update: Update apps and migrate"
|
||||
71
zerops.env
Normal file
71
zerops.env
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# Production Environment Configuration for Zerops Deployment
|
||||
# Copy this file and customize the values for your deployment
|
||||
|
||||
# =============================================================================
|
||||
# REQUIRED ZEROPS SECRETS (set these in Zerops Dashboard > Environment Variables)
|
||||
# =============================================================================
|
||||
db_password=your-strong-database-password
|
||||
admin_password=your-admin-password
|
||||
site_name=your-domain.com
|
||||
|
||||
# =============================================================================
|
||||
# OPTIONAL CONFIGURATION (modify as needed)
|
||||
# =============================================================================
|
||||
ADMIN_EMAIL=admin@your-domain.com
|
||||
ERPNEXT_VERSION=v15.84.0
|
||||
|
||||
# Database Configuration (managed by Zerops)
|
||||
DB_HOST=db
|
||||
DB_PORT=3306
|
||||
|
||||
# Redis Configuration (managed by Zerops)
|
||||
REDIS_CACHE=redis-cache:6379
|
||||
REDIS_QUEUE=redis-queue:6379
|
||||
|
||||
# Application Configuration
|
||||
SOCKETIO_PORT=9000
|
||||
FRAPPE_SITE_NAME_HEADER=your-domain.com
|
||||
|
||||
# Nginx/Proxy Configuration
|
||||
UPSTREAM_REAL_IP_ADDRESS=127.0.0.1
|
||||
UPSTREAM_REAL_IP_HEADER=X-Forwarded-For
|
||||
UPSTREAM_REAL_IP_RECURSIVE=off
|
||||
PROXY_READ_TIMEOUT=120s
|
||||
CLIENT_MAX_BODY_SIZE=50m
|
||||
|
||||
# Frappe/ERPNext Image Configuration
|
||||
CUSTOM_IMAGE=frappe/erpnext
|
||||
CUSTOM_TAG=v15.84.0
|
||||
PULL_POLICY=always
|
||||
RESTART_POLICY=unless-stopped
|
||||
|
||||
# Backup Configuration (optional)
|
||||
# BACKUP_S3_BUCKET=your-backup-bucket
|
||||
# BACKUP_S3_ACCESS_KEY=your-access-key
|
||||
# BACKUP_S3_SECRET_KEY=your-secret-key
|
||||
# BACKUP_S3_REGION=your-region
|
||||
|
||||
# Email Configuration (optional)
|
||||
# MAIL_SERVER=smtp.your-email-provider.com
|
||||
# MAIL_PORT=587
|
||||
# MAIL_USERNAME=your-email@domain.com
|
||||
# MAIL_PASSWORD=your-email-password
|
||||
# MAIL_USE_TLS=true
|
||||
|
||||
# SSL/TLS Configuration (optional, if not using Zerops automatic SSL)
|
||||
# LETSENCRYPT_EMAIL=your-email@domain.com
|
||||
# SITES=your-domain.com
|
||||
|
||||
# =============================================================================
|
||||
# DEPLOYMENT INSTRUCTIONS
|
||||
# =============================================================================
|
||||
# 1. Set the 3 required secrets in Zerops Dashboard:
|
||||
# - db_password: Strong password for MariaDB (min 8 chars)
|
||||
# - admin_password: Password for ERPNext admin user (min 8 chars)
|
||||
# - site_name: Your domain name (e.g., mycompany.example.com)
|
||||
#
|
||||
# 2. Deploy using zerops.yml file
|
||||
#
|
||||
# 3. Access your ERPNext site at the domain specified in site_name
|
||||
# - Username: administrator
|
||||
# - Password: [value from admin_password secret]
|
||||
291
zerops.yml
Normal file
291
zerops.yml
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
# Zerops YAML configuration for Frappe/ERPNext deployment
|
||||
# This file defines the infrastructure and deployment settings for Zerops platform
|
||||
# Documentation: https://docs.zerops.io/
|
||||
|
||||
# Import this file in Zerops GUI to create the project with all required services
|
||||
|
||||
project:
|
||||
name: frappe-erpnext
|
||||
|
||||
services:
|
||||
# MariaDB Database Service
|
||||
- hostname: db
|
||||
type: mariadb
|
||||
version: "11"
|
||||
mode: HA
|
||||
priority: 10
|
||||
# Zerops will automatically configure MariaDB with UTF8MB4
|
||||
|
||||
# Redis Cache Service
|
||||
- hostname: redis-cache
|
||||
type: redis
|
||||
version: "6"
|
||||
mode: HA
|
||||
priority: 10
|
||||
|
||||
# Redis Queue Service
|
||||
- hostname: redis-queue
|
||||
type: redis
|
||||
version: "6"
|
||||
mode: HA
|
||||
priority: 10
|
||||
|
||||
# Main Backend Application (Frappe/ERPNext)
|
||||
- hostname: backend
|
||||
type: python
|
||||
version: "3.11"
|
||||
buildFromGit: https://github.com/UhrinDavid/frappe_docker@zerops
|
||||
enableSubdomainAccess: false
|
||||
minContainers: 1
|
||||
maxContainers: 3
|
||||
autoscaling:
|
||||
cpuThreshold: 70
|
||||
memoryThreshold: 80
|
||||
# Environment variables
|
||||
envSecrets:
|
||||
DB_PASSWORD: ${db_password}
|
||||
ADMIN_PASSWORD: ${admin_password}
|
||||
ERPNEXT_VERSION: v15.84.0
|
||||
DB_HOST: db
|
||||
DB_PORT: 3306
|
||||
REDIS_CACHE: redis-cache
|
||||
REDIS_QUEUE: redis-queue
|
||||
SOCKETIO_PORT: 9000
|
||||
FRAPPE_SITE_NAME_HEADER: ${site_name}
|
||||
CUSTOM_IMAGE: frappe/erpnext
|
||||
CUSTOM_TAG: ${ERPNEXT_VERSION}
|
||||
# Persistent volumes for site data
|
||||
volumes:
|
||||
- name: frappe-sites
|
||||
mountPath: /home/frappe/frappe-bench/sites
|
||||
size: 20GB
|
||||
- name: frappe-logs
|
||||
mountPath: /home/frappe/frappe-bench/logs
|
||||
size: 5GB
|
||||
# Build settings using production Dockerfile
|
||||
build:
|
||||
dockerfile: ./images/production/Containerfile
|
||||
context: .
|
||||
# Build-time commands to include site and apps in image
|
||||
buildCommands:
|
||||
- |
|
||||
# Install any additional apps during build
|
||||
# Example: bench get-app --branch main custom_app https://github.com/user/custom_app
|
||||
echo "Building Frappe image with pre-installed apps..."
|
||||
# Runtime initialization - deployment specific
|
||||
runPrepareCommands:
|
||||
- |
|
||||
# Copy and execute the site initialization script
|
||||
cp scripts/init-frappe-site.sh /home/frappe/init-frappe-site.sh
|
||||
chmod +x /home/frappe/init-frappe-site.sh
|
||||
chown frappe:frappe /home/frappe/init-frappe-site.sh
|
||||
|
||||
# Run the initialization script as frappe user
|
||||
su - frappe -c "/home/frappe/init-frappe-site.sh"
|
||||
# Health check
|
||||
healthCheck:
|
||||
httpGet:
|
||||
port: 8000
|
||||
path: /api/method/ping
|
||||
initialDelaySeconds: 120
|
||||
periodSeconds: 30
|
||||
|
||||
# Frontend/Nginx Proxy Service
|
||||
- hostname: frontend
|
||||
type: nginx
|
||||
version: "1.24"
|
||||
enableSubdomainAccess: true
|
||||
minContainers: 1
|
||||
maxContainers: 2
|
||||
buildFromGit: https://github.com/UhrinDavid/frappe_docker@zerops
|
||||
# Environment variables for nginx templating
|
||||
envSecrets:
|
||||
BACKEND: backend:8000
|
||||
SOCKETIO: websocket:9000
|
||||
FRAPPE_SITE_NAME_HEADER: ${site_name}
|
||||
UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1
|
||||
UPSTREAM_REAL_IP_HEADER: X-Forwarded-For
|
||||
UPSTREAM_REAL_IP_RECURSIVE: "off"
|
||||
PROXY_READ_TIMEOUT: 120s
|
||||
CLIENT_MAX_BODY_SIZE: 50m
|
||||
# Build nginx with custom configuration
|
||||
build:
|
||||
dockerfile: ./images/production/Containerfile
|
||||
context: .
|
||||
# Use the nginx configuration from the frappe image
|
||||
runPrepareCommands:
|
||||
- cp /opt/frappe/nginx-template.conf /etc/nginx/conf.d/default.conf.template
|
||||
- envsubst '$BACKEND $SOCKETIO $FRAPPE_SITE_NAME_HEADER' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
|
||||
# Command to run nginx
|
||||
start: nginx-entrypoint.sh
|
||||
# Health check
|
||||
healthCheck:
|
||||
httpGet:
|
||||
port: 8080
|
||||
path: /api/method/ping
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
|
||||
# WebSocket Service
|
||||
- hostname: websocket
|
||||
type: nodejs
|
||||
version: "18"
|
||||
buildFromGit: https://github.com/UhrinDavid/frappe_docker@zerops
|
||||
enableSubdomainAccess: false
|
||||
minContainers: 1
|
||||
maxContainers: 2
|
||||
# Shared persistent volumes for site access
|
||||
volumes:
|
||||
- name: frappe-sites
|
||||
mountPath: /home/frappe/frappe-bench/sites
|
||||
size: 20GB
|
||||
# Environment variables
|
||||
envSecrets:
|
||||
DB_HOST: db
|
||||
DB_PORT: 3306
|
||||
REDIS_CACHE: redis-cache
|
||||
REDIS_QUEUE: redis-queue
|
||||
SOCKETIO_PORT: 9000
|
||||
build:
|
||||
dockerfile: ./images/production/Containerfile
|
||||
context: .
|
||||
runPrepareCommands:
|
||||
- |
|
||||
# Copy and execute the service initialization script
|
||||
cp scripts/init-service.sh /home/frappe/init-service.sh
|
||||
chmod +x /home/frappe/init-service.sh
|
||||
chown frappe:frappe /home/frappe/init-service.sh
|
||||
|
||||
# Run the initialization script as frappe user
|
||||
su - frappe -c "/home/frappe/init-service.sh WebSocket"
|
||||
# Command to run the WebSocket server
|
||||
start: node /home/frappe/frappe-bench/apps/frappe/socketio.js
|
||||
# Health check
|
||||
healthCheck:
|
||||
httpGet:
|
||||
port: 9000
|
||||
path: /socket.io/
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 30
|
||||
|
||||
# Queue Worker - Short Tasks
|
||||
- hostname: queue-short
|
||||
type: python
|
||||
version: "3.11"
|
||||
buildFromGit: https://github.com/UhrinDavid/frappe_docker@zerops
|
||||
enableSubdomainAccess: false
|
||||
minContainers: 1
|
||||
maxContainers: 3
|
||||
# Shared persistent volumes for site access
|
||||
volumes:
|
||||
- name: frappe-sites
|
||||
mountPath: /home/frappe/frappe-bench/sites
|
||||
size: 20GB
|
||||
# Environment variables
|
||||
envSecrets:
|
||||
DB_HOST: db
|
||||
DB_PORT: 3306
|
||||
REDIS_CACHE: redis-cache
|
||||
REDIS_QUEUE: redis-queue
|
||||
build:
|
||||
dockerfile: ./images/production/Containerfile
|
||||
context: .
|
||||
runPrepareCommands:
|
||||
- |
|
||||
# Copy and execute the service initialization script
|
||||
cp scripts/init-service.sh /home/frappe/init-service.sh
|
||||
chmod +x /home/frappe/init-service.sh
|
||||
chown frappe:frappe /home/frappe/init-service.sh
|
||||
|
||||
# Run the initialization script as frappe user
|
||||
su - frappe -c "/home/frappe/init-service.sh 'Queue Worker (Short)'"
|
||||
# Command to run the worker
|
||||
start: bench worker --queue short,default
|
||||
|
||||
# Queue Worker - Long Tasks
|
||||
- hostname: queue-long
|
||||
type: python
|
||||
version: "3.11"
|
||||
buildFromGit: https://github.com/UhrinDavid/frappe_docker@zerops
|
||||
enableSubdomainAccess: false
|
||||
minContainers: 1
|
||||
maxContainers: 2
|
||||
# Shared persistent volumes for site access
|
||||
volumes:
|
||||
- name: frappe-sites
|
||||
mountPath: /home/frappe/frappe-bench/sites
|
||||
size: 20GB
|
||||
# Environment variables
|
||||
envSecrets:
|
||||
DB_HOST: db
|
||||
DB_PORT: 3306
|
||||
REDIS_CACHE: redis-cache
|
||||
REDIS_QUEUE: redis-queue
|
||||
build:
|
||||
dockerfile: ./images/production/Containerfile
|
||||
context: .
|
||||
runPrepareCommands:
|
||||
- |
|
||||
# Copy and execute the service initialization script
|
||||
cp scripts/init-service.sh /home/frappe/init-service.sh
|
||||
chmod +x /home/frappe/init-service.sh
|
||||
chown frappe:frappe /home/frappe/init-service.sh
|
||||
|
||||
# Run the initialization script as frappe user
|
||||
su - frappe -c "/home/frappe/init-service.sh 'Queue Worker (Long)'"
|
||||
# Command to run the long queue worker
|
||||
start: bench worker --queue long,default,short
|
||||
|
||||
# Scheduler Service
|
||||
- hostname: scheduler
|
||||
type: python
|
||||
version: "3.11"
|
||||
buildFromGit: https://github.com/UhrinDavid/frappe_docker@zerops
|
||||
enableSubdomainAccess: false
|
||||
minContainers: 1
|
||||
maxContainers: 1
|
||||
# Shared persistent volumes for site access
|
||||
volumes:
|
||||
- name: frappe-sites
|
||||
mountPath: /home/frappe/frappe-bench/sites
|
||||
size: 20GB
|
||||
# Environment variables
|
||||
envSecrets:
|
||||
DB_HOST: db
|
||||
DB_PORT: 3306
|
||||
REDIS_CACHE: redis-cache
|
||||
REDIS_QUEUE: redis-queue
|
||||
build:
|
||||
dockerfile: ./images/production/Containerfile
|
||||
context: .
|
||||
runPrepareCommands:
|
||||
- |
|
||||
# Copy and execute the service initialization script
|
||||
cp scripts/init-service.sh /home/frappe/init-service.sh
|
||||
chmod +x /home/frappe/init-service.sh
|
||||
chown frappe:frappe /home/frappe/init-service.sh
|
||||
|
||||
# Run the initialization script as frappe user
|
||||
su - frappe -c "/home/frappe/init-service.sh Scheduler"
|
||||
# Command to run the scheduler
|
||||
start: bench schedule
|
||||
|
||||
# Required secrets that need to be set in Zerops dashboard:
|
||||
# - db_password: Database password for MariaDB (e.g., "mySecureDbPassword123")
|
||||
# - admin_password: ERPNext admin user password (e.g., "myAdminPassword123")
|
||||
# - site_name: Your site domain name (e.g., "mycompany.example.com")
|
||||
#
|
||||
# This configuration includes:
|
||||
# ✅ Clean Docker image with ERPNext apps (deployment-agnostic)
|
||||
# ✅ Persistent volumes for site data, uploads, and configurations
|
||||
# ✅ Deployment-specific initialization via runPrepareCommands
|
||||
# ✅ Shared volumes across all services that need site access
|
||||
#
|
||||
# Benefits:
|
||||
# - Docker image is reusable across different deployment platforms
|
||||
# - Site initialization is handled at deployment time (not in image)
|
||||
# - Container restarts preserve all site data and configurations
|
||||
# - Apps are consistently deployed across all containers
|
||||
# - No manual setup required after deployment
|
||||
# - Fast container startup times
|
||||
# - Proper separation between image and deployment concerns
|
||||
Loading…
Reference in a new issue