feat: Add complete nginx static site example with deployment, service, and documentation
This commit is contained in:
@@ -15,13 +15,14 @@ Comprehensive progression of Kubernetes examples designed to teach MyceliumCloud
|
|||||||
|
|
||||||
### Planned Examples (In Progress)
|
### Planned Examples (In Progress)
|
||||||
|
|
||||||
#### 2. Nginx Static Site 🔄
|
#### 2. Nginx Static Site ✅
|
||||||
- **Difficulty**: ⭐ Easy
|
- **Difficulty**: ⭐ Easy
|
||||||
- **Status**: 🔄 **NEXT UP**
|
- **Status**: ✅ **COMPLETED**
|
||||||
- **Learning Focus**: Static content serving, custom HTML, nginx configuration
|
- **Learning Focus**: Static content serving, custom HTML, nginx configuration
|
||||||
- **Template**: Same efficient pattern as hello-world
|
- **Template**: Same efficient pattern as hello-world
|
||||||
- **Key Concepts**: Static files, nginx deployment, custom configuration
|
- **Key Concepts**: Static files, nginx deployment, custom configuration, ConfigMaps
|
||||||
- **Next Step**: Copy hello-world template, adapt for nginx
|
- **Result**: Tested and working on MyceliumCloud cluster
|
||||||
|
- **Next Step**: Move to Python Flask API example
|
||||||
|
|
||||||
### Planned Examples (Future)
|
### Planned Examples (Future)
|
||||||
|
|
||||||
|
|||||||
48
examples/nginx-static/default-index.html
Normal file
48
examples/nginx-static/default-index.html
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Nginx Static Site</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 40px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
padding: 50px;
|
||||||
|
background: rgba(255,255,255,0.1);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
font-size: 3em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="logo">Kubernetes Example</div>
|
||||||
|
<h1>Nginx Static Site</h1>
|
||||||
|
<p>Welcome to your custom static website on Mycelium Cloud!</p>
|
||||||
|
<p>This site is served by Nginx in a Kubernetes pod.</p>
|
||||||
|
<p><strong>Deployment:</strong> nginx-static</p>
|
||||||
|
<p><strong>Time:</strong> <span id="time"></span></p>
|
||||||
|
<p style="margin-top: 30px; font-size: 0.9em; opacity: 0.8;">
|
||||||
|
Deploying static sites on Mycelium Cloud is easy!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function updateTime() {
|
||||||
|
document.getElementById('time').textContent = new Date().toLocaleString();
|
||||||
|
}
|
||||||
|
setInterval(updateTime, 1000);
|
||||||
|
updateTime();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
26
examples/nginx-static/nginx-static-deployment.yaml
Normal file
26
examples/nginx-static/nginx-static-deployment.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nginx-static
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: nginx-static
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx-static
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx-static
|
||||||
|
image: nginx:alpine
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
volumeMounts:
|
||||||
|
- name: nginx-content
|
||||||
|
mountPath: /usr/share/nginx/html
|
||||||
|
volumes:
|
||||||
|
- name: nginx-content
|
||||||
|
configMap:
|
||||||
|
name: nginx-static-content
|
||||||
11
examples/nginx-static/nginx-static-service.yaml
Normal file
11
examples/nginx-static/nginx-static-service.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: nginx-static-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: nginx-static
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
type: LoadBalancer
|
||||||
288
examples/nginx-static/nginx-static.md
Normal file
288
examples/nginx-static/nginx-static.md
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
# Mycelium Cloud - Nginx Static Site Example
|
||||||
|
|
||||||
|
A complete, standalone example for deploying a static website using Nginx on Mycelium Cloud Kubernetes cluster.
|
||||||
|
|
||||||
|
## 📁 What This Contains
|
||||||
|
|
||||||
|
This directory contains everything you need to deploy a static website:
|
||||||
|
|
||||||
|
- **nginx-static.md** - This guide
|
||||||
|
- **nginx-static-deployment.yaml** - Nginx deployment with custom content
|
||||||
|
- **nginx-static-service.yaml** - Service configuration
|
||||||
|
- **default-index.html** - Default website content (used to create ConfigMap)
|
||||||
|
|
||||||
|
## 🚀 Quick Start (2 minutes)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Deploy the application
|
||||||
|
kubectl apply -f nginx-static-deployment.yaml
|
||||||
|
|
||||||
|
# 2. Create ConfigMap with default content
|
||||||
|
kubectl create configmap nginx-static-content --from-file=index.html=default-index.html
|
||||||
|
|
||||||
|
# 3. Create the service
|
||||||
|
kubectl apply -f nginx-static-service.yaml
|
||||||
|
|
||||||
|
# 3. Access your static site via port-forward
|
||||||
|
|
||||||
|
**Option 1: Simple (Recommended)**
|
||||||
|
```bash
|
||||||
|
# Keep terminal open, see connection logs (Ctrl+C to stop)
|
||||||
|
kubectl port-forward service/nginx-static-service 8080:80
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 2: Advanced (Background)**
|
||||||
|
```bash
|
||||||
|
# Start in background
|
||||||
|
nohup kubectl port-forward service/nginx-static-service 8080:80 > /dev/null 2>&1 &
|
||||||
|
|
||||||
|
# Kill when done
|
||||||
|
lsof -ti:8080 | xargs kill -9
|
||||||
|
```
|
||||||
|
|
||||||
|
# 4. Visit http://localhost:8080
|
||||||
|
curl http://localhost:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Result:** You'll see a custom static website served by Nginx.
|
||||||
|
|
||||||
|
## 📋 What You'll Learn
|
||||||
|
|
||||||
|
- ✅ Nginx container deployment
|
||||||
|
- ✅ Static content serving
|
||||||
|
- ✅ ConfigMap usage for custom HTML
|
||||||
|
- ✅ Service creation and networking
|
||||||
|
- ✅ Port-forwarding for external access (Mycelium Cloud method)
|
||||||
|
- ✅ Basic nginx configuration patterns
|
||||||
|
|
||||||
|
## 🏗️ Architecture
|
||||||
|
|
||||||
|
This example demonstrates:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||||
|
│ User │ │ Port-Forward │ │ Nginx │
|
||||||
|
│ (Browser) │────│ localhost:8080 │────│ Pod │
|
||||||
|
│ │ │ │ │ :80 │
|
||||||
|
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||||
|
│
|
||||||
|
┌───────────────┐
|
||||||
|
│ ConfigMap │
|
||||||
|
│ (HTML/CSS) │
|
||||||
|
└───────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**Components:**
|
||||||
|
- **Nginx Pod**: Serves static content from /usr/share/nginx/html
|
||||||
|
- **ConfigMap**: Stores custom HTML, CSS, and other static files
|
||||||
|
- **Service**: LoadBalancer exposing the nginx pod
|
||||||
|
- **Port-Forward**: Mycelium Cloud method for external access
|
||||||
|
|
||||||
|
## 📊 Resource Details
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Expected output
|
||||||
|
kubectl get pods
|
||||||
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
nginx-static-xxxxxx-xxxxx 1/1 Running 0 2m
|
||||||
|
|
||||||
|
kubectl get svc
|
||||||
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
|
||||||
|
nginx-static-service LoadBalancer 10.43.xx.x 10.20.x.x,10.20.x.x 80:xxxxx/TCP
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Customization Guide
|
||||||
|
|
||||||
|
### Change the Content
|
||||||
|
|
||||||
|
Create a custom ConfigMap with your content:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create your custom HTML file
|
||||||
|
cat << EOF > custom-index.html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>My Custom Site</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: Arial, sans-serif; margin: 40px; }
|
||||||
|
.container { max-width: 800px; margin: 0 auto; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Welcome to My Static Site</h1>
|
||||||
|
<p>This site is running on Mycelium Cloud!</p>
|
||||||
|
<p>Current time: $(date)</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create ConfigMap with custom content
|
||||||
|
kubectl create configmap nginx-static-content \
|
||||||
|
--from-file=index.html=custom-index.html
|
||||||
|
|
||||||
|
# Update deployment to use the new ConfigMap
|
||||||
|
kubectl apply -f nginx-static-deployment.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add More Static Files
|
||||||
|
|
||||||
|
Create additional ConfigMaps for CSS, JavaScript, or images:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Add a stylesheet
|
||||||
|
cat << EOF > custom.css
|
||||||
|
body {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
h1 { text-align: center; margin-top: 100px; }
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create ConfigMap with multiple files
|
||||||
|
kubectl create configmap nginx-static-content \
|
||||||
|
--from-file=index.html=custom-index.html \
|
||||||
|
--from-file=styles.css=custom.css
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚪 Access Methods
|
||||||
|
|
||||||
|
### Method 1: Port-Forward (Recommended for Mycelium Cloud)
|
||||||
|
|
||||||
|
**Option 1: Simple (Recommended)**
|
||||||
|
```bash
|
||||||
|
# Keep terminal open, see connection logs (Ctrl+C to stop)
|
||||||
|
kubectl port-forward service/nginx-static-service 8080:80
|
||||||
|
|
||||||
|
# Access via browser or curl
|
||||||
|
curl http://localhost:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 2: Advanced (Background)**
|
||||||
|
```bash
|
||||||
|
# Start in background
|
||||||
|
nohup kubectl port-forward service/nginx-static-service 8080:80 > /dev/null 2>&1 &
|
||||||
|
|
||||||
|
# Access via browser or curl
|
||||||
|
curl http://localhost:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why this works in Mycelium Cloud:**
|
||||||
|
- LoadBalancer external IPs are internal cluster addresses
|
||||||
|
- Port-forward creates local tunnel to cluster service
|
||||||
|
- Reliable and consistent access method
|
||||||
|
|
||||||
|
### Method 2: LoadBalancer (For Reference)
|
||||||
|
|
||||||
|
Note: In Mycelium Cloud, LoadBalancer external IPs (like 10.20.x.x) are internal cluster IPs and not externally accessible. Use port-forward for external access.
|
||||||
|
|
||||||
|
## 🗑️ Resource Cleanup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Remove all resources
|
||||||
|
kubectl delete -f nginx-static-deployment.yaml -f nginx-static-service.yaml
|
||||||
|
|
||||||
|
# Remove the ConfigMap
|
||||||
|
kubectl delete configmap nginx-static-content
|
||||||
|
|
||||||
|
# Verify cleanup
|
||||||
|
kubectl get all -l app=nginx-static # Should return nothing
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 Troubleshooting
|
||||||
|
|
||||||
|
### Pod Won't Start
|
||||||
|
```bash
|
||||||
|
# Check pod status
|
||||||
|
kubectl get pods -l app=nginx-static
|
||||||
|
|
||||||
|
# Check pod logs
|
||||||
|
kubectl logs deployment/nginx-static
|
||||||
|
|
||||||
|
# Check pod events
|
||||||
|
kubectl describe pod -l app=nginx-static
|
||||||
|
```
|
||||||
|
|
||||||
|
### Site Not Loading
|
||||||
|
```bash
|
||||||
|
# Check service endpoints
|
||||||
|
kubectl get endpoints nginx-static-service
|
||||||
|
|
||||||
|
# Check if port-forward is working
|
||||||
|
kubectl port-forward service/nginx-static-service 8081:80 &
|
||||||
|
curl -v http://localhost:8081
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Content Not Showing
|
||||||
|
```bash
|
||||||
|
# Verify ConfigMap content
|
||||||
|
kubectl get configmap nginx-static-content -o yaml
|
||||||
|
|
||||||
|
# Check if files are mounted correctly
|
||||||
|
kubectl exec -it deployment/nginx-static -- ls -la /usr/share/nginx/html/
|
||||||
|
|
||||||
|
# Reload nginx to pick up changes
|
||||||
|
kubectl exec -it deployment/nginx-static -- nginx -s reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port Forward Fails
|
||||||
|
```bash
|
||||||
|
# Check if port is in use
|
||||||
|
lsof -i :8080
|
||||||
|
|
||||||
|
# Try different port
|
||||||
|
kubectl port-forward service/nginx-static-service 8082:80
|
||||||
|
curl http://localhost:8082
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 More Examples
|
||||||
|
|
||||||
|
This is currently one of the complete examples. Future examples will include:
|
||||||
|
- **python-flask/** - Python web applications
|
||||||
|
- **redis-cache/** - In-memory data caching
|
||||||
|
- **postgresql/** - Persistent database services
|
||||||
|
- **wordpress/** - Multi-container CMS deployment
|
||||||
|
- **nodejs-api/** - Modern JavaScript applications
|
||||||
|
- **jenkins-cicd/** - Infrastructure automation
|
||||||
|
- **nextcloud/** - Enterprise file sharing
|
||||||
|
|
||||||
|
## 💡 Pro Tips
|
||||||
|
|
||||||
|
1. **Start Simple**: Begin with foreground port-forward (`kubectl port-forward`)
|
||||||
|
2. **Background Optional**: Use `nohup` only when you need persistent port-forwards
|
||||||
|
3. **Port Management**: Use `lsof -ti:PORT` to find and kill processes
|
||||||
|
4. **Resource Monitoring**: `kubectl get pods -o wide` shows pod distribution
|
||||||
|
5. **Quick Testing**: `curl -s http://localhost:8080` to verify nginx is working
|
||||||
|
6. **Nginx Logs**: `kubectl logs deployment/nginx-static` for debugging
|
||||||
|
7. **Config Updates**: Update ConfigMap then reload nginx: `kubectl exec deployment/nginx-static -- nginx -s reload`
|
||||||
|
|
||||||
|
## 🎉 Success Indicators
|
||||||
|
|
||||||
|
You'll know everything is working when:
|
||||||
|
- ✅ `kubectl get pods` shows nginx-static pod in "Running" status
|
||||||
|
- ✅ `kubectl get svc` shows nginx-static-service created
|
||||||
|
- ✅ `curl http://localhost:8080` returns your custom HTML content
|
||||||
|
- ✅ `kubectl logs deployment/nginx-static` shows nginx access logs
|
||||||
|
|
||||||
|
## 🏆 Next Steps
|
||||||
|
|
||||||
|
After completing this example, you can:
|
||||||
|
1. **Customize Content**: Replace with your own static site
|
||||||
|
2. **Add More Examples**: Try the Python Flask API example
|
||||||
|
3. **Scale Up**: Learn about load balancing with multiple replicas
|
||||||
|
4. **Add Persistence**: Learn about persistent volumes for file storage
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📞 Getting Help
|
||||||
|
|
||||||
|
- **Troubleshooting**: Check the troubleshooting section above
|
||||||
|
- **Mycelium Cloud Docs**: See main repository README
|
||||||
|
- **Kubectl Help**: `kubectl get pods --help` for command reference
|
||||||
|
- **Support**: Contact Mycelium Cloud support team
|
||||||
|
|
||||||
|
For more help, visit our [documentation](../../README.md) or contact support.
|
||||||
Reference in New Issue
Block a user