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)
|
||||
|
||||
#### 2. Nginx Static Site 🔄
|
||||
- **Difficulty**: ⭐ Easy
|
||||
- **Status**: 🔄 **NEXT UP**
|
||||
#### 2. Nginx Static Site ✅
|
||||
- **Difficulty**: ⭐ Easy
|
||||
- **Status**: ✅ **COMPLETED**
|
||||
- **Learning Focus**: Static content serving, custom HTML, nginx configuration
|
||||
- **Template**: Same efficient pattern as hello-world
|
||||
- **Key Concepts**: Static files, nginx deployment, custom configuration
|
||||
- **Next Step**: Copy hello-world template, adapt for nginx
|
||||
- **Key Concepts**: Static files, nginx deployment, custom configuration, ConfigMaps
|
||||
- **Result**: Tested and working on MyceliumCloud cluster
|
||||
- **Next Step**: Move to Python Flask API example
|
||||
|
||||
### 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