Skip to content

Commit ccda306

Browse files
committed
setup script added for convenience
1 parent f4e8740 commit ccda306

File tree

4 files changed

+271
-34
lines changed

4 files changed

+271
-34
lines changed

README.md

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -75,65 +75,98 @@ git clone https://github.com/<you>/FastAPI-boilerplate
7575
cd FastAPI-boilerplate
7676
```
7777

78-
The `scripts/` folder contains ready-to-use configurations for different deployment scenarios. Pick your path:
78+
**Quick setup:** Run the interactive setup script to choose your deployment configuration:
79+
80+
```bash
81+
./setup.py
82+
```
83+
84+
Or directly specify the deployment type: `./setup.py local`, `./setup.py staging`, or `./setup.py production`.
85+
86+
The script copies the right files for your deployment scenario. Here's what each option sets up:
7987

8088
### Option 1: Local development with Uvicorn
8189

82-
Best for: **Development and testing**. Simply run:
90+
Best for: **Development and testing**
8391

84-
```bash
85-
cp scripts/local_with_uvicorn/Dockerfile Dockerfile
86-
cp scripts/local_with_uvicorn/docker-compose.yml docker-compose.yml
87-
cp scripts/local_with_uvicorn/.env.example src/.env
88-
```
92+
**Copies:**
8993

90-
For local development, the example environment values work fine. You can modify them later if needed. Then you just need to run:
94+
- `scripts/local_with_uvicorn/Dockerfile``Dockerfile`
95+
- `scripts/local_with_uvicorn/docker-compose.yml``docker-compose.yml`
96+
- `scripts/local_with_uvicorn/.env.example``src/.env`
9197

92-
```bash
93-
docker compose up
94-
```
98+
Sets up Uvicorn with auto-reload enabled. The example environment values work fine for development.
9599

96-
Your API will be running at http://127.0.0.1:8000 with auto-reload enabled. Open http://127.0.0.1:8000/docs to see the interactive documentation.
100+
**Manual setup:** `./setup.py local` or copy the files above manually.
97101

98102
### Option 2: Staging with Gunicorn managing Uvicorn workers
99103

100-
Best for: **Staging environments and load testing**. Run:
104+
Best for: **Staging environments and load testing**
101105

102-
```bash
103-
cp scripts/gunicorn_managing_uvicorn_workers/Dockerfile Dockerfile
104-
cp scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml docker-compose.yml
105-
cp scripts/gunicorn_managing_uvicorn_workers/.env.example src/.env
106-
```
106+
**Copies:**
107+
108+
- `scripts/gunicorn_managing_uvicorn_workers/Dockerfile``Dockerfile`
109+
- `scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml``docker-compose.yml`
110+
- `scripts/gunicorn_managing_uvicorn_workers/.env.example``src/.env`
111+
112+
Sets up Gunicorn managing multiple Uvicorn workers for production-like performance testing.
107113

108114
> [!WARNING]
109-
> Change `SECRET_KEY` and passwords in the `.env` file for staging/testing environments.
115+
> Change `SECRET_KEY` and passwords in the `.env` file for staging environments.
116+
117+
**Manual setup:** `./setup.py staging` or copy the files above manually.
118+
119+
### Option 3: Production with NGINX
120+
121+
Best for: **Production deployments**
122+
123+
**Copies:**
110124

111-
And start with:
125+
- `scripts/production_with_nginx/Dockerfile``Dockerfile`
126+
- `scripts/production_with_nginx/docker-compose.yml``docker-compose.yml`
127+
- `scripts/production_with_nginx/.env.example``src/.env`
128+
129+
Sets up NGINX as reverse proxy with Gunicorn + Uvicorn workers for production.
130+
131+
> [!CAUTION]
132+
> You MUST change `SECRET_KEY`, all passwords, and sensitive values in the `.env` file before deploying!
133+
134+
**Manual setup:** `./setup.py production` or copy the files above manually.
135+
136+
---
137+
138+
**Start your application:**
112139

113140
```bash
114141
docker compose up
115142
```
116143

117-
### Option 3: Production with NGINX
144+
**Access your app:**
145+
- **Local**: http://127.0.0.1:8000 (auto-reload enabled) → [API docs](http://127.0.0.1:8000/docs)
146+
- **Staging**: http://127.0.0.1:8000 (production-like performance)
147+
- **Production**: http://localhost (NGINX reverse proxy)
118148

119-
Best for: **Production deployments**. Just run these commands:
149+
### Next steps
120150

151+
**Create your first admin user:**
121152
```bash
122-
cp scripts/production_with_nginx/Dockerfile Dockerfile
123-
cp scripts/production_with_nginx/docker-compose.yml docker-compose.yml
124-
cp scripts/production_with_nginx/.env.example src/.env
153+
docker compose run --rm create_superuser
125154
```
126155

127-
> [!CAUTION]
128-
> You MUST change `SECRET_KEY`, all passwords, and sensitive values in the `.env` file before deploying!
129-
130-
And then, to sart:
156+
**Run database migrations** (if you add models):
157+
```bash
158+
cd src && uv run alembic revision --autogenerate && uv run alembic upgrade head
159+
```
131160

161+
**Test background jobs:**
132162
```bash
133-
docker compose up
163+
curl -X POST 'http://127.0.0.1:8000/api/v1/tasks/task?message=hello'
134164
```
135165

136-
Access your application via http://localhost (NGINX proxies to the FastAPI app).
166+
**Or run locally without Docker:**
167+
```bash
168+
uv sync && uv run uvicorn src.app.main:app --reload
169+
```
137170

138171
> Full setup (from-scratch, .env examples, PostgreSQL & Redis, gunicorn, nginx) lives in the [docs](https://benavlabs.github.io/FastAPI-boilerplate/getting-started/installation/).
139172

docs/getting-started/installation.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,35 @@ Install these tools on your system:
3131
cd fastapi-boilerplate
3232
```
3333

