Add webhook endpoint with automatic container restart on push
This commit is contained in:
11
=7.0.0
Normal file
11
=7.0.0
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Collecting docker
|
||||||
|
Downloading docker-7.1.0-py3-none-any.whl.metadata (3.8 kB)
|
||||||
|
Requirement already satisfied: requests>=2.26.0 in /usr/local/lib/python3.11/site-packages (from docker) (2.32.5)
|
||||||
|
Requirement already satisfied: urllib3>=1.26.0 in /usr/local/lib/python3.11/site-packages (from docker) (2.5.0)
|
||||||
|
Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.11/site-packages (from requests>=2.26.0->docker) (3.4.4)
|
||||||
|
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/site-packages (from requests>=2.26.0->docker) (3.11)
|
||||||
|
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.11/site-packages (from requests>=2.26.0->docker) (2025.10.5)
|
||||||
|
Downloading docker-7.1.0-py3-none-any.whl (147 kB)
|
||||||
|
Installing collected packages: docker
|
||||||
|
Successfully installed docker-7.1.0
|
||||||
|
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
|
||||||
@@ -530,21 +530,102 @@ def gitea_webhook(request):
|
|||||||
|
|
||||||
logger.info(f"[Webhook] Processing push: {commit_count} commit(s) by {pusher} to {repo_full_name}")
|
logger.info(f"[Webhook] Processing push: {commit_count} commit(s) by {pusher} to {repo_full_name}")
|
||||||
|
|
||||||
# Trigger deployment
|
# Trigger deployment - restart containers
|
||||||
# The post-receive hook in Gitea will handle the actual deployment
|
# Note: Git pull is handled by post-receive hook in Gitea
|
||||||
# This webhook is for logging and potential additional actions
|
# This webhook restarts containers to apply changes
|
||||||
|
deployment_success = False
|
||||||
|
deployment_error = None
|
||||||
|
|
||||||
# You can add additional deployment logic here if needed
|
try:
|
||||||
# For example, triggering a rebuild, restarting services, etc.
|
# Try to use docker Python library first, fallback to subprocess
|
||||||
|
try:
|
||||||
|
import docker as docker_lib
|
||||||
|
client = docker_lib.DockerClient(base_url='unix://var/run/docker.sock')
|
||||||
|
|
||||||
|
# Restart frontend container (don't restart backend from within itself)
|
||||||
|
logger.info(f"[Webhook] Restarting frontend container...")
|
||||||
|
frontend_container = client.containers.get("igny8_frontend")
|
||||||
|
frontend_container.restart(timeout=30)
|
||||||
|
logger.info(f"[Webhook] Frontend container restarted successfully")
|
||||||
|
|
||||||
|
# Schedule backend restart via subprocess in background (non-blocking)
|
||||||
|
# This avoids deadlock from restarting the container we're running in
|
||||||
|
logger.info(f"[Webhook] Scheduling backend container restart...")
|
||||||
|
import threading
|
||||||
|
def restart_backend():
|
||||||
|
import time
|
||||||
|
time.sleep(2) # Give webhook time to respond
|
||||||
|
try:
|
||||||
|
backend_container = client.containers.get("igny8_backend")
|
||||||
|
backend_container.restart(timeout=30)
|
||||||
|
logger.info(f"[Webhook] Backend container restarted successfully (delayed)")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[Webhook] Delayed backend restart failed: {e}")
|
||||||
|
|
||||||
|
restart_thread = threading.Thread(target=restart_backend, daemon=True)
|
||||||
|
restart_thread.start()
|
||||||
|
|
||||||
|
deployment_success = True
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
# Fallback to subprocess with docker command
|
||||||
|
logger.info(f"[Webhook] Docker library not available, using subprocess...")
|
||||||
|
|
||||||
|
# Try /usr/bin/docker or docker in PATH
|
||||||
|
docker_cmd = "/usr/bin/docker"
|
||||||
|
import shutil
|
||||||
|
if not os.path.exists(docker_cmd):
|
||||||
|
docker_cmd = shutil.which("docker") or "docker"
|
||||||
|
|
||||||
|
# Restart backend container
|
||||||
|
logger.info(f"[Webhook] Restarting backend container...")
|
||||||
|
backend_result = subprocess.run(
|
||||||
|
[docker_cmd, "restart", "igny8_backend"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=30
|
||||||
|
)
|
||||||
|
|
||||||
|
if backend_result.returncode != 0:
|
||||||
|
raise Exception(f"Backend restart failed: {backend_result.stderr}")
|
||||||
|
logger.info(f"[Webhook] Backend container restarted successfully")
|
||||||
|
|
||||||
|
# Restart frontend container
|
||||||
|
logger.info(f"[Webhook] Restarting frontend container...")
|
||||||
|
frontend_result = subprocess.run(
|
||||||
|
[docker_cmd, "restart", "igny8_frontend"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=30
|
||||||
|
)
|
||||||
|
|
||||||
|
if frontend_result.returncode != 0:
|
||||||
|
raise Exception(f"Frontend restart failed: {frontend_result.stderr}")
|
||||||
|
logger.info(f"[Webhook] Frontend container restarted successfully")
|
||||||
|
|
||||||
|
deployment_success = True
|
||||||
|
|
||||||
|
logger.info(f"[Webhook] Deployment completed: containers restarted")
|
||||||
|
|
||||||
|
except subprocess.TimeoutExpired as e:
|
||||||
|
deployment_error = f"Deployment timeout: {str(e)}"
|
||||||
|
logger.error(f"[Webhook] {deployment_error}")
|
||||||
|
except Exception as deploy_error:
|
||||||
|
deployment_error = str(deploy_error)
|
||||||
|
logger.error(f"[Webhook] Deployment error: {deploy_error}", exc_info=True)
|
||||||
|
|
||||||
return Response({
|
return Response({
|
||||||
'status': 'success',
|
'status': 'success' if deployment_success else 'partial',
|
||||||
'message': 'Webhook received and processed',
|
'message': 'Webhook received and processed',
|
||||||
'repository': repo_full_name,
|
'repository': repo_full_name,
|
||||||
'branch': ref,
|
'branch': ref,
|
||||||
'commits': commit_count,
|
'commits': commit_count,
|
||||||
'pusher': pusher,
|
'pusher': pusher,
|
||||||
'event': event_type
|
'event': event_type,
|
||||||
|
'deployment': {
|
||||||
|
'success': deployment_success,
|
||||||
|
'error': deployment_error
|
||||||
|
}
|
||||||
}, status=http_status.HTTP_200_OK)
|
}, status=http_status.HTTP_200_OK)
|
||||||
|
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ requests>=2.31.0
|
|||||||
celery>=5.3.0
|
celery>=5.3.0
|
||||||
beautifulsoup4>=4.12.0
|
beautifulsoup4>=4.12.0
|
||||||
psutil>=5.9.0
|
psutil>=5.9.0
|
||||||
|
docker>=7.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user