Community
237
HostiServer
2026-02-23 14:53:00

Co je WSGI: snadný průvodce Python webovými projekty

⏱️ Doba čtení: ~8 minut | 📅 Aktualizováno: 23. února 2026

Proč je konfigurace serveru kritická pro Python aplikace

Django a Flask patří mezi nejpopulárnější frameworky pro webový vývoj. Instagram, Pinterest, Spotify, Dropbox jsou postaveny na Django. Netflix, LinkedIn, Reddit používají Flask pro mikroslužby a API. Ale i dokonale napsaný kód bude zpomalovat na špatně nakonfigurovaném serveru.

Špatný počet workerů, chybějící connection pooling, běh pod rootem, DEBUG=True v produkci — typické chyby, které změní rychlou aplikaci na pomalou a zranitelnou. Viděli jsme projekty, kde doba odezvy klesla z 1,2 sekundy na 150 ms jednoduše po správné konfiguraci databáze.

V tomto průvodci probereme production-ready nastavení: od výběru mezi Gunicorn a uWSGI po systemd služby s automatickým restartem, od connection poolingu po monitoring. Všechna doporučení vycházejí z reálných zkušeností s nasazením stovek Python projektů.

Django vs Flask: kdy co vybrat

Django — „batteries included" framework s vestavěnou administrací, ORM, autentizací, formuláři, middleware, systémem migrací. Ideální pro velké projekty: eCommerce, CRM, SaaS platformy, systémy správy obsahu, sociální sítě. Více kódu „z krabice", méně rozhodnutí dělat sami, rychlejší start pro typické úlohy.

Flask — minimalistický mikroframework. Dává plnou svobodu ve výběru komponent: ORM (SQLAlchemy), formuláře (WTForms), autentizace (Flask-Login), admin (Flask-Admin). Vhodný pro API, mikroslužby, malé aplikace, prototypy, Machine Learning služby. Snadnější na naučení, ale vyžaduje více ruční práce pro velké projekty.

Oba frameworky jsou production-ready a používají se ve velkých společnostech. Rozdíl je v přístupu: Django — konvence nad konfigurací (Django Way), Flask — svoboda výběru (micro framework).

Gunicorn vs uWSGI: co vybrat

Oba jsou WSGI servery pro spouštění Python aplikací. Fungují jako prostředník mezi webovým serverem (Nginx) a vaším kódem (Django/Flask). Ale v praxi volíme Gunicorn v 90 % případů.

Proč Gunicorn

  • Jednodušší konfigurace — méně parametrů, srozumitelnější dokumentace, rychlejší start
  • Standard pro Docker — většina tutoriálů, Dockerfile příkladů a best practices je napsána pro něj
  • „Čistší" kód — snadnější ladění problémů, méně „magie"
  • Dostatečná funkcionalita — pro 90 % projektů není potřeba víc
  • Aktivní komunita — rychlé odpovědi na otázky, pravidelné aktualizace

Kdy uWSGI

uWSGI je výkonnější: má vlastní binární protokol (uwsgi), vestavěné cachování, emperor mode pro správu více aplikací, podporu WebSocket z krabice. Ale konfigurace je příliš složitá pro typické projekty — desítky parametrů, komplexní syntaxe. Vyberte uWSGI pouze pokud:

  • Potřebujete emperor mode pro správu mnoha aplikací na jednom serveru
  • Používáte specifické funkce: vestavěné cachování, spooler pro fronty
  • Už máte zkušenosti s uWSGI

Počet workerů

Klasický vzorec (2 × CPU jader) + 1 je dobrý výchozí bod, ale ne axiom. Více o výběru počtu jader a vláken pro server:

Typ úloh Doporučení Proč
CPU-bound ≈ počet jader Zpracování obrázků, náročné výpočty — workery soutěží o CPU
I/O-bound (2–4) × jader Mnoho dotazů do DB, externí API — workery často čekají
Smíšené (2 × jader) + 1 Typická webová aplikace — vyvážení

Async workery (gevent, eventlet)

Pro I/O-bound aplikace s mnoha současnými požadavky můžete použít asynchronní workery:

# Instalace
pip install gunicorn gevent
# Spuštění s gevent workery
gunicorn myproject.wsgi:application \
    --worker-class gevent \
    --workers 4 \
    --worker-connections 1000 \
    --bind unix:/run/gunicorn.sock

Jeden gevent worker může obsluhovat tisíce současných spojení díky kooperativnímu multitaskingu. Ale je tu nuance: veškerý kód musí být „gevent-friendly" — blokující operace zablokují celý worker.

