mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-22 21:06:41 +02:00
docs: remove all Coolify references from codebase
Replace Coolify with Docker Compose throughout documentation. The project never used Coolify - a removal script was created but never executed, leaving incorrect documentation. Changes: - Delete 13 heavily Coolify-focused docs files - Update ~30 files replacing Coolify → Docker Compose - Remove obsolete removal script - Fix deployment references in active and archived projects 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
79b4bb07ed
commit
c61dcb8ff9
42 changed files with 176 additions and 4741 deletions
|
|
@ -11,7 +11,7 @@ Dieses Dokument analysiert die optimale Strategie für die Implementierung einer
|
|||
- **Framework**: SvelteKit 2.22 mit Svelte 5.0
|
||||
- **Backend**: PocketBase (eingebettet)
|
||||
- **Styling**: Tailwind CSS 4.0
|
||||
- **Deployment**: Docker + Coolify auf Hetzner VPS
|
||||
- **Deployment**: Docker Compose auf Hetzner VPS
|
||||
- **Hauptfunktionen**:
|
||||
- URL-Verkürzung mit QR-Code-Generierung
|
||||
- Benutzer-Dashboard mit Analytics
|
||||
|
|
|
|||
|
|
@ -1,335 +0,0 @@
|
|||
# Self-Hosted IP Geolocation Solutions für Coolify/VPS
|
||||
|
||||
**Erstellt:** 16. August 2025
|
||||
**Version:** 1.0
|
||||
**Kontext:** Unabhängige, kommerzielle Geolocation-Lösung für uload
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Für kommerziellen Einsatz ohne Abhängigkeit von externen Services gibt es mehrere exzellente self-hosted Lösungen, die perfekt mit Coolify auf einem VPS funktionieren.
|
||||
|
||||
## Option 1: MaxMind GeoLite2 Docker Container (⭐ EMPFOHLEN)
|
||||
|
||||
### Setup als Docker Service in Coolify
|
||||
|
||||
**1. Docker Compose Service:**
|
||||
|
||||
```yaml
|
||||
services:
|
||||
geolite2-server:
|
||||
image: ghcr.io/m-rots/geolite2-server:latest
|
||||
container_name: geolite2-server
|
||||
restart: always
|
||||
ports:
|
||||
- '8080:8080'
|
||||
environment:
|
||||
- MAXMIND_LICENSE_KEY=${MAXMIND_LICENSE_KEY}
|
||||
- UPDATE_INTERVAL=24h
|
||||
volumes:
|
||||
- geolite2-data:/usr/share/GeoIP
|
||||
networks:
|
||||
- coolify
|
||||
|
||||
uload-app:
|
||||
# ... existing config
|
||||
depends_on:
|
||||
- geolite2-server
|
||||
environment:
|
||||
- GEOLOCATION_URL=http://geolite2-server:8080
|
||||
|
||||
volumes:
|
||||
geolite2-data:
|
||||
```
|
||||
|
||||
**2. Integration im Code:**
|
||||
|
||||
```javascript
|
||||
// src/lib/geolocation.ts
|
||||
export async function getLocationFromIP(ipAddress: string) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${process.env.GEOLOCATION_URL || 'http://localhost:8080'}/json/${ipAddress}`
|
||||
);
|
||||
const data = await response.json();
|
||||
return {
|
||||
country: data.country?.names?.en || 'Unknown',
|
||||
city: data.city?.names?.en || 'Unknown'
|
||||
};
|
||||
} catch (error) {
|
||||
return { country: 'Unknown', city: 'Unknown' };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Vorteile:**
|
||||
|
||||
- ✅ Komplett self-hosted
|
||||
- ✅ Kostenlos (GeoLite2 License)
|
||||
- ✅ Automatische Updates
|
||||
- ✅ Keine API Limits
|
||||
- ✅ GDPR-konform (keine Daten verlassen Server)
|
||||
|
||||
**Setup Steps:**
|
||||
|
||||
1. Registriere kostenlosen MaxMind Account
|
||||
2. Erstelle License Key
|
||||
3. Deploy via Coolify
|
||||
4. Fertig!
|
||||
|
||||
## Option 2: IP2Location LITE Docker
|
||||
|
||||
### Fertige Docker Solution
|
||||
|
||||
```yaml
|
||||
services:
|
||||
ip2location:
|
||||
image: ip2location/ip2location-lite:latest
|
||||
container_name: ip2location
|
||||
restart: always
|
||||
ports:
|
||||
- '8081:80'
|
||||
volumes:
|
||||
- ./ip2location-data:/var/lib/ip2location
|
||||
environment:
|
||||
- AUTO_UPDATE=true
|
||||
- UPDATE_FREQUENCY=weekly
|
||||
```
|
||||
|
||||
**Integration:**
|
||||
|
||||
```javascript
|
||||
async function getLocationFromIP(ip) {
|
||||
const response = await fetch(`http://ip2location:80/api/${ip}`);
|
||||
return await response.json();
|
||||
}
|
||||
```
|
||||
|
||||
**Vorteile:**
|
||||
|
||||
- ✅ Ebenfalls kostenlos für kommerzielle Nutzung
|
||||
- ✅ Sehr leichtgewichtig
|
||||
- ✅ Gute Genauigkeit
|
||||
|
||||
## Option 3: GeoIP2 Server (Rust-basiert, Ultra-Fast)
|
||||
|
||||
### High-Performance Solution
|
||||
|
||||
```dockerfile
|
||||
# Dockerfile
|
||||
FROM ghcr.io/lily-mosquitoes/geoip2-server:latest
|
||||
COPY GeoLite2-City.mmdb /data/
|
||||
CMD ["--database", "/data/GeoLite2-City.mmdb", "--port", "3000"]
|
||||
```
|
||||
|
||||
**Coolify Deployment:**
|
||||
|
||||
```yaml
|
||||
services:
|
||||
geoip-server:
|
||||
build: ./geoip-server
|
||||
restart: always
|
||||
ports:
|
||||
- '3000:3000'
|
||||
volumes:
|
||||
- ./data:/data
|
||||
mem_limit: 128m
|
||||
cpus: 0.25
|
||||
```
|
||||
|
||||
**Performance:**
|
||||
|
||||
- < 1ms Response Time
|
||||
- 50MB RAM Footprint
|
||||
- 10k+ Requests/Second
|
||||
|
||||
## Option 4: All-in-One Solution mit Plausible Analytics
|
||||
|
||||
### Bonus: Komplettes Analytics System
|
||||
|
||||
```yaml
|
||||
services:
|
||||
plausible:
|
||||
image: plausible/analytics:latest
|
||||
container_name: plausible
|
||||
restart: always
|
||||
command: sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"
|
||||
depends_on:
|
||||
- plausible_db
|
||||
- plausible_events_db
|
||||
ports:
|
||||
- 8000:8000
|
||||
env_file:
|
||||
- plausible-conf.env
|
||||
volumes:
|
||||
- ./geoip:/geoip:ro
|
||||
```
|
||||
|
||||
**Vorteile:**
|
||||
|
||||
- ✅ Komplettes Analytics System
|
||||
- ✅ Integrierte Geolocation
|
||||
- ✅ GDPR-konform
|
||||
- ✅ Schönes Dashboard
|
||||
|
||||
## Empfehlung für uload
|
||||
|
||||
### Sofort-Implementation (1 Tag)
|
||||
|
||||
**1. MaxMind GeoLite2 Server via Coolify:**
|
||||
|
||||
```bash
|
||||
# 1. MaxMind Account erstellen (kostenlos)
|
||||
# https://www.maxmind.com/en/geolite2/signup
|
||||
|
||||
# 2. License Key generieren
|
||||
|
||||
# 3. Docker Compose in Coolify
|
||||
```
|
||||
|
||||
**docker-compose.coolify.yml Addition:**
|
||||
|
||||
```yaml
|
||||
geolite2:
|
||||
image: maxmindinc/geoipupdate:latest
|
||||
container_name: geoip-updater
|
||||
environment:
|
||||
GEOIPUPDATE_ACCOUNT_ID: ${MAXMIND_ACCOUNT_ID}
|
||||
GEOIPUPDATE_LICENSE_KEY: ${MAXMIND_LICENSE_KEY}
|
||||
GEOIPUPDATE_EDITION_IDS: 'GeoLite2-City GeoLite2-Country'
|
||||
GEOIPUPDATE_FREQUENCY: 72
|
||||
volumes:
|
||||
- geoip-data:/usr/share/GeoIP
|
||||
restart: unless-stopped
|
||||
|
||||
geoip-api:
|
||||
image: ghcr.io/m-rots/geolite2-server:latest
|
||||
container_name: geoip-api
|
||||
depends_on:
|
||||
- geolite2
|
||||
ports:
|
||||
- '127.0.0.1:8080:8080'
|
||||
volumes:
|
||||
- geoip-data:/usr/share/GeoIP:ro
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
**4. Code Integration:**
|
||||
|
||||
```javascript
|
||||
// src/lib/services/geolocation.ts
|
||||
const GEOIP_SERVICE = process.env.GEOIP_SERVICE_URL || 'http://geoip-api:8080';
|
||||
|
||||
export async function getLocationFromIP(ipAddress: string) {
|
||||
// Skip private IPs
|
||||
if (isPrivateIP(ipAddress)) {
|
||||
return { country: 'Local', city: 'Local' };
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${GEOIP_SERVICE}/json/${ipAddress}`, {
|
||||
signal: AbortSignal.timeout(1000) // 1s timeout
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error('GeoIP lookup failed');
|
||||
|
||||
const data = await response.json();
|
||||
return {
|
||||
country: data.country?.names?.en || 'Unknown',
|
||||
city: data.city?.names?.en || 'Unknown',
|
||||
region: data.subdivisions?.[0]?.names?.en,
|
||||
latitude: data.location?.latitude,
|
||||
longitude: data.location?.longitude
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('GeoIP lookup error:', error);
|
||||
return { country: 'Unknown', city: 'Unknown' };
|
||||
}
|
||||
}
|
||||
|
||||
function isPrivateIP(ip: string): boolean {
|
||||
return ip === '::1' ||
|
||||
ip === '127.0.0.1' ||
|
||||
ip.startsWith('192.168.') ||
|
||||
ip.startsWith('10.') ||
|
||||
ip.startsWith('172.');
|
||||
}
|
||||
```
|
||||
|
||||
## Implementierungs-Checkliste
|
||||
|
||||
### Tag 1: Setup
|
||||
|
||||
- [ ] MaxMind Account erstellen
|
||||
- [ ] License Key generieren
|
||||
- [ ] Docker Service in Coolify deployen
|
||||
- [ ] Environment Variables setzen
|
||||
|
||||
### Tag 2: Integration
|
||||
|
||||
- [ ] Geolocation Service Code hinzufügen
|
||||
- [ ] Click-Handler updaten
|
||||
- [ ] Error Handling testen
|
||||
- [ ] Performance Monitoring
|
||||
|
||||
### Tag 3: Optimization
|
||||
|
||||
- [ ] Caching Layer (Redis/Memory)
|
||||
- [ ] Batch Updates für alte Daten
|
||||
- [ ] Dashboard für Geo-Stats
|
||||
|
||||
## Kosten-Nutzen-Analyse
|
||||
|
||||
| Lösung | Einmalige Kosten | Laufende Kosten | Performance | Wartung |
|
||||
| ---------------- | ---------------- | --------------- | ----------- | ------- |
|
||||
| MaxMind GeoLite2 | 0€ | 0€ | Excellent | Minimal |
|
||||
| IP2Location LITE | 0€ | 0€ | Sehr gut | Minimal |
|
||||
| Plausible Bundle | 0€ | 0€ | Gut | Mittel |
|
||||
|
||||
## Performance Benchmarks
|
||||
|
||||
**Test Setup:** 1000 unique IPs
|
||||
|
||||
- MaxMind Docker: ~0.8ms avg response
|
||||
- Direct MMDB: ~0.2ms avg response
|
||||
- External API: ~50-200ms avg response
|
||||
|
||||
## Fazit
|
||||
|
||||
**Beste Option:** MaxMind GeoLite2 Docker Container
|
||||
|
||||
**Gründe:**
|
||||
|
||||
1. **Zero Cost** - Komplett kostenlos für kommerzielle Nutzung
|
||||
2. **Zero Dependencies** - Läuft komplett auf eurem Server
|
||||
3. **GDPR Compliant** - Keine Daten verlassen euren Server
|
||||
4. **Production Ready** - Von Millionen Sites verwendet
|
||||
5. **Coolify Native** - Ein Docker Compose und fertig
|
||||
|
||||
**Next Steps:**
|
||||
|
||||
1. MaxMind Account in 5 Min erstellen
|
||||
2. Docker Service deployen (10 Min)
|
||||
3. Code Integration (30 Min)
|
||||
4. **Total: < 1 Stunde bis Production!**
|
||||
|
||||
## Bonus: Nginx GeoIP Module
|
||||
|
||||
Falls ihr Nginx verwendet, gibt es noch eine ultra-schnelle Option:
|
||||
|
||||
```nginx
|
||||
# nginx.conf
|
||||
load_module modules/ngx_http_geoip2_module.so;
|
||||
|
||||
http {
|
||||
geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
|
||||
$geoip2_country_name country names en;
|
||||
$geoip2_city_name city names en;
|
||||
}
|
||||
|
||||
# Pass to upstream
|
||||
proxy_set_header X-Country $geoip2_country_name;
|
||||
proxy_set_header X-City $geoip2_city_name;
|
||||
}
|
||||
```
|
||||
|
||||
Dann im Code einfach Header auslesen - 0ms Overhead!
|
||||
Loading…
Add table
Add a link
Reference in a new issue