Skip to content

Commit 9bca710

Browse files
Create distinct dev containers for all Python versions (#110)
1 parent ff0765b commit 9bca710

File tree

9 files changed

+628
-0
lines changed

9 files changed

+628
-0
lines changed
File renamed without changes.

.devcontainer/python313/Dockerfile

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# https://github.com/devcontainers/images/tree/main/src/python
2+
3+
# syntax=docker/dockerfile:1.4
4+
5+
# Use single-stage build with Python 3.13
6+
FROM mcr.microsoft.com/devcontainers/python:1-3.13-bookworm
7+
8+
# Set build arguments
9+
ARG PYTHON_VERSION=3.13
10+
11+
# Set environment variables
12+
ENV PYTHONUNBUFFERED=1 \
13+
PYTHONDONTWRITEBYTECODE=1 \
14+
PIP_NO_CACHE_DIR=1 \
15+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
16+
PYTHONPATH=/workspaces/Apim-Samples/shared/python:/workspaces/Apim-Samples \
17+
DEBIAN_FRONTEND=noninteractive
18+
19+
# Install system dependencies as root
20+
USER root
21+
RUN --mount=type=cache,target=/var/cache/apt \
22+
--mount=type=cache,target=/var/lib/apt/lists \
23+
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 && \
29+
apt-get clean && \
30+
# Create symbolic links to ensure python3 points to Python 3.13
31+
ln -sf /usr/local/bin/python3.13 /usr/bin/python3 && \
32+
ln -sf /usr/local/bin/python3.13 /usr/bin/python && \
33+
# Ensure latest pip is installed for Python 3.13
34+
/usr/local/bin/python3.13 -m pip install --upgrade pip setuptools wheel
35+
36+
# Switch to vscode user
37+
USER vscode
38+
39+
# Configure Azure CLI for Codespaces (prebuild optimization)
40+
RUN az config set core.login_experience_v2=off 2>/dev/null || true && \
41+
az extension add --name containerapp --only-show-errors 2>/dev/null || true && \
42+
az extension add --name front-door --only-show-errors 2>/dev/null || true
43+
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+
57+
# Set final working directory
58+
WORKDIR /workspaces/Apim-Samples
59+
60+
# Add health check for the virtual environment
61+
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
63+
64+
# Add labels for maintainability
65+
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.13" \
69+
debian.version="bookworm" \
70+
venv.location="/workspaces/Apim-Samples/.venv"
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json",
3+
"name": "APIM Samples",
4+
"build": {
5+
"dockerfile": "Dockerfile",
6+
"context": ".."
7+
},
8+
"features": {
9+
"ghcr.io/devcontainers/features/azure-cli:1": {
10+
"version": "2.72.0"
11+
},
12+
"ghcr.io/devcontainers/features/common-utils:2": {
13+
"installZsh": true,
14+
"configureZshAsDefaultShell": true,
15+
"installOhMyZsh": true,
16+
"upgradePackages": true,
17+
"username": "vscode",
18+
"uid": "1000",
19+
"gid": "1000"
20+
},
21+
"ghcr.io/devcontainers/features/git:1": {
22+
"version": "latest",
23+
"ppa": true
24+
},
25+
"ghcr.io/devcontainers/features/docker-in-docker:2": {
26+
"version": "latest",
27+
"enableNonRootDocker": "true"
28+
}
29+
},
30+
"customizations": {
31+
"vscode": {
32+
"extensions": [
33+
"ms-python.python",
34+
"ms-python.debugpy",
35+
"ms-toolsai.jupyter",
36+
"ms-toolsai.jupyter-keymap",
37+
"ms-toolsai.jupyter-renderers",
38+
"ms-toolsai.vscode-jupyter-cell-tags",
39+
"ms-toolsai.vscode-jupyter-slideshow",
40+
"ms-azuretools.vscode-bicep",
41+
"ms-vscode.azurecli",
42+
"ms-azure-devops.azure-pipelines",
43+
"GitHub.copilot",
44+
"GitHub.copilot-chat",
45+
"redhat.vscode-yaml",
46+
"ms-vscode.vscode-json",
47+
"donjayamanne.vscode-default-python-kernel"
48+
],
49+
"settings": {
50+
"python.defaultInterpreterPath": "/workspaces/Apim-Samples/.venv/bin/python",
51+
"python.pythonPath": "/workspaces/Apim-Samples/.venv/bin/python",
52+
"python.terminal.activateEnvironment": true,
53+
"python.terminal.activateEnvInCurrentTerminal": true,
54+
"python.envFile": "${workspaceFolder}/.env",
55+
"python.linting.enabled": true,
56+
"python.linting.pylintEnabled": true,
57+
"python.formatting.autopep8Path": "/workspaces/Apim-Samples/.venv/bin/autopep8",
58+
"python.formatting.blackPath": "/workspaces/Apim-Samples/.venv/bin/black",
59+
"python.formatting.yapfPath": "/workspaces/Apim-Samples/.venv/bin/yapf",
60+
"python.linting.banditPath": "/workspaces/Apim-Samples/.venv/bin/bandit",
61+
"python.linting.flake8Path": "/workspaces/Apim-Samples/.venv/bin/flake8",
62+
"python.linting.mypyPath": "/workspaces/Apim-Samples/.venv/bin/mypy",
63+
"python.linting.pycodestylePath": "/workspaces/Apim-Samples/.venv/bin/pycodestyle",
64+
"python.linting.pydocstylePath": "/workspaces/Apim-Samples/.venv/bin/pydocestyle",
65+
"python.linting.pylintPath": "/workspaces/Apim-Samples/.venv/bin/pylint",
66+
"python.testing.pytestPath": "/workspaces/Apim-Samples/.venv/bin/pytest",
67+
"jupyter.askForKernelRestart": false,
68+
"jupyter.interactiveWindow.textEditor.executeSelection": true,
69+
"jupyter.notebookFileRoot": "${workspaceFolder}",
70+
"jupyter.kernels.excludePythonEnvironments": [
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"
85+
],
86+
"jupyter.kernels.trusted": [
87+
"/workspaces/Apim-Samples/.venv/bin/python"
88+
],
89+
"files.associations": {
90+
"*.bicep": "bicep"
91+
},
92+
"terminal.integrated.showExitAlert": false,
93+
"terminal.integrated.focusAfterRun": "terminal",
94+
"terminal.integrated.defaultProfile.linux": "bash",
95+
"terminal.integrated.tabs.enabled": true,
96+
"workbench.panel.defaultLocation": "bottom",
97+
"workbench.panel.opensMaximized": "preserve",
98+
"workbench.startupEditor": "none",
99+
"workbench.panel.defaultPanelHeight": 400,
100+
"workbench.view.alwaysShowHeaderActions": true,
101+
"workbench.action.terminal.focus": true,
102+
"workbench.action.togglePanel": true,
103+
"terminal.integrated.defaultLocation": "view",
104+
"security.workspace.trust.enabled": false,
105+
"editor.experimental.pasteActions.enabled": true,
106+
"workbench.editor.enablePreview": false
107+
}
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"
113+
}
114+
},
115+
"onCreateCommand": [
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'"
119+
],
120+
"updateContentCommand": [
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'"
124+
],
125+
"postStartCommand": [
126+
"bash",
127+
"-c",
128+
"echo 'APIM Samples Codespace Starting - Keep this terminal open to see progress!' && bash .devcontainer/post-start-setup.sh"
129+
],
130+
"forwardPorts": [
131+
8000,
132+
8080,
133+
5000,
134+
3000
135+
],
136+
"portsAttributes": {
137+
"8000": {
138+
"label": "Python Development Server",
139+
"onAutoForward": "notify"
140+
},
141+
"8080": {
142+
"label": "Alternative HTTP Server",
143+
"onAutoForward": "notify"
144+
},
145+
"5000": {
146+
"label": "Flask Development Server",
147+
"onAutoForward": "notify"
148+
},
149+
"3000": {
150+
"label": "Node.js Development Server",
151+
"onAutoForward": "notify"
152+
}
153+
},
154+
"remoteUser": "vscode",
155+
"workspaceFolder": "/workspaces/Apim-Samples",
156+
"mounts": [],
157+
"runArgs": [
158+
"--init"
159+
]
160+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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+
25+
echo -e "Environment Status:\n"
26+
27+
# Ultra-fast file system checks (no command execution)
28+
if [ -d "$VENV_PATH" ]; then
29+
echo " ✅ Virtual environment"
30+
else
31+
echo " ❌ Virtual environment missing"
32+
fi
33+
34+
if [ -f "$WORKSPACE_ROOT/.env" ]; then
35+
echo " ✅ Environment file"
36+
else
37+
echo " ❌ Environment file missing"
38+
fi
39+
40+
# Quick command availability checks (fast)
41+
if command -v az >/dev/null 2>&1; then
42+
echo " ✅ Azure CLI"
43+
else
44+
echo " ❌ Azure CLI missing"
45+
fi
46+
47+
if command -v python >/dev/null 2>&1; then
48+
echo " ✅ Python"
49+
else
50+
echo " ❌ Python missing"
51+
fi
52+
53+
# Calculate total duration
54+
end=$(date +%s.%N)
55+
duration=$(python3 -c "print(f'{float('$end') - float('$start'):.1f}')" 2>/dev/null || echo "0.1")
56+
57+
echo ""
58+
echo "============================================================================"
59+
echo " ⚡ INSTANT VERIFICATION COMPLETE! "
60+
echo "============================================================================"
61+
echo ""
62+
printf "⏱️ Verification time: %s seconds\n" "$duration"
63+
echo ""
64+
echo "🎉 Your APIM Samples environment is ready to use!"
65+
echo -e "\n"
66+
echo " Next Steps:"
67+
echo ""
68+
echo " 1. Open a new terminal and log in via the Azure CLI with either command."
69+
echo " See TROUBLESHOOTING.md in the root for details."
70+
echo ""
71+
echo " - az login"
72+
echo " - az login --tenant <your-tenant-id>"
73+
echo ""
74+
echo " 2. Wait until Codespace is fully started (it's fairly quick):"
75+
echo " - Watch progress indicators in status bar"
76+
echo " - Wait for all extensions to install"
77+
echo " --> ✅ (.venv) prefix will appear when you open a new terminal"
78+
echo ""
79+
echo " 3. Start using the infrastructures and samples!"
80+
echo " - You may initially need to select the kernel (top-right above the"
81+
echo " Jupyter notebook). If so, select the '.venv' Python environment."
82+
echo ""
83+
echo "============================================================================"
84+
echo -e "\n\n"

.devcontainer/python314/Dockerfile

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# https://github.com/devcontainers/images/tree/main/src/python
2+
3+
# syntax=docker/dockerfile:1.4
4+
5+
# Use single-stage build with Python 3.14
6+
FROM mcr.microsoft.com/devcontainers/python:1-3.14-bookworm
7+
8+
# Set build arguments
9+
ARG PYTHON_VERSION=3.14
10+
11+
# Set environment variables
12+
ENV PYTHONUNBUFFERED=1 \
13+
PYTHONDONTWRITEBYTECODE=1 \
14+
PIP_NO_CACHE_DIR=1 \
15+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
16+
PYTHONPATH=/workspaces/Apim-Samples/shared/python:/workspaces/Apim-Samples \
17+
DEBIAN_FRONTEND=noninteractive
18+
19+
# Install system dependencies as root
20+
USER root
21+
RUN --mount=type=cache,target=/var/cache/apt \
22+
--mount=type=cache,target=/var/lib/apt/lists \
23+
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 && \
29+
apt-get clean && \
30+
# Create symbolic links to ensure python3 points to Python 3.14
31+
ln -sf /usr/local/bin/python3.14 /usr/bin/python3 && \
32+
ln -sf /usr/local/bin/python3.14 /usr/bin/python && \
33+
# Ensure latest pip is installed for Python 3.14
34+
/usr/local/bin/python3.14 -m pip install --upgrade pip setuptools wheel
35+
36+
# Switch to vscode user
37+
USER vscode
38+
39+
# Configure Azure CLI for Codespaces (prebuild optimization)
40+
RUN az config set core.login_experience_v2=off 2>/dev/null || true && \
41+
az extension add --name containerapp --only-show-errors 2>/dev/null || true && \
42+
az extension add --name front-door --only-show-errors 2>/dev/null || true
43+
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+
57+
# Set final working directory
58+
WORKDIR /workspaces/Apim-Samples
59+
60+
# Add health check for the virtual environment
61+
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
63+
64+
# Add labels for maintainability
65+
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.14" \
69+
debian.version="bookworm" \
70+
venv.location="/workspaces/Apim-Samples/.venv"

0 commit comments

Comments
 (0)