Complete Node.js container implementation with multi-version support
- Add Dockerfile with AlmaLinux 9 base, Nginx reverse proxy, and PM2 - Support Node.js versions 18, 20, 22 with automated installation - Implement memory-optimized configuration (256MB minimum, 512MB recommended) - Add Memcached session storage for development environments - Create comprehensive documentation (README, USER-GUIDE, MEMORY-GUIDE, CLAUDE.md) - Include example applications (simple website and REST API) - Add Gitea CI/CD pipeline for automated multi-version builds - Provide local development script with helper utilities - Implement health monitoring, log rotation, and backup systems 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
275
USER-GUIDE.md
Normal file
275
USER-GUIDE.md
Normal file
@@ -0,0 +1,275 @@
|
||||
# User Guide: Deploying Applications with Cloud Node Container
|
||||
|
||||
## Quick Start (For Non-Node.js Users)
|
||||
|
||||
If you've never used Node.js before, don't worry! This container makes it simple.
|
||||
|
||||
### What You Need to Know
|
||||
|
||||
**Node.js** is like PHP, but for JavaScript. Instead of Apache serving PHP files, your JavaScript code runs as a server application.
|
||||
|
||||
**Express.js** is like a web framework (similar to Laravel for PHP) that makes it easy to handle web requests.
|
||||
|
||||
### Basic Workflow Comparison
|
||||
|
||||
| PHP/Apache Workflow | Node.js Container Workflow |
|
||||
|---------------------|---------------------------|
|
||||
| Put `.php` files in web directory | Put `.js` files in `user/app/` |
|
||||
| Apache serves files directly | Express.js handles requests |
|
||||
| Database connection in each file | Server runs continuously |
|
||||
| `<?php echo "Hello"; ?>` | `res.send("Hello")` |
|
||||
|
||||
## Step-by-Step: Deploy Your First App
|
||||
|
||||
### 1. Create Your Application Files
|
||||
|
||||
Create these two files in your `user/app/` directory:
|
||||
|
||||
**File: `package.json`**
|
||||
```json
|
||||
{
|
||||
"name": "my-first-app",
|
||||
"version": "1.0.0",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**File: `server.js`**
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const port = process.env.PORT || 3000;
|
||||
|
||||
// Serve static files (HTML, CSS, images) from 'public' folder
|
||||
app.use(express.static('public'));
|
||||
|
||||
// Route for home page
|
||||
app.get('/', (req, res) => {
|
||||
res.send(`
|
||||
<h1>Welcome to My Website!</h1>
|
||||
<p>This is running on Node.js</p>
|
||||
<a href="/about">About Page</a>
|
||||
`);
|
||||
});
|
||||
|
||||
// Route for about page
|
||||
app.get('/about', (req, res) => {
|
||||
res.send(`
|
||||
<h1>About Us</h1>
|
||||
<p>This website is powered by Node.js and Express</p>
|
||||
<a href="/">Back to Home</a>
|
||||
`);
|
||||
});
|
||||
|
||||
// Health check (required by container)
|
||||
app.get('/ping', (req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date() });
|
||||
});
|
||||
|
||||
// Start the server
|
||||
app.listen(port, () => {
|
||||
console.log(`Server running on port ${port}`);
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Start Your Container
|
||||
|
||||
```bash
|
||||
./local-dev.sh -n my-first-app
|
||||
```
|
||||
|
||||
### 3. Access Your Site
|
||||
|
||||
Visit `https://localhost` (accept the SSL warning) and you'll see your website!
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
### Static Website (Like HTML/CSS sites)
|
||||
|
||||
Put your HTML files in `user/app/public/` and use this simple server:
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
app.use(express.static('public'));
|
||||
app.get('/ping', (req, res) => res.json({ status: 'ok' }));
|
||||
|
||||
app.listen(3000, () => console.log('Static site running'));
|
||||
```
|
||||
|
||||
### Form Processing (Like PHP forms)
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
app.use(express.urlencoded({ extended: true })); // Process form data
|
||||
app.use(express.static('public'));
|
||||
|
||||
// Show contact form
|
||||
app.get('/contact', (req, res) => {
|
||||
res.send(`
|
||||
<form method="POST" action="/contact">
|
||||
<input name="name" placeholder="Your Name" required>
|
||||
<input name="email" type="email" placeholder="Email" required>
|
||||
<textarea name="message" placeholder="Message" required></textarea>
|
||||
<button type="submit">Send</button>
|
||||
</form>
|
||||
`);
|
||||
});
|
||||
|
||||
// Process form submission
|
||||
app.post('/contact', (req, res) => {
|
||||
const { name, email, message } = req.body;
|
||||
|
||||
// Here you would save to database, send email, etc.
|
||||
console.log('Contact form:', { name, email, message });
|
||||
|
||||
res.send(`<h1>Thanks ${name}!</h1><p>We received your message.</p>`);
|
||||
});
|
||||
|
||||
app.get('/ping', (req, res) => res.json({ status: 'ok' }));
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
### Database Connection (Like MySQL in PHP)
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
// In package.json dependencies, add: "mysql2": "^3.6.0"
|
||||
const mysql = require('mysql2');
|
||||
|
||||
const db = mysql.createConnection({
|
||||
host: 'localhost',
|
||||
user: 'your_user',
|
||||
password: 'your_password',
|
||||
database: 'your_database'
|
||||
});
|
||||
|
||||
app.get('/users', (req, res) => {
|
||||
db.query('SELECT * FROM users', (err, results) => {
|
||||
if (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
} else {
|
||||
res.json(results);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/ping', (req, res) => res.json({ status: 'ok' }));
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
## File Structure Examples
|
||||
|
||||
### Simple Website
|
||||
```
|
||||
user/app/
|
||||
├── package.json
|
||||
├── server.js
|
||||
└── public/
|
||||
├── index.html
|
||||
├── about.html
|
||||
├── style.css
|
||||
└── images/
|
||||
└── logo.png
|
||||
```
|
||||
|
||||
### API Application
|
||||
```
|
||||
user/app/
|
||||
├── package.json
|
||||
├── server.js
|
||||
├── routes/
|
||||
│ ├── users.js
|
||||
│ └── products.js
|
||||
└── public/
|
||||
└── api-docs.html
|
||||
```
|
||||
|
||||
## Key Differences from PHP
|
||||
|
||||
| Concept | PHP | Node.js |
|
||||
|---------|-----|---------|
|
||||
| **File serving** | Apache serves .php files directly | Express routes handle requests |
|
||||
| **Variables** | `$variable` | `let variable` |
|
||||
| **Arrays** | `$arr = array()` | `let arr = []` |
|
||||
| **Echo/Print** | `echo "Hello"` | `res.send("Hello")` |
|
||||
| **Include files** | `include 'file.php'` | `require('./file.js')` |
|
||||
| **Database** | Connect in each file | Connect once, reuse connection |
|
||||
| **Sessions** | `$_SESSION` | `req.session` (with middleware) |
|
||||
| **Forms** | `$_POST` | `req.body` (with middleware) |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues for PHP Users
|
||||
|
||||
**Issue:** "Cannot GET /" error
|
||||
**Solution:** Make sure you have an `app.get('/', ...)` route defined
|
||||
|
||||
**Issue:** Static files (CSS/images) not loading
|
||||
**Solution:** Put them in `public/` folder and add `app.use(express.static('public'))`
|
||||
|
||||
**Issue:** Forms not working
|
||||
**Solution:** Add `app.use(express.urlencoded({ extended: true }))` before your routes
|
||||
|
||||
**Issue:** App crashes on restart
|
||||
**Solution:** PM2 will automatically restart it, but check logs in `user/logs/nodejs/`
|
||||
|
||||
### Getting Help
|
||||
|
||||
- Check container logs: `./instance_logs`
|
||||
- Check your app specifically: `docker exec -it your-container-name pm2 logs`
|
||||
- Access container shell: `./instance_shell`
|
||||
- Health check: Visit `/ping` to see if your app is responding
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Using Sessions (like PHP $_SESSION)
|
||||
|
||||
```javascript
|
||||
// Add to package.json dependencies: "express-session": "^1.17.3"
|
||||
const session = require('express-session');
|
||||
|
||||
app.use(session({
|
||||
secret: 'your-secret-key',
|
||||
resave: false,
|
||||
saveUninitialized: false
|
||||
}));
|
||||
|
||||
app.get('/login', (req, res) => {
|
||||
req.session.user = 'john_doe';
|
||||
res.send('Logged in!');
|
||||
});
|
||||
|
||||
app.get('/profile', (req, res) => {
|
||||
if (req.session.user) {
|
||||
res.send(`Hello ${req.session.user}!`);
|
||||
} else {
|
||||
res.send('Please log in');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### File Uploads
|
||||
|
||||
```javascript
|
||||
// Add to package.json: "multer": "^1.4.5-lts.1"
|
||||
const multer = require('multer');
|
||||
const upload = multer({ dest: 'uploads/' });
|
||||
|
||||
app.post('/upload', upload.single('file'), (req, res) => {
|
||||
res.send(`File uploaded: ${req.file.originalname}`);
|
||||
});
|
||||
```
|
||||
|
||||
The container handles all the complex server setup, so you can focus on building your application!
|
Reference in New Issue
Block a user