fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
8
deployment/stacks/redis/.env.example
Normal file
8
deployment/stacks/redis/.env.example
Normal file
@@ -0,0 +1,8 @@
|
||||
# Redis Stack Environment Configuration
|
||||
# Copy to .env and adjust for your environment
|
||||
|
||||
# Redis Password (REQUIRED in production)
|
||||
REDIS_PASSWORD=your-secure-redis-password-here
|
||||
|
||||
# Timezone
|
||||
TZ=Europe/Berlin
|
||||
291
deployment/stacks/redis/README.md
Normal file
291
deployment/stacks/redis/README.md
Normal file
@@ -0,0 +1,291 @@
|
||||
# Redis Stack
|
||||
|
||||
External Redis Stack for the Custom PHP Framework application.
|
||||
|
||||
## Overview
|
||||
|
||||
This Redis Stack provides:
|
||||
- **Cache Backend**: Application-level caching (sessions, query results, objects)
|
||||
- **Queue Backend**: Background job queue storage
|
||||
- **Session Storage**: User session persistence
|
||||
- **Rate Limiting**: Request rate limiting storage
|
||||
|
||||
**Architecture Pattern**: Following the same external stack pattern as PostgreSQL for consistency and separation of concerns.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Create environment configuration
|
||||
cp .env.example .env
|
||||
|
||||
# 2. Set Redis password
|
||||
echo "REDIS_PASSWORD=$(openssl rand -base64 32)" >> .env
|
||||
|
||||
# 3. Create app-internal network (if not exists)
|
||||
docker network create app-internal
|
||||
|
||||
# 4. Start Redis Stack
|
||||
docker compose up -d
|
||||
|
||||
# 5. Verify health
|
||||
docker compose ps
|
||||
docker compose exec redis-stack redis-cli ping
|
||||
# Expected: PONG
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```env
|
||||
REDIS_PASSWORD=your-secure-password # Required for production
|
||||
TZ=Europe/Berlin # Timezone for logs
|
||||
```
|
||||
|
||||
### Redis Configuration
|
||||
|
||||
Redis configuration is in `redis.conf` with production-optimized settings:
|
||||
|
||||
**Persistence:**
|
||||
- RDB Snapshots: 15min/5min/1min intervals
|
||||
- AOF (Append Only File): `everysec` fsync policy
|
||||
- Combined persistence for data durability
|
||||
|
||||
**Memory Management:**
|
||||
- Max Memory: 512MB (configurable)
|
||||
- Eviction Policy: `allkeys-lru` (Least Recently Used)
|
||||
- Lazy freeing for async deletion
|
||||
|
||||
**Performance:**
|
||||
- TCP keepalive: 300s
|
||||
- Active rehashing enabled
|
||||
- Optimized client output buffers
|
||||
|
||||
### Security
|
||||
|
||||
**Password Protection:**
|
||||
```bash
|
||||
# Set via Docker Secrets (recommended)
|
||||
echo "your-redis-password" | docker secret create redis_password -
|
||||
|
||||
# Or via environment variable
|
||||
REDIS_PASSWORD=your-password docker compose up -d
|
||||
```
|
||||
|
||||
**Network Isolation:**
|
||||
- Only accessible via `app-internal` Docker network
|
||||
- Not exposed to public internet
|
||||
- Protected mode enabled
|
||||
|
||||
## Health Monitoring
|
||||
|
||||
```bash
|
||||
# Check Redis health
|
||||
docker compose exec redis-stack redis-cli ping
|
||||
|
||||
# Get Redis info
|
||||
docker compose exec redis-stack redis-cli info
|
||||
|
||||
# Monitor real-time activity
|
||||
docker compose exec redis-stack redis-cli monitor
|
||||
|
||||
# Check memory usage
|
||||
docker compose exec redis-stack redis-cli info memory
|
||||
|
||||
# View slow queries
|
||||
docker compose exec redis-stack redis-cli slowlog get 10
|
||||
```
|
||||
|
||||
## Integration with Application Stack
|
||||
|
||||
### Production Setup
|
||||
|
||||
```bash
|
||||
# In application root directory
|
||||
docker compose \
|
||||
-f docker-compose.base.yml \
|
||||
-f docker-compose.production.yml \
|
||||
-f docker-compose.postgres-override.yml \
|
||||
-f docker-compose.redis-override.yml \
|
||||
up -d
|
||||
```
|
||||
|
||||
### Application Environment Variables
|
||||
|
||||
```env
|
||||
REDIS_HOST=redis-stack # Container name from this stack
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=your-password # Same as Redis Stack password
|
||||
```
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Backup
|
||||
|
||||
Redis persistence is handled automatically via:
|
||||
- **RDB**: Snapshot backups in `/data/dump.rdb`
|
||||
- **AOF**: Append-only log in `/data/appendonly.aof`
|
||||
|
||||
**Manual Backup:**
|
||||
```bash
|
||||
# Trigger immediate RDB snapshot
|
||||
docker compose exec redis-stack redis-cli BGSAVE
|
||||
|
||||
# Copy backup files
|
||||
docker cp redis-stack:/data/dump.rdb ./backups/redis-$(date +%Y%m%d).rdb
|
||||
```
|
||||
|
||||
### Restore
|
||||
|
||||
```bash
|
||||
# Stop Redis
|
||||
docker compose stop redis-stack
|
||||
|
||||
# Restore backup
|
||||
docker cp ./backups/redis-backup.rdb redis-stack:/data/dump.rdb
|
||||
|
||||
# Start Redis
|
||||
docker compose start redis-stack
|
||||
```
|
||||
|
||||
### Cleanup
|
||||
|
||||
```bash
|
||||
# Clear specific database
|
||||
docker compose exec redis-stack redis-cli -n 0 FLUSHDB
|
||||
|
||||
# Clear all databases (DANGEROUS!)
|
||||
docker compose exec redis-stack redis-cli FLUSHALL
|
||||
|
||||
# Remove old AOF/RDB files
|
||||
docker compose exec redis-stack sh -c "rm -f /data/*.aof.old /data/*.rdb.old"
|
||||
```
|
||||
|
||||
## Performance Tuning
|
||||
|
||||
### Memory Optimization
|
||||
|
||||
```bash
|
||||
# Check memory fragmentation
|
||||
docker compose exec redis-stack redis-cli info memory | grep fragmentation
|
||||
|
||||
# Defragment if needed (Redis 4.0+)
|
||||
docker compose exec redis-stack redis-cli MEMORY PURGE
|
||||
```
|
||||
|
||||
### Connection Limits
|
||||
|
||||
Adjust `maxclients` in `redis.conf` based on your application needs:
|
||||
```conf
|
||||
maxclients 10000 # Default, increase if needed
|
||||
```
|
||||
|
||||
### Persistence Trade-offs
|
||||
|
||||
**For Cache-Only Usage:**
|
||||
```conf
|
||||
# Disable persistence for maximum performance
|
||||
save ""
|
||||
appendonly no
|
||||
```
|
||||
|
||||
**For Critical Data:**
|
||||
```conf
|
||||
# More frequent snapshots
|
||||
save 300 1
|
||||
save 60 10
|
||||
appendfsync always # Slower but safest
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Issues
|
||||
|
||||
```bash
|
||||
# Test connection from application container
|
||||
docker exec php sh -c 'redis-cli -h redis-stack -a $REDIS_PASSWORD ping'
|
||||
|
||||
# Check network connectivity
|
||||
docker network inspect app-internal
|
||||
```
|
||||
|
||||
### Memory Issues
|
||||
|
||||
```bash
|
||||
# Check current memory usage
|
||||
docker compose exec redis-stack redis-cli info memory
|
||||
|
||||
# View evicted keys
|
||||
docker compose exec redis-stack redis-cli info stats | grep evicted
|
||||
|
||||
# Increase memory limit (edit docker-compose.yml)
|
||||
# deploy.resources.limits.memory: 1G
|
||||
```
|
||||
|
||||
### Performance Issues
|
||||
|
||||
```bash
|
||||
# Check slow queries
|
||||
docker compose exec redis-stack redis-cli slowlog get 10
|
||||
|
||||
# Monitor commands in real-time
|
||||
docker compose exec redis-stack redis-cli monitor
|
||||
|
||||
# Analyze key patterns
|
||||
docker compose exec redis-stack redis-cli --bigkeys
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Network Topology
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ app-internal Network │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────────┐ │
|
||||
│ │ PHP │────────▶│ redis-stack │ │
|
||||
│ │ App │ │ (Cache) │ │
|
||||
│ └──────────┘ └──────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────┐ │
|
||||
│ │ Queue │────────▶ │
|
||||
│ │ Worker │ (Shared Redis) │
|
||||
│ └──────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Data Separation
|
||||
|
||||
**Database Indexes:**
|
||||
- DB 0: Application cache (default)
|
||||
- DB 1: Session storage
|
||||
- DB 2: Queue backend
|
||||
- DB 3: Rate limiting
|
||||
- DB 4-15: Available for other uses
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use passwords** in production
|
||||
2. **Monitor memory usage** - set appropriate `maxmemory` limit
|
||||
3. **Enable persistence** for critical data (sessions, queue)
|
||||
4. **Regular backups** if using Redis as primary data store
|
||||
5. **Network isolation** - never expose Redis port publicly
|
||||
6. **Health checks** - monitor Redis availability
|
||||
7. **Resource limits** - set Docker memory limits
|
||||
8. **Logging** - check Redis logs for issues
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Application Docker Compose](../../docker-compose.production.yml)
|
||||
- [Redis Override Configuration](../../docker-compose.redis-override.yml)
|
||||
- [PostgreSQL Stack](../postgresql/README.md) (similar pattern)
|
||||
- [Redis Official Documentation](https://redis.io/documentation)
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions:
|
||||
- Check Redis logs: `docker compose logs redis-stack`
|
||||
- Test connectivity: `docker compose exec redis-stack redis-cli ping`
|
||||
- Review configuration: `docker compose exec redis-stack redis-cli config get '*'`
|
||||
37
deployment/stacks/redis/docker-compose.yml
Normal file
37
deployment/stacks/redis/docker-compose.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
services:
|
||||
# Redis Cache & Queue Backend
|
||||
redis-stack:
|
||||
image: redis:7-alpine
|
||||
container_name: redis-stack
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- app-internal
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
- ./redis.conf:/usr/local/etc/redis/redis.conf:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
command: >
|
||||
redis-server /usr/local/etc/redis/redis.conf
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 128M
|
||||
|
||||
volumes:
|
||||
redis-data:
|
||||
name: redis-data
|
||||
|
||||
networks:
|
||||
app-internal:
|
||||
external: true
|
||||
81
deployment/stacks/redis/redis.conf
Normal file
81
deployment/stacks/redis/redis.conf
Normal file
@@ -0,0 +1,81 @@
|
||||
# Redis Configuration for Production Stack
|
||||
# Based on Redis 7.x best practices
|
||||
|
||||
# Network Configuration
|
||||
bind 0.0.0.0
|
||||
port 6379
|
||||
tcp-backlog 511
|
||||
timeout 0
|
||||
tcp-keepalive 300
|
||||
|
||||
# General Settings
|
||||
daemonize no
|
||||
supervised no
|
||||
pidfile /var/run/redis.pid
|
||||
loglevel notice
|
||||
databases 16
|
||||
|
||||
# Persistence Configuration
|
||||
# RDB Snapshots
|
||||
# After 900 sec (15 min) if at least 1 key changed
|
||||
save 900 1
|
||||
# After 300 sec (5 min) if at least 10 keys changed
|
||||
save 300 10
|
||||
# After 60 sec if at least 10000 keys changed
|
||||
save 60 10000
|
||||
|
||||
stop-writes-on-bgsave-error yes
|
||||
rdbcompression yes
|
||||
rdbchecksum yes
|
||||
dbfilename dump.rdb
|
||||
dir /data
|
||||
|
||||
# AOF Persistence (Append Only File)
|
||||
appendonly yes
|
||||
appendfilename "appendonly.aof"
|
||||
appendfsync everysec
|
||||
no-appendfsync-on-rewrite no
|
||||
auto-aof-rewrite-percentage 100
|
||||
auto-aof-rewrite-min-size 64mb
|
||||
|
||||
# Memory Management
|
||||
maxmemory 512mb
|
||||
maxmemory-policy allkeys-lru
|
||||
maxmemory-samples 5
|
||||
|
||||
# Lazy Freeing (async deletion)
|
||||
lazyfree-lazy-eviction yes
|
||||
lazyfree-lazy-expire yes
|
||||
lazyfree-lazy-server-del yes
|
||||
replica-lazy-flush yes
|
||||
|
||||
# Security
|
||||
# NOTE: Password should be set via REDIS_PASSWORD environment variable
|
||||
# requirepass will be set via redis-cli CONFIG SET after startup
|
||||
protected-mode yes
|
||||
|
||||
# Limits
|
||||
maxclients 10000
|
||||
|
||||
# Slow Log
|
||||
slowlog-log-slower-than 10000
|
||||
slowlog-max-len 128
|
||||
|
||||
# Advanced Config
|
||||
hash-max-ziplist-entries 512
|
||||
hash-max-ziplist-value 64
|
||||
list-max-ziplist-size -2
|
||||
set-max-intset-entries 512
|
||||
zset-max-ziplist-entries 128
|
||||
zset-max-ziplist-value 64
|
||||
|
||||
# Performance Tuning
|
||||
activerehashing yes
|
||||
client-output-buffer-limit normal 0 0 0
|
||||
client-output-buffer-limit replica 256mb 64mb 60
|
||||
client-output-buffer-limit pubsub 32mb 8mb 60
|
||||
|
||||
# Disable dangerous commands (optional)
|
||||
# rename-command FLUSHDB ""
|
||||
# rename-command FLUSHALL ""
|
||||
# rename-command CONFIG ""
|
||||
Reference in New Issue
Block a user