Kompletní příklad konfigurace Gunicorn

# /etc/gunicorn/gunicorn.conf.py
# Počet workerů pro 4jádrový server
workers = 9  # (2×4)+1
# Bind na Unix socket (rychlejší než TCP)
bind = 'unix:/run/gunicorn.sock'
# Timeouty
timeout = 30  # Pokud déle — přesuňte do Celery
graceful_timeout = 30  # Čas na dokončení aktuálního požadavku
keepalive = 5  # Keep-alive spojení s Nginx
# Restart workerů pro prevenci úniků paměti
max_requests = 1000
max_requests_jitter = 100  # Náhodná odchylka
# Logování
accesslog = '/var/log/gunicorn/access.log'
errorlog = '/var/log/gunicorn/error.log'
loglevel = 'warning'
# Proces
daemon = False  # Systemd řídí proces
user = 'www-data'
group = 'www-data'

Důležité parametry:

  • timeout = 30 — pokud požadavek trvá déle než 30 sekund, architekturu je třeba změnit na fronty (Celery). Nezvyšujte timeout — skrývá to problém
  • graceful_timeout = 30 — čas na dokončení aktuálního požadavku před restartem workeru
  • max_requests = 1000 — restart workeru po 1000 požadavcích zabraňuje hromadění úniků paměti ze špatně napsaných knihoven

Production Checklist pro Django

Před uvedením do produkce nezapomeňte zkontrolovat tato nastavení:

settings.py

# KRITICKÉ: vypnout debug mode
DEBUG = False
# Jasný seznam povolených domén
ALLOWED_HOSTS = ['example.com', 'www.example.com']
# Pokud je Django za Nginx/proxy
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Bezpečnost
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True

⚠️ DEBUG = False je kritické! Se zapnutým DEBUG při chybách Django zobrazuje celý traceback s kódem, cestami k souborům, proměnnými prostředí. To je přímá bezpečnostní hrozba.

Tajemství a proměnné prostředí

Nikdy necommitujte tajemství do Gitu. Použijte:

  • Environment Variables přes .env soubor (django-environ nebo python-dotenv)
  • HashiCorp Vault nebo AWS Secrets Manager pro velké projekty
# .env soubor (NECOMMITOVAT do Gitu!)
SECRET_KEY=your-super-secret-key
DATABASE_URL=postgres://user:pass@localhost/dbname
DEBUG=False

Middleware

Povinné middleware pro produkci:

  • SecurityMiddleware — přesměrování na HTTPS, ochrana před XSS/Clickjacking
  • WhiteNoise — servírování statických souborů bez samostatného webového serveru (pokud není CDN)
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # Za SecurityMiddleware
    # ... další middleware
]
# Konfigurace WhiteNoise
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Systemd: automatické spuštění a monitoring

Systemd zajišťuje automatické spuštění aplikace při startu serveru a restart při selhání.

Typický soubor služby

Vytvořte soubor /etc/systemd/system/gunicorn.service:

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myproject
# Cesta ke gunicorn ve virtualenv
ExecStart=/var/www/myproject/venv/bin/gunicorn \
    --workers 3 \
    --bind unix:/run/gunicorn.sock \
    myproject.wsgi:application
# Automatický restart při selhání
Restart=always
RestartSec=5
# Proměnné prostředí
EnvironmentFile=/var/www/myproject/.env
[Install]
WantedBy=multi-user.target

Správa služby

# Znovu načíst konfiguraci systemd
sudo systemctl daemon-reload
# Povolit automatické spuštění
sudo systemctl enable gunicorn
# Spustit službu
sudo systemctl start gunicorn
# Zkontrolovat stav
sudo systemctl status gunicorn
# Zobrazit logy
sudo journalctl -u gunicorn -f

Parametr Restart=always spolu s RestartSec=5 zaručuje, že služba se automaticky spustí 5 sekund po jakémkoliv selhání.

Nginx jako reverse proxy

Nginx přijímá požadavky od klientů a předává je Gunicornu. Také servíruje statické soubory a zajišťuje SSL šifrování.

Konfigurace pro Django

