Skip to content

Commit a02839b

Browse files
Devcontainer config for developing in codespaces
1 parent f103e88 commit a02839b

File tree

5 files changed

+126
-1
lines changed

5 files changed

+126
-1
lines changed

.devcontainer/devcontainer.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "FastAPI Jinja2 Postgres WebApp",
3+
"workspaceFolder": "/workspaces/fastapi-jinja2-postgres-webapp",
4+
5+
// Ensure .env exists before Docker Compose processes env_file entries
6+
"initializeCommand": "bash .devcontainer/ensure-env.sh",
7+
8+
// Start the Postgres sidecar using the existing compose file
9+
"dockerComposeFile": [
10+
"../docker-compose.yml",
11+
"docker-compose.yml"
12+
],
13+
"service": "app",
14+
"runServices": ["db"],
15+
"shutdownAction": "stopCompose",
16+
17+
// Forward common app/db ports
18+
"forwardPorts": [8000, 5432],
19+
"portsAttributes": {
20+
"8000": { "label": "FastAPI", "onAutoForward": "openBrowser" },
21+
"5432": { "label": "PostgreSQL" }
22+
},
23+
24+
// Prepare env, install uv, and sync deps
25+
"postCreateCommand": "bash .devcontainer/init-env.sh && curl -LsSf https://astral.sh/uv/install.sh | sh && ~/.local/bin/uv sync",
26+
27+
"customizations": {
28+
"vscode": {
29+
"extensions": [
30+
"ms-python.python",
31+
"ms-python.vscode-pylance"
32+
]
33+
}
34+
}
35+
}
36+

.devcontainer/docker-compose.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
services:
2+
app:
3+
image: mcr.microsoft.com/devcontainers/python:3.13-bookworm
4+
container_name: fastapi-jinja2-postgres-webapp-app
5+
volumes:
6+
- ..:/workspaces/fastapi-jinja2-postgres-webapp:cached
7+
working_dir: /workspaces/fastapi-jinja2-postgres-webapp
8+
depends_on:
9+
- db
10+
env_file:
11+
- ../.env
12+
command: sleep infinity
13+
14+
# Override/augment settings for the db service defined in the root compose file
15+
db:
16+
# Avoid requiring a project-level .env during compose evaluation
17+
env_file: []
18+
environment:
19+
POSTGRES_USER: ${DB_USER:-postgres}
20+
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
21+
POSTGRES_DB: ${DB_NAME:-fastapi-jinja2-postgres-webapp}
22+
ports:
23+
- "5432:5432"
24+
25+
# Note: The 'db' service is defined in the repository root docker-compose.yml.
26+
# This file is merged with that one via devcontainer.json dockerComposeFile array.
27+

.devcontainer/ensure-env.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Run from repo root
5+
cd "$(dirname "${BASH_SOURCE[0]}")/.."
6+
7+
# Ensure a .env exists BEFORE docker compose evaluates env_file
8+
if [ ! -f ".env" ]; then
9+
if [ -f ".env.example" ]; then
10+
cp .env.example .env || true
11+
else
12+
touch .env
13+
fi
14+
fi
15+
16+
echo ".env ensured for compose evaluation."
17+

.devcontainer/init-env.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Run from repo root
5+
cd "$(dirname "${BASH_SOURCE[0]}")/.."
6+
7+
# Ensure a working .env exists
8+
if [ ! -f ".env" ]; then
9+
if [ -f ".env.example" ]; then
10+
cp .env.example .env || true
11+
else
12+
touch .env
13+
fi
14+
fi
15+
16+
# Ensure DB_HOST points to the compose service name for in-container access
17+
if grep -q '^DB_HOST=' .env; then
18+
sed -i 's/^DB_HOST=.*/DB_HOST=db/' .env
19+
else
20+
echo 'DB_HOST=db' >> .env
21+
fi
22+
23+
generate_secret() {
24+
if command -v openssl >/dev/null 2>&1; then
25+
openssl rand -base64 32
26+
else
27+
python - <<'PY'
28+
import base64, os
29+
print(base64.b64encode(os.urandom(32)).decode('ascii'))
30+
PY
31+
fi
32+
}
33+
34+
# Ensure SECRET_KEY exists and is non-empty/non-placeholder
35+
if grep -q '^SECRET_KEY=' .env; then
36+
current_secret="$(grep '^SECRET_KEY=' .env | cut -d= -f2-)"
37+
if [ -z "${current_secret}" ] || [ "${current_secret}" = "changeme" ] || [ "${current_secret}" = "REPLACE_ME" ]; then
38+
new_secret="$(generate_secret)"
39+
sed -i "s/^SECRET_KEY=.*/SECRET_KEY=${new_secret}/" .env
40+
fi
41+
else
42+
echo "SECRET_KEY=$(generate_secret)" >> .env
43+
fi
44+
45+
echo "Environment prepared. DB_HOST set to 'db' and SECRET_KEY ensured."
46+

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
.devcontainer
21
__pycache__
32
*.pyc
43
.env

0 commit comments

Comments
 (0)