Skip to content

Commit 5324ae1

Browse files
Feature/optimize devcontainer (#53)
1 parent 2c82124 commit 5324ae1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2423
-1320
lines changed

.devcontainer/Dockerfile

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,18 @@ RUN az config set core.login_experience_v2=off 2>/dev/null || true && \
4141
az extension add --name containerapp --only-show-errors 2>/dev/null || true && \
4242
az extension add --name front-door --only-show-errors 2>/dev/null || true
4343

44-
# Configure shell to auto-activate virtual environment
45-
RUN echo "# Auto-activate APIM Samples virtual environment" >> ~/.bashrc && \
46-
echo "if [ -f /workspaces/Apim-Samples/.venv/bin/activate ]; then" >> ~/.bashrc && \
47-
echo " source /workspaces/Apim-Samples/.venv/bin/activate" >> ~/.bashrc && \
48-
echo "fi" >> ~/.bashrc && \
49-
echo "# Auto-activate APIM Samples virtual environment" >> ~/.zshrc && \
50-
echo "if [ -f /workspaces/Apim-Samples/.venv/bin/activate ]; then" >> ~/.zshrc && \
51-
echo " source /workspaces/Apim-Samples/.venv/bin/activate" >> ~/.zshrc && \
52-
echo "fi" >> ~/.zshrc && \
53-
# Add helpful aliases
44+
# Configure shell aliases and helpful commands (venv handled by devcontainer)
45+
RUN echo "# APIM Samples helpful aliases" >> ~/.bashrc && \
5446
echo "alias ll='ls -alF'" >> ~/.bashrc && \
5547
echo "alias la='ls -A'" >> ~/.bashrc && \
5648
echo "alias l='ls -CF'" >> ~/.bashrc && \
57-
echo "alias pytest-cov='python -m pytest --cov=. --cov-report=html'" >> ~/.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
5856

5957
# Set final working directory
6058
WORKDIR /workspaces/Apim-Samples

.devcontainer/README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This directory contains the optimized dev container configuration for the Azure
1616

1717
The dev container uses a **three-stage optimization approach** to minimize startup time:
1818

19-
1. **Build Stage** (Dockerfile): Base system setup and Azure CLI configuration
19+
1. **Build Stage** (Dockerfile): Base system setup, Azure CLI configuration, and VS Code extension pre-installation
2020
2. **Prebuild Stage** (devcontainer.json): Heavy installations and environment setup
2121
3. **Runtime Stage** (post-start-setup.sh): Fast verification and user guidance
2222

@@ -87,6 +87,7 @@ This approach ensures that time-consuming operations happen during container pre
8787
- ✅ Azure CLI extension installation
8888
- ✅ Jupyter kernel registration
8989
- ✅ Environment file generation
90+
- ✅ VS Code extension installation
9091

9192
### What Stays in Runtime
9293
- ✅ Environment verification
@@ -100,6 +101,30 @@ This approach ensures that time-consuming operations happen during container pre
100101
- **Reliability**: Fallback mechanisms ensure robustness
101102
- **Transparency**: Clear status reporting throughout
102103

104+
## 🔌 Pre-installed VS Code Extensions
105+
106+
To further optimize the startup experience, several VS Code extensions are pre-installed in the container image rather than being installed at container startup:
107+
108+
| Extension ID | Description |
109+
|-------------|-------------|
110+
| ms-python.python | Python language support |
111+
| ms-python.debugpy | Python debugging |
112+
| ms-toolsai.jupyter | Jupyter notebook support |
113+
| ms-toolsai.jupyter-keymap | Jupyter keyboard shortcuts |
114+
| ms-toolsai.jupyter-renderers | Jupyter output renderers |
115+
| ms-toolsai.vscode-jupyter-cell-tags | Jupyter cell tags |
116+
| ms-toolsai.vscode-jupyter-slideshow | Jupyter slideshow |
117+
| ms-azuretools.vscode-bicep | Bicep language support |
118+
| ms-vscode.azurecli | Azure CLI support |
119+
| ms-azure-devops.azure-pipelines | Azure Pipelines support |
120+
| redhat.vscode-yaml | YAML language support |
121+
| ms-vscode.vscode-json | JSON language support |
122+
| donjayamanne.vscode-default-python-kernel | Default Python kernel |
123+
124+
A few extensions like GitHub Copilot and Copilot Chat are still installed at container startup because they require authentication or have licensing considerations.
125+
126+
This pre-installation happens in the Dockerfile and significantly reduces container startup time as VS Code doesn't need to download and install these extensions.
127+
103128
## 🔧 Jupyter Kernel Configuration
104129

105130
The dev container is configured with a custom Jupyter kernel for optimal Python development experience:

.devcontainer/devcontainer.json

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json",
23
"name": "APIM Samples",
34
"build": {
45
"dockerfile": "Dockerfile",
@@ -67,28 +68,27 @@
6768
"jupyter.interactiveWindow.textEditor.executeSelection": true,
6869
"jupyter.notebookFileRoot": "${workspaceFolder}",
6970
"jupyter.kernels.excludePythonEnvironments": [
70-
"**/anaconda3/**",
71-
"**/conda/**",
72-
"**/miniconda3/**",
73-
"**/python3.*",
74-
"*/site-packages/*",
75-
"/bin/python",
76-
"/bin/python3",
77-
"/opt/python/*/bin/python*",
78-
"/usr/bin/python",
79-
"/usr/bin/python3",
80-
"/usr/local/bin/python",
81-
"/usr/local/bin/python3",
82-
"python",
83-
"python3"
71+
"**/anaconda3/**",
72+
"**/conda/**",
73+
"**/miniconda3/**",
74+
"**/python3.*",
75+
"*/site-packages/*",
76+
"/bin/python",
77+
"/bin/python3",
78+
"/opt/python/*/bin/python*",
79+
"/usr/bin/python",
80+
"/usr/bin/python3",
81+
"/usr/local/bin/python",
82+
"/usr/local/bin/python3",
83+
"python",
84+
"python3"
8485
],
8586
"jupyter.kernels.trusted": [
8687
"/workspaces/Apim-Samples/.venv/bin/python"
8788
],
8889
"files.associations": {
8990
"*.bicep": "bicep"
9091
},
91-
// Auto-show terminal output during codespace startup
9292
"terminal.integrated.showExitAlert": false,
9393
"terminal.integrated.focusAfterRun": "terminal",
9494
"terminal.integrated.defaultProfile.linux": "bash",
@@ -98,35 +98,34 @@
9898
"workbench.startupEditor": "none",
9999
"workbench.panel.defaultPanelHeight": 400,
100100
"workbench.view.alwaysShowHeaderActions": true,
101-
// Auto-open terminal panel on startup
102101
"workbench.action.terminal.focus": true,
103102
"workbench.action.togglePanel": true,
104103
"terminal.integrated.defaultLocation": "view",
105-
// Auto-allow clipboard operations in Codespaces
106104
"security.workspace.trust.enabled": false,
107105
"editor.experimental.pasteActions.enabled": true,
108106
"workbench.editor.enablePreview": false
109107
}
108+
},
109+
"containerEnv": {
110+
"PATH": "/workspaces/Apim-Samples/.venv/bin:${PATH}",
111+
"PYTHONPATH": "/workspaces/Apim-Samples/shared/python:/workspaces/Apim-Samples",
112+
"VIRTUAL_ENV": "/workspaces/Apim-Samples/.venv"
110113
}
111114
},
112-
"containerEnv": {
113-
"PYTHONPATH": "/workspaces/Apim-Samples/shared/python:/workspaces/Apim-Samples"
114-
},
115-
// Container lifecycle commands for optimal Codespaces prebuild performance: https://containers.dev/implementors/features/#lifecycle-hooks
116-
// 1. onCreateCommand: Runs only once during initial prebuild - creates venv
117-
// 2. updateContentCommand: Runs during any prebuild when content changes - installs/updates packages
118-
// 3. postStartCommand: Runs on every startup - verifies and configures
119115
"onCreateCommand": [
120-
"bash", "-c",
121-
"echo '🚀 Creating Python virtual environment in workspace...' && /usr/local/bin/python3.12 -m venv /workspaces/Apim-Samples/.venv --copies && source /workspaces/Apim-Samples/.venv/bin/activate && pip install --upgrade pip setuptools wheel && echo '✅ Virtual environment created'"
116+
"bash",
117+
"-c",
118+
"echo '🚀 Creating Python virtual environment in workspace...' && /usr/local/bin/python3.12 -m venv /workspaces/Apim-Samples/.venv --copies && source /workspaces/Apim-Samples/.venv/bin/activate && pip install --upgrade pip setuptools wheel ipykernel && echo '✅ Virtual environment created' && echo '🔧 Registering Jupyter kernel during prebuild...' && python -m ipykernel install --user --name=apim-samples --display-name='APIM Samples Python 3.12' && echo '🧹 Removing default python3 kernel...' && rm -rf /workspaces/Apim-Samples/.venv/share/jupyter/kernels/python3 2>/dev/null || true && echo '✅ Jupyter kernel registered in prebuild'"
122119
],
123120
"updateContentCommand": [
124-
"bash", "-c",
125-
"echo '📦 Installing/updating Python packages from requirements.txt...' && source /workspaces/Apim-Samples/.venv/bin/activate && pip install -r requirements.txt && pip install pytest pytest-cov coverage ipykernel && echo '✅ Python packages installed/updated' && python setup/setup_python_path.py --generate-env && echo '✅ Environment configuration updated' && echo '🔧 Registering Jupyter kernel...' && python -m ipykernel install --user --name=apim-samples --display-name='APIM Samples Python 3.12' && echo '✅ Jupyter kernel registered' && echo '⚙️ Configuring Azure CLI...' && az config set core.login_experience_v2=off 2>/dev/null || true && az extension add --name containerapp --only-show-errors 2>/dev/null || true && az extension add --name front-door --only-show-errors 2>/dev/null || true && echo '✅ Azure CLI configured for Codespaces'"
121+
"bash",
122+
"-c",
123+
"echo '📦 Installing/updating Python packages from requirements.txt...' && source /workspaces/Apim-Samples/.venv/bin/activate && pip install -r requirements.txt && pip install pytest pytest-cov coverage && echo '✅ Python packages installed/updated' && python setup/setup_python_path.py --generate-env && echo '✅ Environment configuration updated' && echo '⚙️ Configuring Azure CLI...' && az config set core.login_experience_v2=off 2>/dev/null || true && az extension add --name containerapp --only-show-errors 2>/dev/null || true && az extension add --name front-door --only-show-errors 2>/dev/null || true && echo '✅ Azure CLI configured for Codespaces'"
126124
],
127125
"postStartCommand": [
128-
"bash", "-c",
129-
"echo '� APIM Samples Codespace Starting - Keep this terminal open to see progress!' && echo '============================================================' && bash .devcontainer/post-start-setup.sh && echo '============================================================' && echo '✅ Setup completed! This terminal will remain open for your reference.' && echo '💡 Tip: You can minimize this panel if needed, but the setup logs above show your environment status.' && sleep 2"
126+
"bash",
127+
"-c",
128+
"echo 'APIM Samples Codespace Starting - Keep this terminal open to see progress!' && bash .devcontainer/post-start-setup.sh"
130129
],
131130
"forwardPorts": [
132131
8000,

.devcontainer/post-start-setup.sh

Lines changed: 32 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,176 +1,78 @@
11
#!/bin/bash
22

33
# ------------------------------
4-
# APIM SAMPLES POST-START VERIFICATION
4+
# APIM SAMPLES INSTANT VERIFICATION
55
# ------------------------------
66

77
start=$(date +%s.%N)
88

99
# Make terminal output more prominent
1010
clear
1111
echo "============================================================================"
12-
echo " 🚀 APIM SAMPLES CODESPACE VERIFICATION "
12+
echo " 🚀 APIM SAMPLES - INSTANT VERIFICATION "
1313
echo "============================================================================"
1414
echo ""
15-
echo "🔧 This terminal shows the Codespace verification progress."
16-
echo "📋 Keep this panel open to monitor the environment status."
15+
echo "⚡ All heavy setup was completed during prebuild - verifying environment..."
1716
echo ""
18-
echo -e "✅ Most setup completed during prebuild - verifying environment...\n"
1917

2018
# ------------------------------
21-
# CONFIGURATION
19+
# LIGHTNING FAST VERIFICATION
2220
# ------------------------------
2321

24-
echo -e "1/5) Detecting & setting environment variables...\n"
25-
2622
WORKSPACE_ROOT="/workspaces/Apim-Samples"
2723
VENV_PATH="$WORKSPACE_ROOT/.venv"
28-
PYTHON_EXECUTABLE="$VENV_PATH/bin/python"
29-
30-
echo " Workspace : $WORKSPACE_ROOT"
31-
echo " Virtual Environment : $VENV_PATH"
32-
echo " Python Executable : $PYTHON_EXECUTABLE"
33-
34-
# Activate virtual environment to get the correct Python version
35-
source "$VENV_PATH/bin/activate" 2>/dev/null || true
36-
PYTHON_VERSION=$(python --version | grep "Python" | awk '{print $2}')
37-
echo " Python Version : $PYTHON_VERSION"
38-
39-
# Extract Azure CLI version (suppress warnings and get just the version number)
40-
AZ_CLI_VERSION=$(az --version 2>/dev/null | grep "azure-cli" | awk '{print $2}' | head -1)
41-
echo " Azure CLI Version : $AZ_CLI_VERSION"
42-
43-
# ------------------------------
44-
# ENVIRONMENT VERIFICATION
45-
# ------------------------------
4624

47-
echo -e "\n2/5) Verifying virtual environment...\n"
25+
echo -e "Environment Status:\n"
4826

49-
# Verify virtual environment exists
27+
# Ultra-fast file system checks (no command execution)
5028
if [ -d "$VENV_PATH" ]; then
51-
echo " ✅ Virtual environment found at $VENV_PATH"
52-
if [ -f "$PYTHON_EXECUTABLE" ]; then
53-
echo " ✅ Python executable available"
54-
# Activate and verify
55-
source "$VENV_PATH/bin/activate"
56-
echo " ✅ Python version : $PYTHON_VERSION"
57-
# Commenting out the number of packages installed as this does take some time to run. When the setup was verified, a count of 125 packages was printed.
58-
# echo " ✅ Packages installed: $(pip list | wc -l)"
59-
else
60-
echo " ❌ Python executable not found"
61-
exit 1
62-
fi
63-
else
64-
echo " ❌ Virtual environment not found at $VENV_PATH"
65-
echo " 💡 Virtual environment should have been created during container setup"
66-
exit 1
67-
fi
68-
69-
# ------------------------------
70-
# ENVIRONMENT FILE VERIFICATION
71-
# ------------------------------
72-
73-
echo -e "\n3/5) Verifying .env file...\n"
74-
75-
cd "$WORKSPACE_ROOT"
76-
if [ -f ".env" ]; then
77-
echo " ✅ .env file exists"
29+
echo " ✅ Virtual environment"
7830
else
79-
echo " ⚠️ .env file missing, regenerating..."
80-
if [ -f "setup/setup_python_path.py" ]; then
81-
python setup/setup_python_path.py --generate-env
82-
echo " ✅ .env file regenerated"
83-
else
84-
echo " ⚠️ setup_python_path.py not found, creating basic .env"
85-
cat > .env << EOF
86-
# Auto-generated for APIM Samples dev container
87-
PROJECT_ROOT=$WORKSPACE_ROOT
88-
PYTHONPATH=$WORKSPACE_ROOT/shared/python:$WORKSPACE_ROOT
89-
EOF
90-
echo " ✅ Basic .env file created"
91-
fi
31+
echo " ❌ Virtual environment missing"
9232
fi
9333

94-
# ------------------------------
95-
# AZURE CLI VERIFICATION
96-
# ------------------------------
97-
98-
echo -e "\n4/5) Verifying Azure CLI configuration...\n"
99-
100-
# Verify Azure CLI extensions are installed (they should be from prebuild)
101-
echo " Checking Azure CLI extensions..."
102-
if az extension list --query "[?name=='containerapp']" -o tsv | grep -q "containerapp"; then
103-
echo " ✅ containerapp extension installed"
34+
if [ -f "$WORKSPACE_ROOT/.env" ]; then
35+
echo " ✅ Environment file"
10436
else
105-
echo " ⚠️ containerapp extension missing, installing..."
106-
az extension add --name containerapp --only-show-errors 2>/dev/null || true
37+
echo " ❌ Environment file missing"
10738
fi
10839

109-
if az extension list --query "[?name=='front-door']" -o tsv | grep -q "front-door"; then
110-
echo " ✅ front-door extension installed"
40+
# Quick command availability checks (fast)
41+
if command -v az >/dev/null 2>&1; then
42+
echo " ✅ Azure CLI"
11143
else
112-
echo " ⚠️ front-door extension missing, installing..."
113-
az extension add --name front-door --only-show-errors 2>/dev/null || true
44+
echo " ❌ Azure CLI missing"
11445
fi
11546

116-
# Verify Azure CLI configuration
117-
echo " ✅ Azure CLI configured for device code authentication"
118-
119-
# ------------------------------
120-
# FINAL VERIFICATION
121-
# ------------------------------
122-
123-
echo -e "\n5/5) Environment Summary\n"
124-
echo " Virtual Environment : $VIRTUAL_ENV"
125-
echo " Python : $PYTHON_VERSION at $(which python)"
126-
# Commenting out the number of packages installed as this does take some time to run. When the setup was verified, a count of 125 packages was printed.
127-
# echo " Packages: $(pip list | wc -l) installed"
128-
echo " .env File exists? : $([ -f .env ] && echo "" || echo "")"
129-
echo " Azure CLI Version : $AZ_CLI_VERSION"
130-
131-
# Verify Jupyter kernel registration
132-
echo " Jupyter Kernels : $(jupyter kernelspec list --json | python -c "import sys, json; data=json.load(sys.stdin); print(len(data['kernelspecs'])) if 'kernelspecs' in data else print('0')" 2>/dev/null || echo "unknown")"
133-
134-
if jupyter kernelspec list | grep -q "apim-samples" 2>/dev/null; then
135-
echo " APIM Samples Kernel : ✅"
47+
if command -v python >/dev/null 2>&1; then
48+
echo " ✅ Python"
13649
else
137-
echo " APIM Samples Kernel : ⚠️ (missing, re-registering...)"
138-
python -m ipykernel install --user --name=apim-samples --display-name="APIM Samples Python 3.12" 2>/dev/null && echo " ✅ Kernel registered successfully" || echo " ❌ Failed to register kernel"
50+
echo " ❌ Python missing"
13951
fi
14052

141-
# Test core imports
142-
python -c "
143-
try:
144-
import requests, jwt, pandas, matplotlib, azure.identity
145-
print(f' Core packages : ✅')
146-
except ImportError as e:
147-
print(f' Core packages : ❌')
148-
print(f' {e}')
149-
"
150-
151-
# Calculate total duration using Python
53+
# Calculate total duration
15254
end=$(date +%s.%N)
153-
duration=$(python3 -c "print(f'{float('$end') - float('$start'):.2f}')")
55+
duration=$(python3 -c "print(f'{float('$end') - float('$start'):.1f}')" 2>/dev/null || echo "0.1")
15456

15557
echo ""
15658
echo "============================================================================"
157-
echo " 🎉 VERIFICATION COMPLETED! "
59+
echo " ⚡ INSTANT VERIFICATION COMPLETE! "
15860
echo "============================================================================"
15961
echo ""
160-
printf "⏱️ Total verification time: %s seconds\n" "$duration"
161-
echo "💡 Environment prebuild optimizations have significantly reduced startup time!"
162-
echo ""
163-
echo "🔍 This terminal shows your Codespace verification progress and logs."
164-
echo "📋 You can minimize this panel or open a new terminal for your work."
62+
printf "⏱️ Verification time: %s seconds\n" "$duration"
16563
echo ""
166-
echo "🚀 Your APIM Samples environment is ready to use!"
64+
echo "🎉 Your APIM Samples environment is ready to use!"
65+
echo -e "\n"
66+
echo " Next Steps:"
16767
echo ""
68+
echo " 1. Open a new terminal and log in via the Azure CLI: az login"
16869
echo ""
169-
echo " NEXT STEPS:"
170-
echo " -----------"
70+
echo " 2. Wait until Codespace is fully started (it's fairly quick):"
71+
echo " - Watch progress indicators in status bar"
72+
echo " - Wait for all extensions to install"
73+
echo " --> ✅ (.venv) prefix will appear when you open a new terminal"
17174
echo ""
172-
echo " 1. Log in via the Azure CLI: az login"
173-
echo " 2. Start using the infrastructures and samples!"
75+
echo " 3. Start using the infrastructures and samples!"
17476
echo ""
17577
echo "============================================================================"
176-
echo -e "\n\n\n"
78+
echo -e "\n\n"

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ labs-in-progress/
2929
tests/python/htmlcov/
3030

3131
shared/bicep/modules/**/*.json
32-
main.json
32+
main.json
33+
34+
Test-Matrix.html

0 commit comments

Comments
 (0)