# /etc/nginx/sites-available/myproject
upstream gunicorn {
    server unix:/run/gunicorn.sock fail_timeout=0;
}
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL certifikáty (Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # Statické soubory
    location /static/ {
        alias /var/www/myproject/staticfiles/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
    
    # Media soubory (uploads)
    location /media/ {
        alias /var/www/myproject/media/;
        expires 7d;
    }
    
    # Proxy na Gunicorn
    location / {
        proxy_pass http://gunicorn;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        proxy_connect_timeout 30s;
        proxy_read_timeout 30s;
    }
}
# Aktivovat konfiguraci
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Konfigurace pro Flask

Pro Flask je konfigurace Nginx téměř identická. Hlavní rozdíl je v příkazu Gunicorn:

# Django
gunicorn myproject.wsgi:application --workers 3 --bind unix:/run/gunicorn.sock
# Flask
gunicorn app:app --workers 3 --bind unix:/run/gunicorn.sock
# Flask s factory pattern (create_app)
gunicorn "app:create_app()" --workers 3 --bind unix:/run/gunicorn.sock

Kde app:app znamená: soubor app.py, proměnná app (Flask instance).

PostgreSQL vs MySQL

Pro Django doporučujeme PostgreSQL v 95 % případů. Důvody:

  • Nejlepší podpora v Django — JSONB pole, fulltextové vyhledávání, ArrayField, práce s datovými typy
  • Spolehlivost — lepší zpracování souběžných transakcí, MVCC
  • Rozšiřitelnost — PostGIS pro geodata, TimescaleDB pro time-series
  • Průmyslový standard — většina Python projektů používá Postgres

MySQL používáme pouze pokud je to požadavek klienta nebo dědictví starého kódu.

Connection Pooling

Každý požadavek do Django vytváří spojení s databází. Při vysokém provozu se to stává vážným bottleneck — databáze nezvládá počet současných spojení.

Na úrovni Django (základní řešení):

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydb',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'CONN_MAX_AGE': 60,  # Držet spojení 60 sekund
        'CONN_HEALTH_CHECKS': True,  # Django 4.1+
    }
}

CONN_MAX_AGE obvykle nastavujeme na 60–300 sekund. To umožňuje znovu používat spojení mezi požadavky.

Při vysokém provozu — PgBouncer:

Pokud CONN_MAX_AGE nestačí nebo vidíte chyby „too many connections", nastavte PgBouncer mezi Django a databázi. Udržuje pool spojení a rozděluje je mezi workery.

# Instalace PgBouncer
sudo apt install pgbouncer
# Konfigurace /etc/pgbouncer/pgbouncer.ini
[databases]
mydb = host=localhost dbname=mydb
[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 20

💡 Reálný případ: Projekt na Flask, kde každý požadavek vytvářel nové připojení k DB. Výsledek: 504 Gateway Timeout pod zátěží, doba odezvy ~1,2 sekundy. Po implementaci PgBouncer (connection pooling) doba odezvy klesla na 150 ms — zlepšení 8×.

Docker v produkci

Rozhodně doporučujeme. Docker zajišťuje identické prostředí vývoje a produkce — „works on my machine" přestává být problémem. Nasazení se stává předvídatelným a opakovatelným.

Výběr základního obrazu

Doporučujeme python:3.12-slim:

  • alpine — často vytváří problémy s kompilací C knihoven (psycopg2, numpy, Pillow, cryptography). Build může trvat mnohem déle kvůli kompilaci s musl libc
  • slim — ideální vyvážení mezi velikostí (~150 MB) a stabilitou. Používá glibc, všechny knihovny se instalují bez problémů
  • plný obraz — pouze pokud potřebujete specifické systémové balíčky (ffmpeg, imagemagick atd.)

Příklad Dockerfile

FROM python:3.12-slim
# Proměnné prostředí pro Python
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Systémové závislosti
RUN apt-get update && apt-get install -y \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Nejdříve zkopírujeme requirements pro cachování vrstev
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Pak kód aplikace
COPY . .
# Vytvoříme neprivilegovaného uživatele
RUN useradd -m appuser && chown -R appuser:appuser /app
USER appuser
# Sběr statiky
RUN python manage.py collectstatic --noinput
# Spuštění
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "myproject.wsgi:application"]

Docker Compose pro produkci

version: '3.8'
services:
  web:
    build: .
    restart: always
    env_file: .env
    depends_on:
      - db
      - redis
    networks:
      - backend
    
  db:
    image: postgres:16
    restart: always
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    networks:
      - backend
  
  redis:
    image: redis:7-alpine
    restart: always
    networks:
      - backend
  nginx:
    image: nginx:alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./staticfiles:/var/www/static:ro
      - ./certbot/conf:/etc/letsencrypt:ro
    depends_on:
      - web
    networks:
      - backend
