1"""
2Simple Flask application demonstrating containerization best practices.
3
4This application provides:
5- A basic hello world endpoint
6- A health check endpoint for container orchestration
7- Proper logging and error handling
8"""
9
10from flask import Flask, jsonify
11import logging
12import os
13import signal
14import sys
15
16# Configure logging
17logging.basicConfig(
18 level=logging.INFO,
19 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
20)
21logger = logging.getLogger(__name__)
22
23app = Flask(__name__)
24
25
26@app.route('/')
27def hello():
28 """Main endpoint returning a simple greeting."""
29 logger.info("Hello endpoint accessed")
30 return jsonify({
31 'message': 'Hello from Docker!',
32 'version': '1.0',
33 'environment': os.getenv('ENVIRONMENT', 'development')
34 })
35
36
37@app.route('/health')
38def health():
39 """
40 Health check endpoint.
41
42 This is used by:
43 - Docker HEALTHCHECK directive
44 - Kubernetes liveness/readiness probes
45 - Load balancers
46
47 Returns:
48 JSON response with health status
49 """
50 return jsonify({
51 'status': 'healthy',
52 'service': 'flask-app'
53 }), 200
54
55
56def graceful_shutdown(signum, frame):
57 """
58 Handle graceful shutdown on SIGTERM.
59
60 This is important in container environments where the orchestrator
61 sends SIGTERM before forcefully killing the container.
62 """
63 logger.info(f"Received signal {signum}, shutting down gracefully...")
64 sys.exit(0)
65
66
67# Register signal handlers for graceful shutdown
68signal.signal(signal.SIGTERM, graceful_shutdown)
69signal.signal(signal.SIGINT, graceful_shutdown)
70
71
72if __name__ == '__main__':
73 # Get configuration from environment variables
74 port = int(os.getenv('PORT', 5000))
75 debug = os.getenv('DEBUG', 'False').lower() == 'true'
76
77 logger.info(f"Starting Flask application on port {port}")
78
79 # Use 0.0.0.0 to accept connections from outside the container
80 app.run(host='0.0.0.0', port=port, debug=debug)