プラットフォームの背後にあるインフラストラクチャ
のようなプラットフォームを構築する イベントをプレイする それはアプリケーションコードを書くことだけを意味するのではなく、インフラストラクチャを設計することも意味します。 それは保証します 信頼性, 再現性 e 導入の容易さ。ローカル開発環境から本番 VPS まで、 各インフラストラクチャ コンポーネントは、導入時間を短縮し、最小限に抑えられるように設計されています。 手動エラーを防止し、サービスが常に利用できるようにします。
この記事では、Play The Event の DevOps スタック全体について説明します: コンテナ化から systemd サービスから自動化スクリプトまで、SSL を使用した Docker Compose から Nginx セットアップまで、 データベースの移行と Redis キャッシュの管理まで。
この記事でわかること
- MySQL、Redis、phpMyAdmin、Redis Commander を使用した開発環境用の Docker Compose
- SSL Let's Encrypt、レート制限、セキュリティ ヘッダーを備えたリバース プロキシとしての Nginx
- バックエンドとフロントエンドを自動的に開始するための systemd サービス
- デプロイ、起動、停止、再起動、メンテナンス用の 18 個以上の Bash スクリプト
- 199 MySQL スキーマ進化のための Flyway 移行
- 256MB 構成と allkeys-lru ポリシーを備えた Redis
- サービスのログ管理と健全性監視
Docker Compose: 開発環境
の開発環境は、 イベントをプレイする Docker Compose を介して完全にコンテナ化されています。 4 つの統合されたサービス すべての開発者が 1 つのコマンドでスタック全体を起動できるようにします。 MySQL、Redis、または管理ツールを手動でインストールして構成することを心配する必要はありません。
version: '3.8'
services:
# MySQL 8.4.3 - Database principale
mysql:
image: mysql:8.4.3
container_name: management-events-mysql
restart: unless-stopped
environment:
MYSQL_DATABASE: management_events_db
MYSQL_USER: events_user
TZ: Europe/Rome
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./backend/src/main/resources/db/init:/docker-entrypoint-initdb.d
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --max_connections=200
- --innodb_buffer_pool_size=1G
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
# Redis 7.4.1 - Cache e sessioni
redis:
image: redis:7.4.1-alpine
container_name: management-events-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: >
redis-server --appendonly yes
--maxmemory 256mb
--maxmemory-policy allkeys-lru
# phpMyAdmin - Gestione database via web
phpmyadmin:
image: phpmyadmin:5.2
container_name: management-events-phpmyadmin
ports:
- "8081:80"
depends_on:
mysql:
condition: service_healthy
# Redis Commander - Gestione cache via web
redis-commander:
image: rediscommander/redis-commander:latest
container_name: management-events-redis-commander
environment:
REDIS_HOSTS: local:redis:6379
ports:
- "8082:8081"
depends_on:
redis:
condition: service_healthy
Docker 構成の重要な側面は次のとおりです。
- ヘルスチェック: MySQL と Redis には両方ともヘルスチェックが組み込まれています。依存サービス (phpMyAdmin、Redis Commander) は、基本サービスの準備ができるまで待機してから開始します。
- 永続ボリューム:
mysql_dataeredis_dataコンテナーの再起動後もデータが存続することを確認する - 最適化された MySQL:
utf8mb4Unicode を完全にサポートするには、innodb_buffer_pool_size=1G最適なパフォーマンスを実現するために、最大 200 の同時接続が可能 - AOF を使用した Redis:
appendonly yesディスクの永続性を有効にします。方針allkeys-lru最も最近使用されていないキーを削除することで、メモリ不足を回避します。
開発サービスのドア
- 3306 - MySQL 8.4.3 (マスターデータベース)
- 6379 - Redis 7.4.1 (キャッシュとセッション)
- 8080 - Spring Boot バックエンド (REST API)
- 4200 - Angular フロントエンド (サーバー開発)
- 8081 - phpMyAdmin (データベース管理)
- 8082 - Redis Commander (キャッシュ管理)
Nginx: SSL を使用したリバース プロキシ
運用環境では、Nginx は次のように機能します。 リバースプロキシ すべてのサービスの前で イベントをプレイする。 SSL 終了、リクエスト ルーティング、gzip 圧縮、キャッシュを処理します。 静的資産の保護とレート制限による保護。
# Upstream per il backend Spring Boot
upstream backend_api {
server localhost:8080 fail_timeout=5s max_fails=3;
keepalive 32;
}
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/m;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=10r/m;
server {
listen 443 ssl http2;
server_name playtheevent.com www.playtheevent.com;
# SSL Let's Encrypt
ssl_certificate /etc/letsencrypt/live/playtheevent.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/playtheevent.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css application/json
application/javascript text/xml image/svg+xml;
# Backend API con rate limiting
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend_api;
proxy_http_version 1.1;
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;
}
# Rate limiting stretto per login
location /api/auth/login {
limit_req zone=login_limit burst=5 nodelay;
proxy_pass http://backend_api;
}
# Frontend Angular (SSR o static)
location / {
try_files $uri $uri/ /index.html;
}
# Asset statici con cache lunga
location ~* \.(js|css|png|jpg|svg|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
ネットワークレベルのセキュリティ
Nginx 構成では、いくつかの保護戦略が実装されています。
- 2 レベルのレート制限: 一般的な API は IP ごとに 1 分あたり 100 リクエストに制限されていますが、認証エンドポイントには 1 分あたり 10 リクエストというより厳しい制限があり、超過した場合は HTTP 429 応答が返されます。
- Let's Encrypt を使用した SSL: Certbot による自動更新を備えた無料の証明書。スクリプト
setup-ssl.shDNS検証、Certbotのインストール、証明書の生成を自動化します。 - セキュリティヘッダー: クリックジャッキングに対する保護 (
X-Frame-Options)、MIME スニッフィング (X-Content-Type-Options) および XSS (X-XSS-Protection) - 機密ファイルのロック: で始まるファイルへのリクエスト
.(として.env,.git) は自動的にブロックされます
ヘルスチェックエンドポイント
Nginx はエンドポイントを公開します /health 外部モニタリング専用。このエンドポイント
バックエンドに触れることなく単純な応答を返すため、システムの監視が可能になります
リバース プロキシがアクティブであることを確認します。
# Health check endpoint (risposta diretta da Nginx)
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Nginx status per monitoraggio (solo localhost)
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
Systemd: 自動開始サービス
Spring Boot バックエンドと Angular フロントエンドは VPS 上の systemd サービスとして管理されます Ubuntu 24.04。これにより、クラッシュ後にサービスが自動的に再起動されます。 またはサーバーの再起動。
[Unit]
Description=Play the Event - Backend Spring Boot API
After=network.target mysql.service
Wants=mysql.service
[Service]
Type=simple
User=federicocalo
WorkingDirectory=/home/ubuntu/managementevents/backend
# Environment
Environment="JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64"
Environment="SPRING_PROFILES_ACTIVE=prod"
EnvironmentFile=/home/ubuntu/managementevents/backend/.env.prod
# Esecuzione con JAR precompilato
ExecStart=/usr/bin/java -jar target/management-events-backend.jar
# Restart policy
Restart=on-failure
RestartSec=10s
StartLimitInterval=5min
StartLimitBurst=3
# Resource limits
LimitNOFILE=65536
LimitNPROC=4096
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=play-the-event-backend
# Security
NoNewPrivileges=true
PrivateTmp=true
# Graceful shutdown
TimeoutStopSec=30s
KillMode=mixed
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target
[Unit]
Description=Play the Event - Frontend Angular
After=network.target
[Service]
Type=simple
User=federicocalo
WorkingDirectory=/home/ubuntu/managementevents/frontend
# Environment
Environment="NODE_ENV=production"
# Angular serve (SSR o static)
ExecStart=/usr/bin/npm start
# Restart policy
Restart=on-failure
RestartSec=10s
StartLimitInterval=5min
StartLimitBurst=3
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=play-the-event-frontend
# Security
NoNewPrivileges=true
PrivateTmp=true
# Graceful shutdown
TimeoutStopSec=15s
KillMode=mixed
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target
systemd 構成の重要な側面:
- 依存関係: バックエンドが宣言する
After=mysql.serviceeWants=mysql.serviceSpring Boot アプリケーションの前に MySQL が開始されていることを確認します。 - 自動再起動:
Restart=on-failureconRestartSec=10s無限ループを避けるため、クラッシュ後にサービスを自動的に再起動しますが、試行回数は 5 分間に 3 回に制限されています - 環境変数: 機密性の高い構成はからロードされます
.env.prodを通してEnvironmentFile、資格情報をソースコードに含めない - 安全性:
NoNewPrivileges=true権限昇格を防ぎます。PrivateTmp=trueサービスの一時ディレクトリを分離します - 正常なシャットダウン:
KillSignal=SIGTERMconKillMode=mixed最初に終了シグナルを親プロセスに送信し、次にタイムアウト後に子プロセスを強制的に停止します。
自動展開スクリプト
Play The Event の展開は、次のスイートによって管理されます。 18 個以上の Bash スクリプト これにより、OVHcloud VPS 上のアプリケーションのライフサイクルのあらゆる側面が自動化されます。
デプロイメントスクリプト
deploy-all.shdeploy-backend.shdeploy-frontend.shdeploy-analytics.shrestart-all.shstart-all.shstop-all.sh
セットアップとメンテナンスのスクリプト
setup-nginx.shsetup-ssl.shsetup-mysql-databases.shsetup-analytics.shupdate-nginx-ssr.shupdate-vps-config.shcleanup-logs-vps.shwatch-logs.sh
オーケストレーションされたデプロイ:deploy-all.sh
メインスクリプト deploy-all.sh すべてのサービスの展開を調整します
シーケンシャルまたはパラレル実行、サービスの選択的スキップをサポートし、
実行時間の詳細なレポート。
# Deploy completo (sequenziale)
./scripts/deploy-all.sh
# Deploy parallelo (più veloce)
./scripts/deploy-all.sh --parallel
# Solo frontend e analytics (salta backend)
./scripts/deploy-all.sh --skip-be
# Continua anche se un deploy fallisce
./scripts/deploy-all.sh --continue
デプロイ-all.sh フローには以下が含まれます。
- 引数の解析: のサポート
--parallel,--skip-be,--skip-fe,--skip-ai,--continue - 順次または並行デプロイメント: 並列モードでは、3 つのサービスがバックグラウンド プロセスとして開始され、すべてのサービスが完了するのを待ちます。
- ヘルスチェック: 導入後、各サービスがそれぞれの正常性エンドポイントを介して正しく応答することを確認します。
- 最終レポート: 各サービスのステータス (成功、エラー、スキップ) と実行時間を表示します。
バックエンドのデプロイメント
スクリプト deploy-backend.sh バックエンド展開ライフサイクル全体を管理します
8 つの自動化されたステップで:
# Step 1: Verifica prerequisiti (Java 21, Maven, MySQL)
# Step 2: Navigazione alla directory backend
# Step 3: Caricamento variabili da .env.prod + test connessione DB
# Step 4: Build Maven (mvnw clean package -DskipTests)
# Step 5: Verifica database e migrazioni Flyway
# Step 6: Creazione/aggiornamento servizio systemd
# Step 7: Restart servizio con verifica stato
# Step 8: Health check con retry (max 15 tentativi, 2s intervallo)
# Comandi utili post-deploy:
sudo systemctl status management-events-backend
sudo journalctl -u management-events-backend -f
curl http://localhost:8080/api/health
OVHcloud VPS の管理
プラットフォームは、Ubuntu 24.04 を搭載した OVHcloud VPS 上で実行されます。スクリプト start-all.sh,
stop-all.sh e restart-all.sh ライフサイクル全体を管理する
VPS 上のサービスの詳細。
# Ordine di avvio dei servizi:
# [1/5] Verifica e avvio MySQL
systemctl start mysql
mysql -u root -e "USE management_events_system;"
# [2/5] Stop servizi esistenti (pulizia)
systemctl stop management-events-backend
systemctl stop management-events-frontend
# [3/5] Avvio backend Spring Boot
systemctl start management-events-backend
# Attesa health check su localhost:8080/api/health
# [4/5] Avvio frontend Angular
systemctl start management-events-frontend
# Attesa health check su localhost:4200
# [5/5] Verifica e reload Nginx
systemctl reload nginx
# Verifica proxy funzionante
クリティカルなブート順序
ブート順序は重要です。その前に MySQL が完全に動作する必要があります。
Spring Boot バックエンドが接続を試行します。接続しない場合、Flyway は実行に失敗します。
移住。このため start-all.sh MySQL が有効であることを検証するだけでなく、
バックエンドに進む前に、アクティブであるだけでなく、特定のデータベースに到達可能であることも確認してください。
Flyway を使用したデータベースの移行
MySQL データベース スキーマ イベントをプレイする を通じて管理されています 199 フライウェイの移行 バージョン化されています。スキーマへの変更 バックエンドの起動時に自動的に実行される番号付きの SQL 移行です。 スプリングブート。
backend/src/main/resources/db/migration/
├── V1__create_users_table.sql
├── V2__create_events_table.sql
├── V3__create_participants_table.sql
├── ...
├── V98__create_analytics_tables.sql
├── V99__create_tipologie_luogo_table.sql
├── V100__create_luoghi_table.sql
├── V101__create_festival_table.sql
├── V102__create_giornate_festival_table.sql
└── ... (199 migrazioni totali)
Flyway は、テーブル内ですでに実行された移行を追跡します。 flyway_schema_history。
起動時に、バックエンドはクラスパスに存在する移行とすでに実行された移行を比較します。
新しいもののみを適用します。このアプローチにより、次のことが保証されます。
- 段階的な進化: このスキームはデータを失うことなく徐々に進化します
- 再現性: すべての移行を順番に実行することで、どのデータベース インスタンスでも現在の状態に到達できます。
- トレーサビリティ: 各スキーマ変更は、作成者、日付、変更理由が記載された Git リポジトリ内の SQL ファイルです。
- 安全性: マイグレーションはべき等であり、実行後に変更することはできません (Flyway はチェックサムをチェックします)
Redis: キャッシュとセッションの管理
Redis は Play The Event のアーキテクチャで重要な役割を果たし、キャッシュとキャッシュの両方を管理します 頻繁なクエリとユーザー セッション。構成は次のように最適化されています。 メモリが制限された環境。
# Avvio Redis con configurazione personalizzata
redis-server \
--appendonly yes \
--maxmemory 256mb \
--maxmemory-policy allkeys-lru
# appendonly yes → Persistenza AOF su disco
# maxmemory 256mb → Limite memoria massima
# maxmemory-policy → Eviction delle chiavi meno usate
方針 allkeys-lru (最も最近使用されていない) が選択された理由 イベント管理のコンテキストでは、一般に最新のデータが最も関連性があります。 アクティブなイベント、現在のセッション、および最も頻繁に尋ねられるクエリが優先されます。 古いデータやほとんど参照されないデータのキャッシュ。
プラットフォームでの Redis の使用
- クエリキャッシュ: 最も頻繁なクエリの結果 (パブリック イベントのリスト、イベントの詳細) がキャッシュされ、MySQL の負荷が軽減されます。
- ユーザーセッション: バックエンドの水平スケーリングをサポートするために、セッション データは Redis に保存されます
- レート制限: API レート制限カウンターは、自動 TTL を使用して Redis で処理されます。
- 一時データ: 電子メール検証トークン、OTP コード、自動期限切れの Stripe チェックアウト データ
ログ管理
スクリプト スイートには、ログ管理専用のツールが含まれています。 運用環境でのデバッグや、VPS 上のディスク容量の維持に使用します。
リアルタイムでログインを視聴する
スクリプト watch-logs.sh ログストリーミング用のインタラクティブなメニューを提供します
リアルタイムで、すべてのサービスをカバーする 9 つのオプションがあります。
Seleziona quale log visualizzare:
1) Backend (systemd journal)
2) Backend (application log)
3) Backend (error log)
4) Frontend (systemd journal)
5) Frontend (application log)
6) Frontend (error log)
7) Nginx (access log)
8) Nginx (error log)
9) Tutti i backend logs (multipli)
オプション 9 の用途 multitail (利用可能な場合) 同時に表示する
systemd ログ、アプリケーション ログ、およびエラー ログには色付きのプレフィックスが付いています。マルチテールが存在しない場合、
フォールバック スクリプトは複数のプロセスを結合します tail -f 接頭辞付き
[SYSTEMD], [APP] e [ERROR].
自動ログクリーニング
スクリプト cleanup-logs-vps.sh VPS 上のログのクリーニングを自動化します。
ログ ディレクトリのスキャン、ファイルの削除、systemd ジャーナルのクリーンアップ
7日以上経過しています。
# Directory monitorate per la pulizia
LOG_DIRS=(
"/var/log/management-events"
"/home/ubuntu/managementevents/logs"
"/opt/management-events/logs"
)
# Per ogni directory: conta file, calcola dimensione, elimina
# Pulisce anche journalctl logs > 7 giorni
sudo journalctl --vacuum-time=7d
# Mostra spazio disco rimanente
df -h /
Let's Encrypt による SSL 設定
スクリプト setup-ssl.sh ドメインのHTTPS構成全体を自動化します
playtheevent.com。このプロセスには、DNS 検証、Certbot のインストール、
証明書の生成と自動更新の構成。
# Configurazione
DOMAIN="playtheevent.com"
WWW_DOMAIN="www.playtheevent.com"
# Step 1: Verifica DNS
# - Recupera IP della VPS (curl ifconfig.me)
# - Verifica che il dominio punti all'IP corretto (dig +short)
# - Controlla sia @ che www
# Step 2: Installazione Certbot
sudo apt install -y certbot python3-certbot-nginx
# Step 3: Generazione certificati
sudo certbot --nginx \
-d playtheevent.com \
-d www.playtheevent.com \
--email admin@playtheevent.com \
--agree-tos
# Step 4: Verifica rinnovo automatico (cron)
sudo certbot renew --dry-run
モニタリングとヘルスチェック
Play The Event の監視システムはすべてのサービスの健全性をチェックします 各展開後に実行でき、オンデマンドで実行できます。
# Health check integrato nel deploy-all.sh:
# Backend - verifica risposta HTTP 200
curl -s -o /dev/null -w "%{http_code}" \
http://localhost:8080/api/health
# Frontend SSR - verifica risposta HTTP 200/301/302
curl -s -o /dev/null -w "%{http_code}" \
http://localhost:4200
# Analytics - verifica risposta HTTP 200
curl -s -o /dev/null -w "%{http_code}" \
http://localhost:8001/health
# Nginx - verifica proxy funzionante
curl -s https://playtheevent.com/health
最終的な展開レポートには、ステータスが明確に表示されます。
╔════════════════════════════════════════════╗
║ REPORT DEPLOY ║
╚════════════════════════════════════════════╝
Stato Servizi:
✓ Backend SUCCESS (2m 34s)
✓ Frontend SUCCESS (1m 12s)
✓ Analytics SUCCESS (45s)
Tempo totale: 4m 31s
URL di accesso:
• Frontend: https://playtheevent.com
• API: https://playtheevent.com/api
• Analytics: http://localhost:8001/docs
インフラストラクチャの概要
完全なインフラストラクチャ スタック
- VPS: OVHcloud Ubuntu 24.04 LTS
- コンテナ化: 開発用 Docker Compose (MySQL 8.4.3、Redis 7.4.1、phpMyAdmin、Redis Commander)
- ウェブサーバー: SSL Let's Encrypt、レート制限、gzip 圧縮を備えたリバース プロキシとしての Nginx
- プロセスマネージャー: systemd によるバックエンドとフロントエンドの自動起動と障害時の再起動
- データベース: MySQL 8.4.3 と 199 の Flyway 移行のバージョン管理
- キャッシュ: Redis 7.4.1 (256 MB、allkeys-lru ポリシー、AOF 永続性)
- オートメーション: 導入、セットアップ、メンテナンス、監視用の 18 個以上の Bash スクリプト
- SSL: Certbot による自動更新で Let's Encrypt
のインフラストラクチャ イベントをプレイする 単一の開発者によって管理されるプロジェクトでもレベルを設定できる方法を示します。 スクリプトのおかげで、大規模なチームに匹敵する自動化と信頼性を実現 適切に構造化された systemd サービスと堅牢な Nginx セットアップ。
ソースコードは次の場所から入手できます。 GitHub.







