11#! /bin/bash
22
33set -e
4- # from .env import all variables
5- source .env
6-
7- # Function to run tests
8- run_tests () {
9- echo " 🚀 Running tests..."
10- if [ -f " tests/run_tests.sh" ]; then
11- cd tests
12- ./run_tests.sh
13- cd ..
14- else
15- echo " ⚠️ Test script not found. Skipping tests."
16- fi
4+
5+ # Load environment variables
6+ if [ -f " .env" ]; then
7+ source .env
8+ else
9+ echo " ❌ Error: .env file not found"
10+ exit 1
11+ fi
12+
13+ # Default values
14+ DOMAIN=${DOMAIN:- localhost}
15+ APP_NAME=${APP_NAME:- app}
16+
17+ # Function to check if a container is running
18+ container_is_running () {
19+ docker ps --filter " name=$1 " --format ' {{.Names}}' | grep -q " ^$1 $"
20+ }
21+
22+ # Function to wait for a container to be healthy
23+ wait_for_container () {
24+ local container=$1
25+ local max_attempts=30
26+ local wait_seconds=5
27+
28+ echo " ⏳ Waiting for $container to be ready..."
29+
30+ for (( i= 1 ; i<= max_attempts; i++ )) ; do
31+ if container_is_running " $container " ; then
32+ echo " ✅ $container is running"
33+ return 0
34+ fi
35+ echo " ⏳ $container not ready yet (attempt $i /$max_attempts )..."
36+ sleep $wait_seconds
37+ done
38+
39+ echo " ❌ Timeout waiting for $container to start"
40+ return 1
1741}
1842
1943echo " 📁 Creating project structure..."
@@ -22,7 +46,8 @@ cd $APP_NAME
2246
2347# Create FastAPI app if it doesn't exist
2448if [ ! -f " app/main.py" ]; then
25- echo " from fastapi import FastAPI\n\napp = FastAPI()\n\[email protected] (\" /\" )\nasync def read_root():\n return {\" message\" : \" Hello, World!\" }" > app/main.py
49+ mkdir -p app
50+ echo " from fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\n# Enable CORS\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\" *\" ],\n allow_credentials=True,\n allow_methods=[\" *\" ],\n allow_headers=[\" *\" ],\n)\n\[email protected] (\" /\" )\nasync def read_root():\n return {\" message\" : \" Hello, World!\" }\n\[email protected] (\" /health\" )\nasync def health_check():\n return {\" status\" : \" healthy\" }\n" > app/main.py
2651fi
2752
2853# Create requirements.txt if it doesn't exist
3257
3358# Create Dockerfile if it doesn't exist
3459if [ ! -f " Dockerfile" ]; then
35- echo " FROM python:3.9-slim\n\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY . .\n\nCMD [\" uvicorn\" , \" app.main:app\" , \" --host\" , \" 0.0.0.0\" , \" --port\" , \" 8080\" ]" > Dockerfile
60+ echo " FROM python:3.9-slim\n\nWORKDIR /app\n\n# Install system dependencies\nRUN apt-get update && apt-get install -y --no-install-recommends \\ \n build-essential \\ \n && rm -rf /var/lib/apt/lists/*\n\n# Install Python dependencies\ nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\n# Copy application code\ nCOPY . .\n\n# Expose port\nEXPOSE 8080\n\n# Run the application \nCMD [\" uvicorn\" , \" app.main:app\" , \" --host\" , \" 0.0.0.0\" , \" --port\" , \" 8080\" ]" > Dockerfile
3661fi
3762
3863# Create docker-compose.yml if it doesn't exist
3964if [ ! -f " ../docker-compose.yml" ]; then
40- echo " services:
41- caddy:
42- image: caddy:2.8.0
43- container_name: caddy
44- ports:
45- - \" 80:80\"
46- - \" 443:443\"
47- volumes:
48- - ./Caddyfile:/etc/caddy/Caddyfile
49- - caddy_data:/data
50- - caddy_config:/config
51- environment:
52- - CLOUDFLARE_API_TOKEN=\$ {CF_API_TOKEN}
53- networks:
54- - web
55- restart: unless-stopped
56-
57- myapi:
58- build: .
59- container_name: myapi
60- expose:
61- - \" 8080\"
62- networks:
63- - web
64- command: uvicorn app.main:app --host 0.0.0.0 --port 8080 --reload
65-
66- networks:
67- web:
68- external: true
69-
70- volumes:
71- caddy_data:
72- caddy_config:" > ../docker-compose.yml
65+ echo " version: '3.8'\n\nservices:\n caddy:\n image: caddy:2.8.0\n container_name: caddy\n ports:\n - \" 80:80\" \n - \" 443:443\" \n volumes:\n - ./Caddyfile:/etc/caddy/Caddyfile:ro\n - caddy_data:/data\n - caddy_config:/config\n environment:\n - CLOUDFLARE_API_TOKEN=\$ {CF_API_TOKEN}\n networks:\n - web\n restart: unless-stopped\n healthcheck:\n test: [\" CMD\" , \" curl\" , \" -f\" , \" http://localhost:80/\" ]\n interval: 10s\n timeout: 5s\n retries: 3\n\n myapi:\n build:\n context: .\n dockerfile: Dockerfile\n container_name: myapi\n expose:\n - \" 8080\" \n networks:\n - web\n restart: unless-stopped\n healthcheck:\n test: [\" CMD\" , \" curl\" , \" -f\" , \" http://localhost:8080/health\" ]\n interval: 10s\n timeout: 5s\n retries: 3\n\nnetworks:\n web:\n driver: bridge\n\nvolumes:\n caddy_data:\n caddy_config:\n" > ../docker-compose.yml
7366fi
7467
7568# Create Caddyfile if it doesn't exist
7669if [ ! -f " ../Caddyfile" ]; then
77- echo " ${DOMAIN} {
78- reverse_proxy myapi:8080
79- tls {
80- dns cloudflare {env.CLOUDFLARE_API_TOKEN}
81- }" > ../Caddyfile
70+ echo " ${DOMAIN} {\n # Enable the admin API (optional, for debugging)\n # admin\n \n # Logging\n log {\n output file /var/log/caddy/access.log\n format json\n }\n \n # Handle API requests\n handle_path /api/* {\n reverse_proxy myapi:8080\n }\n \n # Handle all other requests\n handle {\n reverse_proxy myapi:8080\n }\n \n # Enable TLS with Cloudflare DNS challenge\n tls {\n dns cloudflare {env.CLOUDFLARE_API_TOKEN}\n }\n}" > ../Caddyfile
71+ fi
72+
73+ # Create logs directory
74+ mkdir -p ../logs
75+
76+ # Create web network if it doesn't exist
77+ if ! docker network inspect web > /dev/null 2>&1 ; then
78+ echo " 🌐 Creating Docker network 'web'..."
79+ docker network create web
8280fi
8381
8482echo " 🚀 Starting services..."
8583cd ..
84+
85+ echo " 🔧 Building and starting containers..."
8686docker-compose up -d --build
8787
88- echo " ⏳ Waiting for services to be ready..."
89- sleep 10
88+ # Wait for containers to be ready
89+ wait_for_container " caddy"
90+ wait_for_container " myapi"
91+
92+ echo " ✅ Services started successfully!"
9093
9194# Run tests
92- run_tests
95+ echo -e " \n🚀 Running tests..."
96+
97+ # Run basic tests
98+ if [ -f " ./run_tests.sh" ]; then
99+ chmod +x ./run_tests.sh
100+ if ! ./run_tests.sh; then
101+ echo -e " \n${YELLOW} Basic tests failed. Check the output above for details.${NC} "
102+ fi
103+ else
104+ echo -e " \n${YELLOW} ⚠️ Basic test script not found. Skipping basic tests.${NC} "
105+ fi
93106
94- echo " ✅ Setup completed successfully!"
107+ # Run Ansible tests
108+ if [ -f " ./run_ansible_tests.sh" ]; then
109+ echo -e " \n🔍 Running Ansible tests..."
110+ chmod +x ./run_ansible_tests.sh
111+ if ./run_ansible_tests.sh; then
112+ echo -e " \n${GREEN} ✅ Ansible tests completed successfully!${NC} "
113+ else
114+ echo -e " \n${YELLOW} ⚠️ Ansible tests completed with some failures.${NC} "
115+ fi
116+ else
117+ echo -e " \n${YELLOW} ⚠️ Ansible test script not found. Skipping Ansible tests.${NC} "
118+ fi
119+
120+ echo " \n✅ Setup completed successfully!"
95121echo " 🌐 Your FastAPI app should be available at: https://${DOMAIN} "
122+ echo " 📝 API documentation: https://${DOMAIN} /docs"
123+
124+ echo " \n📋 Container status:"
125+ docker ps --filter " name=caddy|myapi" --format " table {{.Names}}\t{{.Status}}\t{{.Ports}}"
0 commit comments