Keywords: Jenkins | Permission Issues | React Build
Abstract: This article provides an in-depth analysis of the 'react-scripts: Permission denied' error encountered when deploying React applications on Ubuntu systems using Jenkins. By examining user permission conflicts, file ownership issues, and environment configuration, it offers a comprehensive technical pathway from root causes to solutions. Based on real-world cases and best practices, the article demonstrates how to achieve stable builds through sudoers configuration, file permission adjustments, and Pipeline scripting, while discussing supplementary measures like memory optimization.
Problem Background and Error Analysis
When deploying Spring-Boot/React applications across platforms, particularly migrating from Windows 10 to Ubuntu 18.04, developers often encounter permission-related build failures. As shown in the case, users repeatedly face the react-scripts: Permission denied error when executing npm run build, even after recursively setting permissions to 777 for node_modules and .nvm directories. The error message indicates exit status 126, suggesting the shell cannot execute the specified command, typically due to insufficient file permissions or mismatched user contexts.
Core Issue: User Permission Conflicts
The root cause lies in the Jenkins service running build tasks under the jenkins user, while project files may be created or modified by the root user. Even with file permissions set to 777 (readable, writable, and executable by all users), the system may still deny execution due to inconsistent ownership. For instance, if the react-scripts binary in node_modules/.bin/ is owned by root and Jenkins attempts to execute it as jenkins, a permission error is triggered. This explains why the problem persists after manual chmod -R 777 commands.
Solution: System-Level Permission Adjustment
Based on best practices, first modify the /etc/sudoers file to grant passwordless sudo privileges to the jenkins user. By executing sudo visudo and adding the line: jenkins ALL=(ALL) NOPASSWD:ALL. This allows Jenkins to execute privileged commands during builds without interactive passwords, though security risks should be noted, and permission scopes limited in production environments.
Implementation: Jenkins Pipeline Script Optimization
Adopt Jenkins Pipeline instead of Freestyle projects for greater script control. Below is a corrected Pipeline script example integrating permission fixes:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
echo 'Checkout...'
sh 'sudo chmod -R 777 /var/lib/jenkins/workspace/MedAverter/medaverter-front'
checkout scm
sh 'sudo chmod -R 777 /var/lib/jenkins/workspace/MedAverter/medaverter-front'
sh 'sudo chown -R jenkins /var/lib/jenkins/workspace/MedAverter/medaverter-front'
stash 'sources'
}
}
stage('Build') {
steps {
echo 'Build...'
unstash 'sources'
sh 'sudo chmod -R 777 /var/lib/jenkins/workspace/MedAverter/medaverter-front'
sh 'sudo chown -R jenkins /var/lib/jenkins/workspace/MedAverter/medaverter-front'
sh 'mvn clean package -DskipTests'
stash 'sources'
}
}
}
}
This script recursively modifies project directory permissions and ownership before and after code checkout, ensuring the jenkins user has full control. Key commands include chmod -R 777 to set full permissions and chown -R jenkins to change ownership, thereby eliminating user context conflicts.
Supplementary Measures and Optimization Suggestions
After resolving permission issues, dependency errors such as missing jest-worker may need addressing. Install required packages via yarn add jest-worker or npm install jest-worker --save. Additionally, insufficient memory can cause build failures, as seen when upgrading DigitalOcean instance memory from 1GB to 2GB. Monitor system resources using free -m, and configure Node.js memory limits in package.json, e.g., adding "scripts": { "build": "node --max-old-space-size=2048 react-scripts build" }.
Alternative Approaches and In-Depth Discussion
Other answers provide supplementary methods: installing react-scripts as a project dependency (npm install react-scripts --save) ensures local availability; directly adding execute permissions to the react-scripts binary (chmod +x node_modules/.bin/react-scripts) targets file-level issues; using sudo npm run build temporarily elevates privileges but may introduce security risks. These serve as quick fixes but do not address the fundamental ownership problem.
Conclusion and Best Practices
Resolving the react-scripts: Permission denied error requires integrating system configuration, file permissions, and CI/CD workflows. Key steps include ensuring Jenkins user has appropriate sudo privileges, incorporating permission fixes in Pipeline scripts, and monitoring resource usage. Avoid over-reliance on chmod 777; instead, use chown to correctly set ownership. For production environments, consider Docker containerization to isolate user contexts and permissions, enhancing security and consistency.