typo
Build and Push Docker Images / build-and-push (push) Successful in 1m11s

This commit is contained in:
2025-07-02 09:55:13 +02:00
parent 16f018018f
commit ef362ad23a
5 changed files with 0 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
FROM python:3.9-slim
# Install required system dependencies
RUN apt-get update && apt-get install -y \
curl \
docker.io \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy requirements first to leverage Docker cache
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the healthcheck script
COPY healthcheck.py .
# Set environment variables
ENV PYTHONUNBUFFERED=1
ENV BASE_URL="https://puppeteer.workwithkora.com"
ENV TEST_URL="https://www.google.com"
ENV API_KEY="Q7Sd#hhFkyHy*T"
ENV TARGET_CONTAINER="puppeteer-api"
ENV CHECK_INTERVAL=60
# Create a non-root user
RUN useradd -m healthcheck && chown -R healthcheck:healthcheck /app
USER healthcheck
# Run the healthcheck script
CMD ["python", "healthcheck.py"]
+110
View File
@@ -0,0 +1,110 @@
# Puppeteer API Healthcheck
A Docker container that monitors the Puppeteer API and automatically restarts the target container when the API becomes unresponsive.
## Features
- Monitors the Puppeteer API endpoint every minute
- Automatically restarts the target container after 3 consecutive failures
- Configurable via environment variables
- Comprehensive logging
- Docker socket access for container management
## Environment Variables
| Variable | Default | Description |
| ------------------ | ------------------------------------ | -------------------------------- |
| `BASE_URL` | `https://puppeteer.workwithkora.com` | Base URL of the Puppeteer API |
| `TEST_URL` | `https://www.google.com` | URL to test the API with |
| `API_KEY` | `Q7Sd#hhFkyHy*T` | API key for authentication |
| `TARGET_CONTAINER` | `puppeteer-api` | Name of the container to restart |
| `CHECK_INTERVAL` | `60` | Health check interval in seconds |
## Usage
### Docker Run
```bash
docker run -d \
--name puppeteer-healthcheck \
-v /var/run/docker.sock:/var/run/docker.sock \
-e BASE_URL="https://puppeteer.workwithkora.com" \
-e TEST_URL="https://www.google.com" \
-e API_KEY="your-api-key" \
-e TARGET_CONTAINER="puppeteer-api" \
-e CHECK_INTERVAL="60" \
your-registry/puppeteer-healthcheck:latest
```
### Docker Compose
```yaml
version: "3.8"
services:
puppeteer-healthcheck:
build: .
container_name: puppeteer-healthcheck
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- BASE_URL=https://puppeteer.workwithkora.com
- TEST_URL=https://www.google.com
- API_KEY=your-api-key
- TARGET_CONTAINER=puppeteer-api
- CHECK_INTERVAL=60
restart: unless-stopped
depends_on:
- puppeteer-api
```
## How It Works
1. The healthcheck container makes a GET request to the Puppeteer API every minute
2. It uses the configured test URL and API key for authentication
3. If the request fails (non-200 status or timeout), it increments a failure counter
4. After 3 consecutive failures, it attempts to restart the target container
5. If the restart is successful, the failure counter is reset
6. The process continues indefinitely
## Logging
The container logs all health check activities to both stdout and a log file (`/app/healthcheck.log`). Log levels include:
- INFO: Normal operations and successful health checks
- WARNING: Failed health checks
- ERROR: Container restart attempts and failures
## Security Considerations
- The container requires access to the Docker socket to restart other containers
- Ensure proper API key management
- Consider running with limited privileges where possible
- The container runs as a non-root user for security
## Troubleshooting
### Container not found
- Ensure the `TARGET_CONTAINER` environment variable matches the exact name of your puppeteer-api container
- Verify the container is running and accessible
### Permission denied
- Ensure the Docker socket is properly mounted
- Check that the container has the necessary permissions to access the Docker daemon
### API key issues
- Verify the API key is correct and has the necessary permissions
- Check that the base URL is accessible from the container
## Building
```bash
docker build -t puppeteer-healthcheck .
```
## Version
Current version: 1.0.0
@@ -0,0 +1,155 @@
#!/usr/bin/env python3
"""
Healthcheck script for Puppeteer API
Monitors the API endpoint and restarts the container if it fails
"""
import os
import time
import logging
import requests
import docker
from urllib.parse import quote
from datetime import datetime
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('/app/healthcheck.log')
]
)
logger = logging.getLogger(__name__)
class PuppeteerHealthcheck:
def __init__(self):
self.base_url = os.getenv('BASE_URL', 'https://puppeteer.workwithkora.com')
self.test_url = os.getenv('TEST_URL', 'https://www.google.com')
self.api_key = os.getenv('API_KEY', 'Q7Sd#hhFkyHy*T')
self.target_container = os.getenv('TARGET_CONTAINER', 'puppeteer-api')
self.check_interval = int(os.getenv('CHECK_INTERVAL', '60'))
# Initialize Docker client
try:
self.docker_client = docker.from_env()
logger.info("Docker client initialized successfully")
except Exception as e:
logger.error(f"Failed to initialize Docker client: {e}")
raise
logger.info(f"Healthcheck initialized with:")
logger.info(f" Base URL: {self.base_url}")
logger.info(f" Test URL: {self.test_url}")
logger.info(f" Target Container: {self.target_container}")
logger.info(f" Check Interval: {self.check_interval} seconds")
def perform_health_check(self):
"""Perform the health check by making a request to the puppeteer API"""
try:
# Construct the URL with the test URL as a parameter
encoded_test_url = quote(self.test_url, safe='')
url = f"{self.base_url}/?url={encoded_test_url}"
headers = {
'x-api-key': self.api_key,
'User-Agent': 'Puppeteer-Healthcheck/1.0'
}
logger.info(f"Performing health check: {url}")
response = requests.get(
url,
headers=headers,
timeout=30,
allow_redirects=True
)
if response.status_code == 200:
logger.info("Health check passed - API is responding correctly")
return True
else:
logger.warning(f"Health check failed - Status code: {response.status_code}")
logger.warning(f"Response: {response.text[:200]}...")
return False
except requests.exceptions.RequestException as e:
logger.error(f"Health check failed - Request error: {e}")
return False
except Exception as e:
logger.error(f"Health check failed - Unexpected error: {e}")
return False
def restart_container(self):
"""Restart the target puppeteer-api container"""
try:
logger.info(f"Attempting to restart container: {self.target_container}")
# Get the container
container = self.docker_client.containers.get(self.target_container)
# Restart the container
container.restart(timeout=30)
logger.info(f"Successfully restarted container: {self.target_container}")
return True
except docker.errors.NotFound:
logger.error(f"Container not found: {self.target_container}")
return False
except docker.errors.APIError as e:
logger.error(f"Docker API error while restarting container: {e}")
return False
except Exception as e:
logger.error(f"Unexpected error while restarting container: {e}")
return False
def run(self):
"""Main loop for the healthcheck"""
logger.info("Starting Puppeteer API healthcheck service")
consecutive_failures = 0
max_consecutive_failures = 3 # Restart after 3 consecutive failures
while True:
try:
# Perform health check
if self.perform_health_check():
consecutive_failures = 0
logger.info("Health check passed - resetting failure counter")
else:
consecutive_failures += 1
logger.warning(f"Health check failed - consecutive failures: {consecutive_failures}")
# Restart container if we've had too many consecutive failures
if consecutive_failures >= max_consecutive_failures:
logger.error(f"Health check failed {consecutive_failures} times consecutively - restarting container")
if self.restart_container():
consecutive_failures = 0
logger.info("Container restarted successfully - resetting failure counter")
else:
logger.error("Failed to restart container")
# Wait before next check
logger.info(f"Waiting {self.check_interval} seconds before next health check...")
time.sleep(self.check_interval)
except KeyboardInterrupt:
logger.info("Healthcheck service stopped by user")
break
except Exception as e:
logger.error(f"Unexpected error in main loop: {e}")
time.sleep(self.check_interval)
def main():
"""Main entry point"""
try:
healthcheck = PuppeteerHealthcheck()
healthcheck.run()
except Exception as e:
logger.error(f"Failed to start healthcheck service: {e}")
exit(1)
if __name__ == "__main__":
main()
@@ -0,0 +1,2 @@
requests==2.31.0
docker==6.1.3
+1
View File
@@ -0,0 +1 @@
latest