React SPA + StorageVault (S3 staatiline majutus)
Selles juhendis ehitame React SPA rakenduse, mis kasutab Pilvio StorageVault'i (S3) staatiliste failide majutamiseks ja failide üleslaadimiseks.
⏳ CDN tulemas: Pilvio CDN on arenduses. Praegu saab staatilisi faile serveerida otse StorageVault'i S3 kaudu. CDN-i saabudes saad hõlpsalt lisada vahemälu ja geograafilise levitamise.
Mida ehitame
- React SPA, mis suhtleb Pilvio backendiga
- Failide üleslaadimine otse StorageVault'i (eelsigneeritud URL-id)
- Staatiline deploy S3 bucketisse
Eeldused
- Pilvio konto, API token ja S3 võtmed (vaata ülevaadet)
- Node.js 20+ ja npm
- Backend API (soovituslik: FastAPI + StorageVault)
1. samm: React projekti loomine
npm create vite@latest pilvio-react-app -- --template react
cd pilvio-react-app
npm install
npm install axios
2. samm: Pilvio API kliendi loomine
Loo fail src/lib/pilvio-client.js:
import axios from 'axios';
// Backend API URL (mitte otse Pilvio API, vaid sinu backend)
const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost:8000';
const api = axios.create({
baseURL: API_BASE,
headers: {
'Content-Type': 'application/json',
},
});
// Failide üleslaadimine backend proxy kaudu
export async function uploadFile(file) {
const formData = new FormData();
formData.append('file', file);
const response = await api.post('/api/v1/files/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
return response.data;
}
// Failide loetelu
export async function listFiles(prefix = 'uploads/') {
const response = await api.get('/api/v1/files', {
params: { prefix },
});
return response.data;
}
// Allalaadimis-URL hankimine (eelsigneeritud S3 URL)
export async function getDownloadUrl(fileKey) {
const response = await api.get(`/api/v1/files/download-url/${fileKey}`);
return response.data;
}
// Faili kustutamine
export async function deleteFile(fileKey) {
const response = await api.delete(`/api/v1/files/${fileKey}`);
return response.data;
}
export default api;
Turvalisus: Ära pane kunagi Pilvio API tokenit ega S3 võtmeid React rakendusse! Kõik Pilvio API päringud peavad käima läbi sinu backend serveri.
3. samm: Failihalduse komponent
Loo fail src/components/FileManager.jsx:
import { useState, useEffect } from 'react';
import { uploadFile, listFiles, getDownloadUrl, deleteFile } from '../lib/pilvio-client';
export default function FileManager() {
const [files, setFiles] = useState([]);
const [uploading, setUploading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
loadFiles();
}, []);
async function loadFiles() {
try {
const data = await listFiles();
setFiles(data.files || []);
} catch (err) {
setError('Failide laadimine ebaõnnestus');
}
}
async function handleUpload(event) {
const file = event.target.files[0];
if (!file) return;
setUploading(true);
setError(null);
try {
await uploadFile(file);
await loadFiles();
} catch (err) {
setError('Üleslaadimine ebaõnnestus');
} finally {
setUploading(false);
}
}
async function handleDownload(fileKey) {
try {
const data = await getDownloadUrl(fileKey);
window.open(data.url, '_blank');
} catch (err) {
setError('Allalaadimine ebaõnnestus');
}
}
async function handleDelete(fileKey) {
if (!confirm('Kas oled kindel?')) return;
try {
await deleteFile(fileKey);
await loadFiles();
} catch (err) {
setError('Kustutamine ebaõnnestus');
}
}
function formatSize(bytes) {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / 1048576).toFixed(1)} MB`;
}
return (
<div style={{ maxWidth: '800px', margin: '0 auto', padding: '20px' }}>
<h1>StorageVault failihaldus</h1>
{error && (
<div style={{ color: 'red', padding: '10px', marginBottom: '10px' }}>
{error}
</div>
)}
<div style={{ marginBottom: '20px' }}>
<input type="file" onChange={handleUpload} disabled={uploading} />
{uploading && <span> Laadin üles...</span>}
</div>
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
<thead>
<tr>
<th style={{ textAlign: 'left', padding: '8px' }}>Fail</th>
<th style={{ textAlign: 'right', padding: '8px' }}>Suurus</th>
<th style={{ textAlign: 'right', padding: '8px' }}>Tegevused</th>
</tr>
</thead>
<tbody>
{files.map((file) => (
<tr key={file.key} style={{ borderTop: '1px solid #eee' }}>
<td style={{ padding: '8px' }}>{file.key.split('/').pop()}</td>
<td style={{ textAlign: 'right', padding: '8px' }}>{formatSize(file.size)}</td>
<td style={{ textAlign: 'right', padding: '8px' }}>
<button onClick={() => handleDownload(file.key)}>Lae alla</button>{' '}
<button onClick={() => handleDelete(file.key)}>Kustuta</button>
</td>
</tr>
))}
</tbody>
</table>
{files.length === 0 && <p>Faile ei ole. Laadi midagi üles!</p>}
</div>
);
}
4. samm: Keskkonnamuutujad
Loo fail .env:
VITE_API_URL=https://sinu-api-domeen.ee
5. samm: Staatiline deploy StorageVault'i (S3)
Ehita React rakendus ja laadi üles S3 bucketisse:
# Ehita
npm run build
# Laadi dist/ sisu S3-sse (AWS CLI Pilvio endpointiga)
aws s3 sync dist/ s3://minu-react-app/ \
--endpoint-url https://s3.pilvio.com:8080 \
--delete
# Sea index.html Content-Type
aws s3 cp s3://minu-react-app/index.html s3://minu-react-app/index.html \
--endpoint-url https://s3.pilvio.com:8080 \
--content-type "text/html" \
--metadata-directive REPLACE
Alternatiiv: Deploy skript
Loo fail deploy.sh:
#!/bin/bash
set -e
echo "Ehitan React rakendust..."
npm run build
echo "Laadin üles StorageVault'i..."
aws s3 sync dist/ s3://minu-react-app/ \
--endpoint-url https://s3.pilvio.com:8080 \
--delete \
--cache-control "public, max-age=31536000" \
--exclude "index.html"
# index.html ilma vahemäluta (et uus versioon oleks kohe näha)
aws s3 cp dist/index.html s3://minu-react-app/index.html \
--endpoint-url https://s3.pilvio.com:8080 \
--content-type "text/html" \
--cache-control "no-cache"
echo "Deploy valmis!"
chmod +x deploy.sh
./deploy.sh
Alternatiiv: SPA majutamine Pilvio VM + Nginx
Kui S3 staatilise majutuse seadistamine on keeruline, saab SPA-d serveerida ka Nginx kaudu VM-il:
# Kopeeri ehitatud failid serverisse
scp -r dist/* deploy@SINU_FLOATING_IP:/var/www/react-app/
# Nginx seadistus SPA jaoks
sudo tee /etc/nginx/sites-available/react-app <<'EOF'
server {
listen 80;
server_name sinu-domeen.ee;
root /var/www/react-app;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
EOF
⏳ CDN (tulemas): Pilvio CDN võimaldab tulevikus lisada S3 bucketile automaatse vahemälu ja edge-serveerimise. Praegune S3-põhine lahendus töötab hästi ja CDN-i lisamine nõuab ainult URL-i muutmist.
Järgmised sammud: Ühenda backend API-ga (Node.js või FastAPI) ja lisa andmebaas.