34-
1. **Set up environment**:
34+
1. **Quick setup** (recommended):
3535

3636
```bash
37-
cp src/.env.example src/.env
38-
# Edit src/.env with your configuration
37+
# Interactive setup - choose your deployment type
38+
./setup.py
39+
40+
# Or specify directly: ./setup.py local, ./setup.py staging, ./setup.py production
3941
```
4042

43+
This automatically copies the correct `Dockerfile`, `docker-compose.yml`, and `.env` files for your chosen deployment scenario.
44+
4145
1. **Start services**:
4246

4347
```bash
4448
docker compose up -d
4549
```
4650

51+
#### Manual Setup Alternative
52+
53+
If you prefer to set up manually:
54+
55+
```bash
56+
# Copy configuration files for local development
57+
cp scripts/local_with_uvicorn/Dockerfile Dockerfile
58+
cp scripts/local_with_uvicorn/docker-compose.yml docker-compose.yml
59+
cp scripts/local_with_uvicorn/.env.example src/.env
60+
# Edit src/.env with your configuration if needed
61+
```
62+
4763
1. **Verify installation**:
4864

4965
```bash

docs/user-guide/configuration/docker-setup.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22

33
Learn how to configure and run the FastAPI Boilerplate using Docker Compose. The project includes a complete containerized setup with PostgreSQL, Redis, background workers, and optional services.
44

5+
## Quick Start
6+
7+
The fastest way to get started is with the setup script:
8+
9+
```bash
10+
./setup.py
11+
```
12+
13+
This script helps you choose between three deployment configurations:
14+
15+
- **Local development** (`./setup.py local`) - Uvicorn with auto-reload
16+
- **Staging** (`./setup.py staging`) - Gunicorn with workers
17+
- **Production** (`./setup.py production`) - NGINX + Gunicorn
18+
19+
Each option copies the appropriate `Dockerfile`, `docker-compose.yml`, and `.env.example` files from the `scripts/` folder.
20+
521
## Docker Compose Architecture
622

723
The boilerplate includes these core services:

setup.py

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#!/usr/bin/env python3
2+
"""
3+
FastAPI Boilerplate Setup Script
4+
5+
Automates copying the correct configuration files for different deployment scenarios.
6+
"""
7+
8+
import sys
9+
import shutil
10+
from pathlib import Path
11+
12+
DEPLOYMENTS = {
13+
"local": {
14+
"name": "Local development with Uvicorn",
15+
"description": "Auto-reload enabled, development-friendly",
16+
"path": "scripts/local_with_uvicorn"
17+
},
18+
"staging": {
19+
"name": "Staging with Gunicorn managing Uvicorn workers",
20+
"description": "Production-like setup for testing",
21+
"path": "scripts/gunicorn_managing_uvicorn_workers"
22+
},
23+
"production": {
24+
"name": "Production with NGINX",
25+
"description": "Full production setup with reverse proxy",
26+
"path": "scripts/production_with_nginx"
27+
}
28+
}
29+
30+
def show_help():
31+
"""Display help information"""
32+
print("FastAPI Boilerplate Setup")
33+
print("=" * 25)
34+
print()
35+
print("Usage: python setup.py <deployment-type>")
36+
print()
37+
print("Available deployment types:")
38+
for key, config in DEPLOYMENTS.items():
39+
print(f" {key:12} - {config['name']}")
40+
print(f" {' ' * 12} {config['description']}")
41+
print()
42+
print("Examples:")
43+
print(" python setup.py local # Set up for local development")
44+
print(" python setup.py staging # Set up for staging environment")
45+
print(" python setup.py production # Set up for production deployment")
46+
47+
def copy_files(deployment_type: str):
48+
"""Copy configuration files for the specified deployment type"""
49+
if deployment_type not in DEPLOYMENTS:
50+
print(f"❌ Unknown deployment type: {deployment_type}")
51+
print()
52+
show_help()
53+
return False
54+
55+
config = DEPLOYMENTS[deployment_type]
56+
source_path = Path(config["path"])
57+
58+
if not source_path.exists():
59+
print(f"❌ Configuration path not found: {source_path}")
60+
return False
61+
62+
print(f"🚀 Setting up {config['name']}...")
63+
print(f" {config['description']}")
64+
print()
65+
66+
files_to_copy = [
67+
("Dockerfile", "Dockerfile"),
68+
("docker-compose.yml", "docker-compose.yml"),
69+
(".env.example", "src/.env")
70+
]
71+
72+
success = True
73+
for source_file, dest_file in files_to_copy:
74+
source = source_path / source_file
75+
dest = Path(dest_file)
76+
77+
if not source.exists():
78+
print(f"⚠️ Warning: {source} not found, skipping...")
79+
continue
80+
81+
try:
82+
dest.parent.mkdir(parents=True, exist_ok=True)
83+
84+
shutil.copy2(source, dest)
85+
print(f"✅ Copied {source}{dest}")
86+
87+
except Exception as e:
88+
print(f"❌ Failed to copy {source}{dest}: {e}")
89+
success = False
90+
91+
if success:
92+
print()
93+
print("🎉 Setup complete!")
94+
print()
95+
96+
if deployment_type in ["staging", "production"]:
97+
print("⚠️ IMPORTANT: Update the .env file with your production values:")
98+
print(" - Generate a new SECRET_KEY: openssl rand -hex 32")
99+
print(" - Change all passwords and sensitive values")
100+
print()
101+
102+
print("Next steps:")
103+
print(" docker compose up")
104+
105+
if deployment_type == "local":
106+
print(" open http://127.0.0.1:8000/docs")
107+
elif deployment_type == "production":
108+
print(" open http://localhost")
109+
110+
return True
111+
112+
return False
113+
114+
def interactive_setup():
115+
"""Interactive setup when no arguments provided"""
116+
print("FastAPI Boilerplate Setup")
117+
print("=" * 25)
118+
print()
119+
print("Choose your deployment type:")
120+
print()
121+
122+
options = list(DEPLOYMENTS.keys())
123+
for i, key in enumerate(options, 1):
124+
config = DEPLOYMENTS[key]
125+
print(f" {i}. {config['name']}")
126+
print(f" {config['description']}")
127+
print()
128+
129+
while True:
130+
try:
131+
choice = input(f"Enter your choice (1-{len(options)}): ").strip()
132+
133+
if choice.isdigit():
134+
choice_num = int(choice)
135+
if 1 <= choice_num <= len(options):
136+
return options[choice_num - 1]
137+
138+
if choice.lower() in DEPLOYMENTS:
139+
return choice.lower()
140+
141+
print(f"❌ Invalid choice. Please enter 1-{len(options)} or the deployment name.")
142+
143+
except KeyboardInterrupt:
144+
print("\n\n👋 Setup cancelled.")
145+
return None
146+
except EOFError:
147+
print("\n\n👋 Setup cancelled.")
148+
return None
149+
150+
def main():
151+
"""Main entry point"""
152+
if len(sys.argv) > 1 and sys.argv[1] in ["-h", "--help", "help"]:
153+
show_help()
154+
return
155+
156+
if len(sys.argv) == 2:
157+
deployment_type = sys.argv[1].lower()
158+
elif len(sys.argv) == 1:
159+
deployment_type = interactive_setup()
160+
if deployment_type is None:
161+
return
162+
else:
163+
show_help()
164+
return
165+
166+
success = copy_files(deployment_type)
167+
168+
if not success:
169+
sys.exit(1)
170+
171+
if __name__ == "__main__":
172+
main()

0 commit comments

Comments
 (0)