networks:
  backend:
volumes:
  postgres_data:

Důležité praktiky pro Docker

  • Multi-stage builds — pro zmenšení velikosti finálního obrazu
  • Health checks — pro automatický restart nezdravých kontejnerů
  • .dockerignore — vylučte .git, __pycache__, .env, venv
  • Neukládejte data v kontejneru — používejte volumes pro DB a media soubory

Celery pro úlohy na pozadí

Pokud požadavek do Django trvá déle než 30 sekund — je to signál přesunout úlohu do Celery. Gunicorn worker je blokován po dobu vykonávání požadavku, a při dlouhých úlohách rychle dojdou volné workery.

Typické kandidáty pro Celery:

  • Odesílání e-mailů (zejména hromadné rozesílky)
  • Zpracování obrázků (resize, watermark, optimalizace)
  • Generování reportů (PDF, Excel)
  • Volání externích API (platební systémy, doručování)
  • Import/export dat (CSV, XML)
  • Video/audio konverze
  • Synchronizace s CRM/ERP

Základní nastavení

# settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Europe/Prague'
# Limity pro prevenci přetížení
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
CELERY_TASK_ACKS_LATE = True

Příklad úlohy

# tasks.py
from celery import shared_task
from django.core.mail import send_mail
@shared_task
def send_welcome_email(user_id):
    from users.models import User
    user = User.objects.get(id=user_id)
    send_mail(
        'Vítejte!',
        'Děkujeme za registraci.',
        'noreply@example.com',
        [user.email],
    )
# Volání ve view
send_welcome_email.delay(user.id)  # Asynchronně

Systemd služba pro Celery worker

# /etc/systemd/system/celery.service
[Unit]
Description=Celery Worker
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myproject
EnvironmentFile=/var/www/myproject/.env
ExecStart=/var/www/myproject/venv/bin/celery \
    -A myproject worker \
    --loglevel=info \
    --concurrency=4
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

Pro periodické úlohy (cron-like) přidejte Celery Beat jako samostatnou službu s celery -A myproject beat.

Monitoring a logování

Produkce bez monitoringu je létání naslepo. Když něco spadne, dozvíte se to od uživatelů, ne z alertů.

Logování v Django

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'file': {
            'level': 'WARNING',
            'class': 'logging.FileHandler',
            'filename': '/var/log/django/app.log',
            'formatter': 'verbose',
        },
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'root': {
        'handlers': ['file', 'console'],
        'level': 'INFO',
    },
}

Sentry pro sledování chyb

Sentry automaticky sbírá exceptions z produkce a posílá alerty. Neocenitelný nástroj pro ladění.

# Instalace
pip install sentry-sdk
# settings.py
import sentry_sdk
sentry_sdk.init(
    dsn="https://xxx@sentry.io/xxx",
    traces_sample_rate=0.1,  # 10 % transakcí pro performance monitoring
    environment="production",
)

Health checks

Endpoint pro kontrolu stavu aplikace — užitečné pro load balancery a monitoring:

# Django urls.py
from django.http import JsonResponse
def health_check(request):
    # Kontrola DB
    from django.db import connection
    try:
        connection.ensure_connection()
    except Exception as e:
        return JsonResponse({'status': 'error', 'db': str(e)}, status=500)
    
    return JsonResponse({'status': 'ok'})
urlpatterns = [
    path('health/', health_check),
    # ...
]

Metriky pro Prometheus/Grafana

Pro seriózní monitoring použijte django-prometheus nebo statsd:

  • Počet požadavků za sekundu
  • Doba odezvy (p50, p95, p99)
  • Počet chyb
  • Využití paměti workerů

Časté chyby

❌ Spuštění Django pod rootem

Nikdy nespouštějte aplikaci jako root. Vytvořte samostatného uživatele (www-data nebo django) s minimálními právy. Pokud je aplikace kompromitována, útočník získá pouze omezená práva, ne plnou kontrolu nad serverem.

❌ DEBUG = True v produkci

Při chybách Django zobrazuje veškerý kód, cesty k souborům, hodnoty proměnných, SQL dotazy. To je přímá bezpečnostní hrozba — útočník vidí vnitřní strukturu aplikace. Vždy zkontrolujte DEBUG před nasazením.

❌ Chybějící logování

Když něco spadne v produkci a v lozích je prázdno — ladění se stává noční můrou. Nakonfigurujte LOGGING v settings.py, logujte chyby do souboru nebo centralizovaného systému. Použijte Sentry pro sledování exceptions v reálném čase.

