Skip to content

Commit 8c43a80

Browse files
author
OpenNebula Community Contributor
committed
Split tutorial into separate automatic and manual guides
- Remove combined CREATE_APPLIANCE_TUTORIAL.md - Add AUTOMATIC_APPLIANCE_GUIDE.md (5 min quick start) - Add MANUAL_APPLIANCE_GUIDE.md (full control, 30-45 min) - Add docs/README.md with guide comparison and selection help Benefits: - Clearer separation of concerns - Easier to navigate and find relevant information - Better for beginners (automatic guide is simpler) - Better for advanced users (manual guide has full details) - Comparison table helps users choose the right approach
1 parent 6bac36d commit 8c43a80

File tree

4 files changed

+1324
-890
lines changed

4 files changed

+1324
-890
lines changed

docs/AUTOMATIC_APPLIANCE_GUIDE.md

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
# Creating OpenNebula Appliances - Automatic Method
2+
3+
**Quick appliance creation using the generator script (5 minutes)**
4+
5+
---
6+
7+
## 📖 Introduction
8+
9+
This guide shows you how to quickly create OpenNebula appliances from Docker containers using an automated generator script. The generator creates all necessary files following the proven Phoenix RTOS/Node-RED structure.
10+
11+
**What you'll create:**
12+
- A VM image (QCOW2 format) with Ubuntu 22.04 + Docker
13+
- Automatic Docker container startup on VM boot
14+
- SSH access with password and key authentication
15+
- Console and serial console auto-login
16+
- OpenNebula context integration for runtime configuration
17+
18+
**Time required:** ~5 minutes for generation + 15-20 minutes for building
19+
20+
---
21+
22+
## ✅ Prerequisites
23+
24+
- Linux system (Ubuntu 22.04+ recommended)
25+
- Git
26+
- Packer (for building the image)
27+
- QEMU/KVM (for building the image)
28+
29+
```bash
30+
sudo apt update
31+
sudo apt install -y git qemu-kvm qemu-utils
32+
```
33+
34+
---
35+
36+
## 🚀 Quick Start
37+
38+
### Step 1: Clone Repository
39+
40+
```bash
41+
git clone https://github.com/OpenNebula/marketplace-community.git
42+
cd marketplace-community
43+
```
44+
45+
### Step 2: Create Configuration File
46+
47+
Create a `.env` file with your Docker container details:
48+
49+
```bash
50+
cd docs/automatic-appliance-tutorial
51+
52+
cat > myapp.env << 'ENVEOF'
53+
# Required variables
54+
DOCKER_IMAGE="your-docker-image:tag"
55+
APPLIANCE_NAME="myapp"
56+
APP_NAME="MyApp"
57+
PUBLISHER_NAME="Your Name"
58+
PUBLISHER_EMAIL="your.email@example.com"
59+
60+
# Optional variables
61+
APP_DESCRIPTION="MyApp description"
62+
APP_FEATURES="Feature 1,Feature 2,Feature 3"
63+
DEFAULT_CONTAINER_NAME="myapp-container"
64+
DEFAULT_PORTS="8080:8080"
65+
DEFAULT_ENV_VARS=""
66+
DEFAULT_VOLUMES="/data:/data"
67+
APP_PORT="8080"
68+
WEB_INTERFACE="true"
69+
ENVEOF
70+
```
71+
72+
### Step 3: Run Generator
73+
74+
```bash
75+
./generate-docker-appliance.sh myapp.env
76+
```
77+
78+
The generator will:
79+
1. Create all appliance files
80+
2. Generate Packer configuration
81+
3. Prompt you to build the image immediately
82+
83+
**Output:**
84+
```
85+
🚀 Loading configuration from myapp.env
86+
🎯 Generating complete appliance: myapp (MyApp)
87+
📁 Creating directory structure...
88+
✅ Directory structure created
89+
📝 Generating metadata.yaml...
90+
✅ Metadata files generated
91+
📝 Generating README.md...
92+
✅ README.md generated
93+
📝 Generating appliance.sh installation script...
94+
✅ appliance.sh generated
95+
📝 Generating Packer configuration files...
96+
✅ Packer configuration files generated
97+
🎉 Appliance 'myapp' generated successfully!
98+
99+
Do you want to build the image now? (y/n):
100+
```
101+
102+
### Step 4: Build the Image
103+
104+
If you answered 'y' to the prompt, the build starts automatically. Otherwise:
105+
106+
```bash
107+
cd ../../apps-code/community-apps
108+
make myapp
109+
```
110+
111+
**Build time:** 15-20 minutes (downloads Ubuntu, installs Docker, pulls your container image)
112+
113+
**Output file:** `export/myapp.qcow2`
114+
115+
---
116+
117+
## 📋 Configuration Variables
118+
119+
| Variable | Required | Description | Example |
120+
|----------|----------|-------------|---------|
121+
| `DOCKER_IMAGE` | Yes | Docker image name | `nginx:alpine` |
122+
| `APPLIANCE_NAME` | Yes | Lowercase name (no spaces) | `nginx` |
123+
| `APP_NAME` | Yes | Display name | `NGINX Web Server` |
124+
| `PUBLISHER_NAME` | Yes | Your name | `John Doe` |
125+
| `PUBLISHER_EMAIL` | Yes | Your email | `john@example.com` |
126+
| `APP_DESCRIPTION` | No | Full description | `NGINX is a web server...` |
127+
| `APP_FEATURES` | No | Comma-separated features | `Web Server,Reverse Proxy` |
128+
| `DEFAULT_CONTAINER_NAME` | No | Container name | `nginx-container` |
129+
| `DEFAULT_PORTS` | No | Port mappings | `80:80,443:443` |
130+
| `DEFAULT_ENV_VARS` | No | Environment variables | `KEY=value,KEY2=value2` |
131+
| `DEFAULT_VOLUMES` | No | Volume mappings | `/data:/data,/config:/config` |
132+
| `APP_PORT` | No | Main application port | `80` |
133+
| `WEB_INTERFACE` | No | Has web UI? | `true` or `false` |
134+
135+
---
136+
137+
## 📁 Generated Files
138+
139+
The generator creates:
140+
141+
```
142+
marketplace-community/
143+
├── appliances/myapp/
144+
│ ├── appliance.sh # Installation script
145+
│ ├── metadata.yaml # Build configuration
146+
│ ├── <uuid>.yaml # Marketplace metadata
147+
│ ├── README.md # Documentation
148+
│ ├── CHANGELOG.md # Version history
149+
│ └── tests/
150+
│ └── tests.yaml # Test configuration
151+
└── apps-code/community-apps/packer/myapp/
152+
├── myapp.pkr.hcl # Packer build file
153+
└── myapp.auto.pkrvars.hcl # Packer variables
154+
```
155+
156+
---
157+
158+
## 🔧 Customization
159+
160+
After generation, you can customize the files:
161+
162+
### Modify Container Configuration
163+
164+
Edit `appliances/myapp/appliance.sh`:
165+
166+
```bash
167+
# Change default values
168+
DEFAULT_CONTAINER_NAME="custom-name"
169+
DEFAULT_PORTS="8080:8080,8443:8443"
170+
DEFAULT_ENV_VARS="DEBUG=true,LOG_LEVEL=info"
171+
```
172+
173+
### Add Custom Installation Steps
174+
175+
Add to the `service_install()` function in `appliance.sh`:
176+
177+
```bash
178+
service_install()
179+
{
180+
# ... existing Docker installation ...
181+
182+
# Add your custom steps here
183+
apt-get install -y additional-package
184+
185+
# Custom configuration
186+
echo "custom config" > /etc/myapp.conf
187+
}
188+
```
189+
190+
### Rebuild After Changes
191+
192+
```bash
193+
cd apps-code/community-apps
194+
make clean
195+
make myapp
196+
```
197+
198+
---
199+
200+
## 📦 Examples
201+
202+
See `docs/automatic-appliance-tutorial/examples/` for complete working examples:
203+
204+
### NGINX Web Server
205+
206+
```bash
207+
cat > nginx.env << 'EOF'
208+
DOCKER_IMAGE="nginx:alpine"
209+
APPLIANCE_NAME="nginx"
210+
APP_NAME="NGINX"
211+
PUBLISHER_NAME="Your Name"
212+
PUBLISHER_EMAIL="your@email.com"
213+
DEFAULT_PORTS="80:80,443:443"
214+
APP_PORT="80"
215+
WEB_INTERFACE="true"
216+
EOF
217+
218+
./generate-docker-appliance.sh nginx.env
219+
```
220+
221+
### Node-RED
222+
223+
```bash
224+
cat > nodered.env << 'EOF'
225+
DOCKER_IMAGE="nodered/node-red:latest"
226+
APPLIANCE_NAME="nodered"
227+
APP_NAME="Node-RED"
228+
PUBLISHER_NAME="Your Name"
229+
PUBLISHER_EMAIL="your@email.com"
230+
DEFAULT_PORTS="1880:1880"
231+
DEFAULT_VOLUMES="/data:/data"
232+
APP_PORT="1880"
233+
WEB_INTERFACE="true"
234+
EOF
235+
236+
./generate-docker-appliance.sh nodered.env
237+
```
238+
239+
### PostgreSQL Database
240+
241+
```bash
242+
cat > postgres.env << 'EOF'
243+
DOCKER_IMAGE="postgres:16-alpine"
244+
APPLIANCE_NAME="postgres"
245+
APP_NAME="PostgreSQL"
246+
PUBLISHER_NAME="Your Name"
247+
PUBLISHER_EMAIL="your@email.com"
248+
DEFAULT_PORTS="5432:5432"
249+
DEFAULT_ENV_VARS="POSTGRES_PASSWORD=changeme"
250+
DEFAULT_VOLUMES="/var/lib/postgresql/data:/var/lib/postgresql/data"
251+
APP_PORT="5432"
252+
WEB_INTERFACE="false"
253+
EOF
254+
255+
./generate-docker-appliance.sh postgres.env
256+
```
257+
258+
---
259+
260+
## 🧪 Testing Your Appliance
261+
262+
### 1. Test Locally with QEMU
263+
264+
```bash
265+
cd apps-code/community-apps/export
266+
267+
# Start VM with QEMU
268+
qemu-system-x86_64 \
269+
-enable-kvm \
270+
-m 2048 \
271+
-smp 2 \
272+
-drive file=myapp.qcow2,format=qcow2 \
273+
-net nic -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:8080 \
274+
-vnc :0
275+
```
276+
277+
Connect via VNC to `localhost:5900` and verify:
278+
- Console auto-login works
279+
- Docker container is running: `docker ps`
280+
- Application is accessible
281+
282+
### 2. Test on OpenNebula
283+
284+
See the [Manual Appliance Guide](MANUAL_APPLIANCE_GUIDE.md#deploying-to-opennebula) for detailed deployment instructions.
285+
286+
---
287+
288+
## 🐛 Troubleshooting
289+
290+
### Generator Fails
291+
292+
**Problem:** Missing required variables
293+
**Solution:** Check all required variables are set in .env file
294+
295+
```bash
296+
# Verify your .env file has all required fields
297+
grep -E "DOCKER_IMAGE|APPLIANCE_NAME|APP_NAME|PUBLISHER" myapp.env
298+
```
299+
300+
### Build Fails
301+
302+
**Problem:** Packer build fails
303+
**Solution:** Check Packer logs
304+
305+
```bash
306+
cd apps-code/community-apps
307+
make myapp 2>&1 | tee build.log
308+
```
309+
310+
Common issues:
311+
- Network connectivity (can't download Ubuntu ISO)
312+
- Insufficient disk space
313+
- Docker image doesn't exist or is private
314+
315+
### Container Doesn't Start
316+
317+
**Problem:** Container fails to start on VM boot
318+
**Solution:** Check the generated `appliance.sh` for correct Docker image name
319+
320+
```bash
321+
# Verify Docker image name in appliance.sh
322+
grep "DOCKER_IMAGE=" appliances/myapp/appliance.sh
323+
```
324+
325+
### Permission Issues
326+
327+
**Problem:** Container can't write to volumes
328+
**Solution:** The generator automatically sets ownership to `1000:1000`. If your container uses a different UID, edit `appliance.sh`:
329+
330+
```bash
331+
# In service_install() function
332+
mkdir -p /data
333+
chown 1001:1001 /data # Change to your container's UID:GID
334+
```
335+
336+
---
337+
338+
## 📤 Next Steps
339+
340+
After successfully building and testing your appliance:
341+
342+
1. **Add a logo** - Create a 256x256 PNG logo at `logos/myapp.png`
343+
2. **Test thoroughly** - Deploy on OpenNebula and verify all functionality
344+
3. **Submit to marketplace** - See [Manual Appliance Guide](MANUAL_APPLIANCE_GUIDE.md#submitting-to-marketplace) for PR instructions
345+
346+
---
347+
348+
## 💡 Tips
349+
350+
- **Start simple** - Begin with minimal configuration, add features incrementally
351+
- **Use official images** - Prefer official Docker images from Docker Hub
352+
- **Test the Docker image first** - Run `docker run` locally before generating appliance
353+
- **Check examples** - Study the example .env files for reference
354+
- **Volume permissions** - If container runs as non-root, ensure volume directories have correct ownership
355+
- **Environment variables** - Use DEFAULT_ENV_VARS for container configuration
356+
- **Port conflicts** - Ensure ports don't conflict with system services
357+
358+
---
359+
360+
## 📖 Additional Resources
361+
362+
- [Manual Appliance Guide](MANUAL_APPLIANCE_GUIDE.md) - For advanced customization
363+
- [OpenNebula Documentation](https://docs.opennebula.io/)
364+
- [Docker Hub](https://hub.docker.com/)
365+
- [Packer Documentation](https://www.packer.io/docs)
366+
- [OpenNebula Marketplace](https://marketplace.opennebula.io/)
367+

0 commit comments

Comments
 (0)