Skip to content

Commit b1f715d

Browse files
Feature/optimize dev containers (#112)
1 parent bb86623 commit b1f715d

File tree

13 files changed

+323
-749
lines changed

13 files changed

+323
-749
lines changed

.devcontainer/README.md

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ This directory contains the optimized dev container configuration for the Azure
1515

1616
## 🎯 Overview
1717

18+
This repository provides three prebuilt dev container configurations, one for each current Python version: 3.12, 3.13, and 3.14. When creating a new Codespace, select the variant you prefer — all variants are functionally equivalent for this project and differ only by Python runtime version.
19+
1820
The dev container uses a **three-stage optimization approach** to minimize startup time:
1921

2022
1. **Build Stage** (Dockerfile): Base system setup, Azure CLI configuration, and VS Code extension pre-installation
@@ -29,36 +31,60 @@ This approach ensures that time-consuming operations happen during container pre
2931

3032
| File | Purpose | Stage |
3133
|------|---------|-------|
32-
| `devcontainer.json` | Main dev container configuration | All |
33-
| `Dockerfile` | Container image definition | Build |
34-
| `post-start-setup.sh` | Runtime verification script | Runtime |
34+
| `python312/devcontainer.json` | Dev container configuration (Python 3.12) | All |
35+
| `python312/Dockerfile` | Container image definition (Python 3.12) | Build |
36+
| `python313/devcontainer.json` | Dev container configuration (Python 3.13) | All |
37+
| `python313/Dockerfile` | Container image definition (Python 3.13) | Build |
38+
| `python314/devcontainer.json` | Dev container configuration (Python 3.14) | All |
39+
| `python314/Dockerfile` | Container image definition (Python 3.14) | Build |
40+
| `post-start-setup.sh` | Shared runtime verification script | Runtime |
3541
| `README.md` | This documentation | - |
3642

3743
### Configuration Details
3844

39-
#### `devcontainer.json`
45+
#### `devcontainer.json` (per Python version folder)
4046
- **Features**: Azure CLI, common utilities, Git, Docker-in-Docker
4147
- **Extensions**: Python, Jupyter, Bicep, GitHub Copilot, and more
4248
- **Lifecycle Commands**: Optimized three-stage setup
4349
- **Port Forwarding**: Common development ports (3000, 5000, 8000, 8080)
4450

45-
#### `Dockerfile`
46-
- **Base Image**: Microsoft's Python 3.12 dev container
51+
#### `Dockerfile` (per Python version folder)
52+
- **Base Image**: Microsoft's Python 3.12/3.13/3.14 dev container (depending on folder)
4753
- **System Dependencies**: Essential packages and tools
4854
- **Azure CLI Setup**: Extensions and configuration for Codespaces
4955
- **Virtual Environment**: Auto-activation configuration
5056

51-
#### `post-start-setup.sh`
57+
#### `post-start-setup.sh` (shared behavior)
58+
- **Location**: `.devcontainer/post-start-setup.sh` is invoked by each Python variant's `post-start-setup.sh` wrapper
5259
- **Environment Verification**: Quick checks and status reporting
5360
- **Fallback Installation**: Safety net for missing components
5461
- **User Guidance**: Next steps and helpful information
5562

63+
## 🧭 Choosing a Dev Container in Codespaces
64+
65+
When creating a new Codespace, GitHub will present multiple dev container options derived from the `.devcontainer` subfolders:
66+
67+
- **APIM Samples – Python 3.12** ✅ (folder: `python312`)
68+
- **APIM Samples – Python 3.13** ✅ (folder: `python313`)
69+
- **APIM Samples – Python 3.14** ✅ (folder: `python314`)
70+
71+
All three are supported and prebuilt; choose the Python runtime that best matches your needs or local environment.
72+
73+
### ⚠️ About the "Default" Option
74+
75+
GitHub Codespaces will also display a generic **"Default"** dev container option. **Do not use this option** — it will result in:
76+
- Significantly slower startup times (5-10 minutes vs. ~30 seconds)
77+
- Missing tools, extensions, and optimizations
78+
- Suboptimal development experience
79+
80+
**Always select one of the three Python-specific configurations above.** Unfortunately, GitHub does not currently provide a way to remove the default option from the Codespace creation dialog. This is a GitHub limitation, and we recommend always selecting one of the optimized Python variants.
81+
5682
## 🚀 Setup Stages
5783

5884
### Stage 1: Container Build (Dockerfile)
5985
**When it runs**: During initial container build
6086
**What it does**:
61-
- Installs Python 3.12 and system dependencies
87+
- Installs the selected Python version (3.12, 3.13, or 3.14) and system dependencies
6288
- Configures Azure CLI for Codespaces (device code authentication)
6389
- Installs Azure CLI extensions (`containerapp`, `front-door`)
6490
- Sets up shell auto-activation for virtual environment
@@ -160,11 +186,12 @@ Our devcontainer uses two key lifecycle commands optimized for prebuild:
160186
#### `onCreateCommand` (Container Creation)
161187
```bash
162188
# Creates Python virtual environment and registers Jupyter kernel
189+
# Note: The Python path varies by selected variant (3.12/3.13/3.14)
163190
echo '🚀 Creating Python virtual environment in workspace...' &&
164-
/usr/local/bin/python3.12 -m venv /workspaces/Apim-Samples/.venv --copies &&
191+
/usr/local/bin/python3.<version> -m venv /workspaces/Apim-Samples/.venv --copies &&
165192
source /workspaces/Apim-Samples/.venv/bin/activate &&
166193
pip install --upgrade pip setuptools wheel ipykernel &&
167-
python -m ipykernel install --user --name=apim-samples --display-name='APIM Samples Python 3.12'
194+
python -m ipykernel install --user --name=python-venv --display-name='Python (.venv)'
168195
```
169196

170197
#### `updateContentCommand` (Content Updates)
@@ -187,6 +214,14 @@ Prebuild automatically occurs when you push changes to:
187214
- `requirements.txt` (when referenced in `updateContentCommand`)
188215
- Any other files referenced in lifecycle commands
189216

217+
### Caching Strategy
218+
219+
This project relies on GitHub Codespaces Prebuilds for fast startup and predictable environments:
220+
221+
- Main branch: Prebuilds are automatically triggered and cached when `.devcontainer/**` or `requirements.txt` changes. Opening a Codespace on main pulls the prebuilt image, typically starting in ~30 seconds.
222+
- Feature branches: If prebuilds are not enabled, the first Codespace startup builds from the Dockerfile (usually a few minutes with the optimized images). Subsequent starts reuse Codespaces' transient cache.
223+
- Registry images (optional): If you later need deterministic, versioned images across many branches or forks, you can publish images to GHCR and reference the tags directly in `devcontainer.json`. For now, prebuilds on main are sufficient.
224+
190225
### Monitoring Prebuild Status
191226

192227
You can monitor prebuild status in several ways:
@@ -249,16 +284,16 @@ To refresh the prebuilt container (recommended periodically):
249284

250285
## 🔧 Jupyter Kernel Configuration
251286

252-
The dev container is configured with a custom Jupyter kernel for optimal Python development experience:
287+
The dev container is configured with a standardized Jupyter kernel for optimal Python development experience:
253288

254-
- **Kernel Name**: `apim-samples`
255-
- **Display Name**: "APIM Samples Python 3.12"
289+
- **Kernel Name**: `python-venv`
290+
- **Display Name**: "Python (.venv)"
256291
- **Python Path**: `/workspaces/Apim-Samples/.venv/bin/python`
257292

258293
### Kernel Registration Details
259294
The kernel is automatically registered during the prebuild stage using:
260295
```bash
261-
python -m ipykernel install --user --name=apim-samples --display-name="APIM Samples Python 3.12"
296+
python -m ipykernel install --user --name=python-venv --display-name="Python (.venv)"
262297
```
263298

264299
### VS Code Kernel Configuration
@@ -300,7 +335,7 @@ az extension add --name front-door
300335
**Symptom**: Kernel not visible in VS Code
301336
**Solution**: Re-register the kernel:
302337
```bash
303-
python -m ipykernel install --user --name=apim-samples --display-name="APIM Samples Python 3.12"
338+
python -m ipykernel install --user --name=python-venv --display-name="Python (.venv)"
304339
```
305340

306341
#### Environment Variables Not Set

.devcontainer/post-start-setup.sh

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/bin/bash
2+
3+
# ------------------------------
4+
# APIM SAMPLES INSTANT VERIFICATION
5+
# ------------------------------
6+
7+
start=$(date +%s.%N)
8+
9+
# Make terminal output more prominent
10+
clear
11+
echo "============================================================================"
12+
echo " 🚀 APIM SAMPLES - INSTANT VERIFICATION "
13+
echo "============================================================================"
14+
echo ""
15+
echo "⚡ All heavy setup was completed during prebuild - verifying environment..."
16+
echo ""
17+
18+
# ------------------------------
19+
# LIGHTNING FAST VERIFICATION
20+
# ------------------------------
21+
22+
WORKSPACE_ROOT="/workspaces/Apim-Samples"
23+
VENV_PATH="$WORKSPACE_ROOT/.venv"
24+
PY_VERSION=$(python --version 2>/dev/null | awk '{print $2}' | cut -d'.' -f1,2)
25+
PY_VERSION_DISPLAY=${PY_VERSION:-"unknown"}
26+
27+
echo -e "Environment Status:\n"
28+
29+
# Ultra-fast file system checks (no command execution)
30+
if [ -d "$VENV_PATH" ]; then
31+
echo " ✅ Virtual environment"
32+
else
33+
echo " ❌ Virtual environment missing"
34+
fi
35+
36+
if [ -f "$WORKSPACE_ROOT/.env" ]; then
37+
echo " ✅ Environment file"
38+
else
39+
echo " ❌ Environment file missing"
40+
fi
41+
42+
# Quick command availability checks (fast)
43+
if command -v az >/dev/null 2>&1; then
44+
echo " ✅ Azure CLI"
45+
else
46+
echo " ❌ Azure CLI missing"
47+
fi
48+
49+
if command -v python >/dev/null 2>&1; then
50+
echo " ✅ Python (${PY_VERSION_DISPLAY})"
51+
else
52+
echo " ❌ Python missing"
53+
fi
54+
55+
# Calculate total duration
56+
end=$(date +%s.%N)
57+
duration=$(python3 -c "print(f'{float('$end') - float('$start'):.1f}')" 2>/dev/null || echo "0.1")
58+
59+
echo ""
60+
echo "============================================================================"
61+
echo " ⚡ INSTANT VERIFICATION COMPLETE! "
62+
echo "============================================================================"
63+
echo ""
64+
printf "⏱️ Verification time: %s seconds\n" "$duration"
65+
echo ""
66+
echo "🎉 Your APIM Samples environment is ready to use!"
67+
echo -e "\n"
68+
echo " Next Steps:"
69+
echo ""
70+
echo " 1. Open a new terminal and log in via the Azure CLI with either command."
71+
echo " See TROUBLESHOOTING.md in the root for details."
72+
echo ""
73+
echo " - az login"
74+
echo " - az login --tenant <your-tenant-id>"
75+
echo ""
76+
echo " 2. Wait until Codespace is fully started (it's fairly quick):"
77+
echo " - Watch progress indicators in status bar"
78+
echo " - Wait for all extensions to install"
79+
echo " --> ✅ (.venv) prefix will appear when you open a new terminal"
80+
echo ""
81+
echo " 3. Start using the infrastructures and samples!"
82+
echo " - You may initially need to select the kernel (top-right above the"
83+
echo " Jupyter notebook). If so, select the '.venv' Python environment."
84+
echo ""
85+
echo "============================================================================"
86+
echo -e "\n\n"

.devcontainer/python312/Dockerfile

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,14 @@ ENV PYTHONUNBUFFERED=1 \
1616
PYTHONPATH=/workspaces/Apim-Samples/shared/python:/workspaces/Apim-Samples \
1717
DEBIAN_FRONTEND=noninteractive
1818

19-
# Install system dependencies as root
19+
# Install minimal system dependencies as root
2020
USER root
2121
RUN --mount=type=cache,target=/var/cache/apt \
2222
--mount=type=cache,target=/var/lib/apt/lists \
2323
apt-get update && \
24-
# Remove Python 3.11 and other versions if they exist
25-
apt-get remove -y python3.11* python3-minimal python3.11-minimal || true && \
26-
apt-get autoremove -y && \
27-
# Install essential packages
28-
apt-get install -y --no-install-recommends curl wget jq tree git-lfs vim nano htop && \
24+
apt-get install -y --no-install-recommends curl git-lfs && \
2925
apt-get clean && \
30-
# Create symbolic links to ensure python3 points to Python 3.12
31-
ln -sf /usr/local/bin/python3.12 /usr/bin/python3 && \
32-
ln -sf /usr/local/bin/python3.12 /usr/bin/python && \
33-
# Ensure latest pip is installed for Python 3.12
26+
rm -rf /var/lib/apt/lists/* && \
3427
/usr/local/bin/python3.12 -m pip install --upgrade pip setuptools wheel
3528

3629
# Switch to vscode user
@@ -41,30 +34,17 @@ RUN az config set core.login_experience_v2=off 2>/dev/null || true && \
4134
az extension add --name containerapp --only-show-errors 2>/dev/null || true && \
4235
az extension add --name front-door --only-show-errors 2>/dev/null || true
4336

44-
# Configure shell aliases and helpful commands (venv handled by devcontainer)
45-
RUN echo "# APIM Samples helpful aliases" >> ~/.bashrc && \
46-
echo "alias ll='ls -alF'" >> ~/.bashrc && \
47-
echo "alias la='ls -A'" >> ~/.bashrc && \
48-
echo "alias l='ls -CF'" >> ~/.bashrc && \
49-
echo "alias pytest-cov='python -m pytest --cov=. --cov-report=html'" >> ~/.bashrc && \
50-
echo "" >> ~/.zshrc && \
51-
echo "# APIM Samples helpful aliases" >> ~/.zshrc && \
52-
echo "alias ll='ls -alF'" >> ~/.zshrc && \
53-
echo "alias la='ls -A'" >> ~/.zshrc && \
54-
echo "alias l='ls -CF'" >> ~/.zshrc && \
55-
echo "alias pytest-cov='python -m pytest --cov=. --cov-report=html'" >> ~/.zshrc
56-
5737
# Set final working directory
5838
WORKDIR /workspaces/Apim-Samples
5939

6040
# Add health check for the virtual environment
6141
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
62-
CMD . /workspaces/Apim-Samples/.venv/bin/activate && python -c "import sys, pip; print(f'Python {sys.version}'); print(f'Pip {pip.__version__}'); import requests, jwt; print('Core packages OK')" || exit 1
42+
CMD . /workspaces/Apim-Samples/.venv/bin/activate && python -c "import sys, pip; print(f'Python {sys.version}'); print(f'Pip {pip.__version__}')" || exit 1
6343

6444
# Add labels for maintainability
6545
LABEL maintainer="APIM Samples Team" \
66-
description="Simplified dev container for Azure API Management samples with Codespaces prebuild optimization" \
67-
version="2.1" \
68-
python.version="3.12" \
69-
debian.version="bookworm" \
70-
venv.location="/workspaces/Apim-Samples/.venv"
46+
description="Optimized dev container for Azure API Management samples with Codespaces prebuild support" \
47+
version="2.2" \
48+
python.version="3.12" \
49+
debian.version="bookworm" \
50+
venv.location="/workspaces/Apim-Samples/.venv"

0 commit comments

Comments
 (0)