❌ Media soubory ve složce s kódem

Ukládání uploads ve složce s kódem znemožňuje horizontální škálování a komplikuje nasazení v Docker. Použijte S3-kompatibilní úložiště (AWS S3, MinIO, DigitalOcean Spaces) nebo samostatný volume.

❌ Tajemství v kódu

SECRET_KEY, hesla DB, API klíče v settings.py nebo commitnuté do Gitu — klasická chyba. Historii Gitu nelze úplně vyčistit, tajemství zůstanou přístupná. Používejte environment variables od prvního dne projektu.

❌ Chybějící migrace v produkci

Spuštění python manage.py migrate v produkci bez testování — riziko ztráty dat nebo výpadku. Vždy testujte migrace na staging prostředí, dělejte backup databáze před migrací.

🐍 Připraveni spustit Python projekt?

VPS pro start nebo Dedicated pro vysokou zátěž — řešení, která rostou s vámi.

💻 Cloud (VPS) Hosting

  • Od 19,95 $/měs — Začněte v malém, škálujte okamžitě
  • KVM virtualizace — Garantované zdroje bez oversellingu
  • Okamžité upgrady — Bez výpadku
  • NVMe úložiště — Rychlý výkon
  • 24/7 podpora — Odpověď do 10 min

🖥️ Dedikované servery

  • Od 200 $/měs — Moderní konfigurace
  • Vlastní konfigurace — Intel nebo AMD, nejnovější modely
  • Více lokalit — EU + USA
  • 99,9% uptime — Spolehlivost
  • DDoS ochrana — Zahrnuto
  • Bezplatná migrace — Pomůžeme
  • Private Cloud — Proxmox, VMware, OpenStack

💬 Nejste si jisti, kterou variantu potřebujete?
💬 Napište nám — pomůžeme se vším!

Často kladené otázky

Gunicorn nebo uWSGI pro produkci?

Pro 90 % projektů doporučujeme Gunicorn — jednodušší konfigurace, je standardem pro Docker kontejnery, má srozumitelnou dokumentaci. uWSGI vyberte pouze pokud potřebujete jeho specifické funkce: vlastní binární protokol uwsgi, vestavěné cachování, emperor mode pro správu více aplikací.

PostgreSQL nebo MySQL pro Django?

PostgreSQL v 95 % případů. Django má nejlepší podporu právě pro Postgres: JSONB pole pro ukládání JSON bez samostatných tabulek, fulltextové vyhledávání bez Elasticsearch, ArrayField, HStoreField. MySQL pouze pokud je to požadavek klienta nebo migrace existujícího projektu.

Kolik workerů pro Gunicorn?

Výchozí vzorec: (2 × CPU jader) + 1. Pro 4jádrový server to je 9 workerů. Pro I/O-bound úlohy (mnoho dotazů do DB) můžete zvýšit. Pro CPU-bound (zpracování obrázků) — držte se blíže počtu jader. Vždy testujte pod reálnou zátěží.

Který Docker obraz vybrat?

python:3.12-slim — optimální vyvážení mezi velikostí (~150 MB) a stabilitou. Alpine často vytváří problémy s kompilací C knihoven kvůli musl libc — psycopg2, numpy, Pillow se nemusí sestavit nebo sestavení trvá hodiny.

Co dělat při 504 Gateway Timeout?

Obvykle problém v dlouhých dotazech do DB nebo externích služeb. Zkontrolujte PostgreSQL slow query log, implementujte connection pooling (PgBouncer), přesuňte náročné úlohy do Celery, použijte Redis pro cachování častých dotazů.

Jak bezpečně aktualizovat závislosti?

Neaktualizujte vše najednou. Použijte pip-audit pro kontrolu zranitelností, aktualizujte jeden balíček najednou, testujte na staging. Pro kritické bezpečnostní záplaty — aktualizujte okamžitě po testování.

Jak škálovat Django/Flask aplikaci?

Horizontálně: přidejte více serverů za load balancer. Vertikálně: zvyšte prostředky serveru. Povinně: přesuňte sessions do Redis, media soubory do S3, databázi na samostatný server. Použijte CDN pro statiku.

Contents

Sdílejte tento článek

MANAGED VPS STARTING AT

$19 95 / mo

NEW INTEL XEON BASED SERVERS

$80 / mo

CDN STARTING AT

$0 / mo

 

Tento web používá cookies. Používáním tohoto webu souhlasíte s politikou ochrany osobních údajů.