image url
This commit is contained in:
@@ -527,67 +527,23 @@ def process_image_generation_queue(self, image_ids: list, account_id: int = None
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Download and save image to /data/app/images
|
# Download and save image to /data/app/igny8/frontend/public/images/ai-images
|
||||||
saved_file_path = None
|
saved_file_path = None
|
||||||
if image_url:
|
if image_url:
|
||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
from django.conf import settings
|
import time
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# Create images directory if it doesn't exist
|
# Use the correct path: /data/app/igny8/frontend/public/images/ai-images
|
||||||
# Use frontend/public/images/ai-images/ for web accessibility (like /images/logo/)
|
# This is web-accessible via /images/ai-images/ (Vite serves from public/)
|
||||||
# This allows images to be served via app.igny8.com/images/ai-images/
|
|
||||||
write_test_passed = False
|
|
||||||
images_dir = None
|
|
||||||
|
|
||||||
# Try frontend/public/images/ai-images/ first (web-accessible)
|
|
||||||
try:
|
|
||||||
# Use absolute path: /data/app/igny8/frontend/public/images/ai-images/
|
|
||||||
# This matches the structure where frontend is at project root level
|
|
||||||
images_dir = '/data/app/igny8/frontend/public/images/ai-images'
|
images_dir = '/data/app/igny8/frontend/public/images/ai-images'
|
||||||
os.makedirs(images_dir, exist_ok=True)
|
|
||||||
# Test write access
|
|
||||||
test_file = os.path.join(images_dir, '.write_test')
|
|
||||||
with open(test_file, 'w') as f:
|
|
||||||
f.write('test')
|
|
||||||
os.remove(test_file)
|
|
||||||
write_test_passed = True
|
|
||||||
logger.info(f"[process_image_generation_queue] Image {image_id} - Directory writable (web-accessible): {images_dir}")
|
|
||||||
except Exception as web_dir_error:
|
|
||||||
logger.warning(f"[process_image_generation_queue] Image {image_id} - Web-accessible directory not writable: {images_dir}, error: {web_dir_error}")
|
|
||||||
# Fallback to /data/app/igny8/images (mounted volume)
|
|
||||||
try:
|
|
||||||
images_dir = '/data/app/igny8/images'
|
|
||||||
os.makedirs(images_dir, exist_ok=True)
|
|
||||||
test_file = os.path.join(images_dir, '.write_test')
|
|
||||||
with open(test_file, 'w') as f:
|
|
||||||
f.write('test')
|
|
||||||
os.remove(test_file)
|
|
||||||
write_test_passed = True
|
|
||||||
logger.info(f"[process_image_generation_queue] Image {image_id} - Using mounted volume directory: {images_dir}")
|
|
||||||
except Exception as mounted_error:
|
|
||||||
logger.warning(f"[process_image_generation_queue] Image {image_id} - Mounted directory not writable: {images_dir}, error: {mounted_error}")
|
|
||||||
# Final fallback to /data/app/images
|
|
||||||
try:
|
|
||||||
images_dir = '/data/app/images'
|
|
||||||
os.makedirs(images_dir, exist_ok=True)
|
|
||||||
test_file = os.path.join(images_dir, '.write_test')
|
|
||||||
with open(test_file, 'w') as f:
|
|
||||||
f.write('test')
|
|
||||||
os.remove(test_file)
|
|
||||||
write_test_passed = True
|
|
||||||
logger.info(f"[process_image_generation_queue] Image {image_id} - Using fallback directory: {images_dir}")
|
|
||||||
except Exception as final_error:
|
|
||||||
logger.error(f"[process_image_generation_queue] Image {image_id} - All directories not writable. Last error: {final_error}")
|
|
||||||
raise Exception(f"None of the image directories are writable. Last error: {final_error}")
|
|
||||||
|
|
||||||
if not write_test_passed:
|
# Create directory if it doesn't exist
|
||||||
raise Exception(f"Failed to find writable directory for saving images")
|
os.makedirs(images_dir, exist_ok=True)
|
||||||
|
logger.info(f"[process_image_generation_queue] Image {image_id} - Using directory: {images_dir}")
|
||||||
|
|
||||||
# Generate filename: image_{image_id}_{timestamp}.png (or .webp for Runware)
|
# Generate filename: image_{image_id}_{timestamp}.png (or .webp for Runware)
|
||||||
import time
|
|
||||||
timestamp = int(time.time())
|
timestamp = int(time.time())
|
||||||
# Use webp extension if provider is Runware, otherwise png
|
# Use webp extension if provider is Runware, otherwise png
|
||||||
file_ext = 'webp' if provider == 'runware' else 'png'
|
file_ext = 'webp' if provider == 'runware' else 'png'
|
||||||
|
|||||||
@@ -395,38 +395,11 @@ class ImagesViewSet(SiteSectorModelViewSet):
|
|||||||
|
|
||||||
file_path = image.image_path
|
file_path = image.image_path
|
||||||
|
|
||||||
# Verify file exists - if not, try alternative locations
|
# Verify file exists at the saved path
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
logger.warning(f"[serve_image_file] Image {pk} - File not found at saved path: {file_path}, trying alternative locations...")
|
logger.error(f"[serve_image_file] Image {pk} - File not found at saved path: {file_path}")
|
||||||
|
|
||||||
# Try alternative locations based on the filename
|
|
||||||
filename = os.path.basename(file_path)
|
|
||||||
alternative_paths = [
|
|
||||||
'/data/app/igny8/frontend/public/images/ai-images/' + filename, # Primary location (web-accessible)
|
|
||||||
'/data/app/igny8/images/' + filename, # Secondary location
|
|
||||||
'/data/app/images/' + filename, # Fallback location
|
|
||||||
]
|
|
||||||
|
|
||||||
# Try each alternative path
|
|
||||||
found = False
|
|
||||||
for alt_path in alternative_paths:
|
|
||||||
if os.path.exists(alt_path):
|
|
||||||
file_path = alt_path
|
|
||||||
logger.info(f"[serve_image_file] Image {pk} - Found file at alternative location: {file_path}")
|
|
||||||
# Update database with correct path
|
|
||||||
try:
|
|
||||||
image.image_path = file_path
|
|
||||||
image.save(update_fields=['image_path'])
|
|
||||||
logger.info(f"[serve_image_file] Image {pk} - Updated database with correct path: {file_path}")
|
|
||||||
except Exception as update_error:
|
|
||||||
logger.warning(f"[serve_image_file] Image {pk} - Failed to update database path: {update_error}")
|
|
||||||
found = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if not found:
|
|
||||||
logger.error(f"[serve_image_file] Image {pk} - File not found in any location. Tried: {[file_path] + alternative_paths}")
|
|
||||||
return Response({
|
return Response({
|
||||||
'error': f'Image file not found at: {file_path} (also checked alternative locations)'
|
'error': f'Image file not found at: {file_path}'
|
||||||
}, status=status.HTTP_404_NOT_FOUND)
|
}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
# Check if file is readable
|
# Check if file is readable
|
||||||
|
|||||||
129
docker-compose.yml
Normal file
129
docker-compose.yml
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# MASTER DOCKER COMPOSE - SINGLE SOURCE OF TRUTH
|
||||||
|
# =============================================================================
|
||||||
|
# This file manages ALL apps and shared services
|
||||||
|
# Used by both Portainer and CLI - no conflicts
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ===========================================================================
|
||||||
|
# SHARED SERVICES (Global - used by all apps)
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:15
|
||||||
|
container_name: igny8_postgres
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: igny8
|
||||||
|
POSTGRES_PASSWORD: igny8pass
|
||||||
|
POSTGRES_DB: igny8_db
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB} || exit 1"]
|
||||||
|
interval: 20s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 15s
|
||||||
|
networks: [igny8_net]
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7
|
||||||
|
container_name: igny8_redis
|
||||||
|
restart: always
|
||||||
|
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
|
||||||
|
volumes:
|
||||||
|
- redisdata:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "redis-cli ping | grep -q PONG"]
|
||||||
|
interval: 20s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
networks: [igny8_net]
|
||||||
|
|
||||||
|
pgadmin:
|
||||||
|
image: dpage/pgadmin4
|
||||||
|
container_name: igny8_pgadmin
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
PGADMIN_DEFAULT_EMAIL: admin@igny8.com
|
||||||
|
PGADMIN_DEFAULT_PASSWORD: admin123
|
||||||
|
ports:
|
||||||
|
- "0.0.0.0:5050:80"
|
||||||
|
volumes:
|
||||||
|
- pgadmin_data:/var/lib/pgadmin
|
||||||
|
networks: [igny8_net]
|
||||||
|
|
||||||
|
filebrowser:
|
||||||
|
image: filebrowser/filebrowser:v2.25.0
|
||||||
|
container_name: igny8_filebrowser
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Karachi
|
||||||
|
ports:
|
||||||
|
- "0.0.0.0:8080:80"
|
||||||
|
volumes:
|
||||||
|
- /data:/srv
|
||||||
|
- /backups:/srv/backups
|
||||||
|
- filebrowser_db:/database
|
||||||
|
networks: [igny8_net]
|
||||||
|
labels:
|
||||||
|
- "com.docker.compose.project=igny8-infra"
|
||||||
|
- "com.docker.compose.service=filebrowser"
|
||||||
|
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
container_name: gitea
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
volumes:
|
||||||
|
- ./gitea:/data
|
||||||
|
- /data/app/igny8:/deploy/igny8:rw # Mount app directory for deployment
|
||||||
|
ports:
|
||||||
|
- "0.0.0.0:3000:3000" # Web UI
|
||||||
|
- "0.0.0.0:2222:22" # SSH for Git access
|
||||||
|
networks: [igny8_net]
|
||||||
|
labels:
|
||||||
|
- "com.docker.compose.project=igny8-infra"
|
||||||
|
- "com.docker.compose.service=gitea"
|
||||||
|
|
||||||
|
caddy:
|
||||||
|
image: caddy:latest
|
||||||
|
container_name: igny8_caddy
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- caddy_data:/data
|
||||||
|
- caddy_config:/config
|
||||||
|
# Mount Caddyfile for routing configuration
|
||||||
|
- /var/lib/docker/volumes/portainer_data/_data/caddy/Caddyfile:/etc/caddy/Caddyfile
|
||||||
|
networks: [igny8_net]
|
||||||
|
|
||||||
|
setup-helper:
|
||||||
|
image: alpine:3.20
|
||||||
|
container_name: setup-helper
|
||||||
|
command: ["sh", "-c", "sleep infinity"]
|
||||||
|
restart: always
|
||||||
|
networks: [igny8_net]
|
||||||
|
volumes:
|
||||||
|
- /data/backups:/backups:rw
|
||||||
|
- /scripts:/scripts:ro
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
redisdata:
|
||||||
|
pgadmin_data:
|
||||||
|
filebrowser_db:
|
||||||
|
caddy_data:
|
||||||
|
caddy_config:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
igny8_net:
|
||||||
|
external: true
|
||||||
Reference in New Issue
Block a user