-
Notifications
You must be signed in to change notification settings - Fork 0
feat(devcontainers): add initial dev containers configs #61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Development Container Setup | ||
|
|
||
| This project includes Dev Container support for VS Code and other compatible editors. | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### Option 1: Using VS Code Dev Containers Extension (Recommended) | ||
| 1. Install the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) | ||
| 2. Open this project in VS Code | ||
| 3. Click "Reopen in Container" when prompted, or use Command Palette: `Dev Containers: Reopen in Container` | ||
|
|
||
| ### Option 2: Attach to Running Container | ||
| 1. Start the dev container: | ||
| ```bash | ||
| task dev-container | ||
| ``` | ||
| 2. In VS Code, use Command Palette: `Dev Containers: Attach to Running Container` | ||
| 3. Select the `{{ cookiecutter.project_slug }}-dev` container | ||
|
|
||
| ### Option 3: Command Line Access | ||
| ```bash | ||
| # Build and start the dev container | ||
| task dev-container | ||
|
|
||
| # Check if container is running | ||
| task dev-container-status | ||
|
|
||
| # Access the container shell | ||
| task dev-container-shell | ||
|
|
||
| # Run a specific command | ||
| task dev-container-exec CMD="python --version" | ||
|
|
||
| # Stop the container when done | ||
| task dev-container-stop | ||
| ``` | ||
|
|
||
| ## Features | ||
|
|
||
| The dev container includes: | ||
| - Python {{ cookiecutter.python_version }}+ with uv package manager | ||
| - All project dependencies (including dev dependencies) | ||
| - Git, GitHub CLI, Task, and pre-commit tools | ||
| - VS Code extensions for Python development | ||
| - Proper volume mounts for live code editing | ||
|
|
||
| ## Environment | ||
|
|
||
| - `DEV_MODE=true` - Installs all development dependencies | ||
| - Python path set to `/workspace/src` - Ensures proper module imports | ||
| - Working directory: `/workspace` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| If you encounter issues: | ||
| 1. Ensure Docker is running | ||
| 2. Check that you have the latest Dev Containers extension | ||
| 3. Try rebuilding the container: `Dev Containers: Rebuild Container` | ||
| 4. For manual setup, ensure you run `task init` after container starts |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| { | ||
| "name": "{{ cookiecutter.project_name }}", | ||
| "dockerComposeFile": "docker-compose.yml", | ||
| "service": "dev", | ||
| "workspaceFolder": "/workspace", | ||
| "features": { | ||
| "ghcr.io/devcontainers/features/git:1": {}, | ||
| "ghcr.io/devcontainers/features/github-cli:1": {}, | ||
| "ghcr.io/devcontainers-contrib/features/task:1": {}, | ||
| "ghcr.io/devcontainers-contrib/features/pre-commit:2": {} | ||
| }, | ||
| "customizations": { | ||
| "vscode": { | ||
| "settings": { | ||
| "python.defaultInterpreterPath": "/app/.venv/bin/python", | ||
| "python.formatting.provider": "none", | ||
| "[python]": { | ||
| "editor.defaultFormatter": "charliermarsh.ruff", | ||
| "editor.formatOnSave": true, | ||
| "editor.codeActionsOnSave": { | ||
| "source.fixAll.ruff": "explicit", | ||
| "source.organizeImports.ruff": "explicit" | ||
| } | ||
| }, | ||
| "python.testing.pytestArgs": [ | ||
| "tests" | ||
| ], | ||
| "python.testing.unittestEnabled": false, | ||
| "python.testing.pytestEnabled": true, | ||
| "python.linting.enabled": false, | ||
| "python.analysis.typeCheckingMode": "basic", | ||
| "editor.rulers": [120] | ||
| }, | ||
| "extensions": [ | ||
| "ms-python.python", | ||
| "ms-python.vscode-pylance", | ||
| "charliermarsh.ruff", | ||
| "tamasfe.even-better-toml", | ||
| "redhat.vscode-yaml", | ||
| "ms-azuretools.vscode-docker", | ||
| "GitHub.vscode-pull-request-github", | ||
| "GitHub.copilot" | ||
| ] | ||
| } | ||
| }, | ||
| "postCreateCommand": "cd /workspace && task init", | ||
| "postStartCommand": "git config --global --add safe.directory /workspace", | ||
| "containerEnv": { | ||
| "DEV_MODE": "true", | ||
| "PYTHONPATH": "/workspace/src" | ||
| }, | ||
| "remoteUser": "root" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| version: '3.8' | ||
|
|
||
| services: | ||
| dev: | ||
| build: | ||
| context: .. | ||
| dockerfile: Dockerfile | ||
| target: builder | ||
| args: | ||
| PYTHON_VERSION: {{ cookiecutter.python_version }} | ||
| DEV_MODE: "true" | ||
| volumes: | ||
| # Mount the entire project directory | ||
| - ..:/workspace:cached | ||
| # Cache directories for faster rebuilds | ||
| - uv-cache:/root/.cache/uv | ||
| environment: | ||
| - DEV_MODE=true | ||
| - PYTHONPATH=/workspace/src | ||
| - UV_COMPILE_BYTECODE=1 | ||
| - UV_LINK_MODE=copy | ||
| working_dir: /workspace | ||
| # Overwrite the default command to keep container running | ||
| command: sleep infinity | ||
| # Network mode for easier debugging and service access | ||
| network_mode: host | ||
| # Add capabilities needed for debugging | ||
| cap_add: | ||
| - SYS_PTRACE | ||
| security_opt: | ||
| - seccomp:unconfined | ||
|
Comment on lines
+26
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical Security Risk: The combination of
For development containers, consider using port mapping instead of host networking and removing these privileged settings unless absolutely necessary for specific debugging scenarios. |
||
|
|
||
| volumes: | ||
| uv-cache: | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -184,6 +184,86 @@ tasks: | |
| # rebuild the builder instance, updating its BuildKit. There's no harm in running this even if we didn't do the `docker buildx rm` previously | ||
| - task: init-docker-multiplatform | ||
|
|
||
| dev-container: | ||
| desc: Build and start development container | ||
| vars: | ||
| TIMESTAMP: | ||
| sh: '{{ '{{.RUN_SCRIPT}}' }} {{ '{{.SCRIPTS_DIR}}' }}/get_rfc3339_timestamp.py' | ||
| COMMIT_HASH: | ||
| sh: git rev-parse HEAD | ||
| DESCRIPTION: "{{ cookiecutter.project_short_description | replace('"', '\\"') | replace("'", "\\\\'") }}" | ||
| cmds: | ||
| # Stop any existing container | ||
| - docker stop {{ '{{.PROJECT_SLUG}}' }}-dev 2>/dev/null || true | ||
| - docker rm {{ '{{.PROJECT_SLUG}}' }}-dev 2>/dev/null || true | ||
| # Build the dev image | ||
| - | | ||
| docker buildx build \ | ||
| --platform {{ '{{.LOCAL_PLATFORM}}' }} \ | ||
| --load \ | ||
| --target builder \ | ||
| --build-arg PYTHON_VERSION="{{ '{{.PYTHON_VERSION}}' }}" \ | ||
| --build-arg DEV_MODE="true" \ | ||
| --build-arg NAME="{{ '{{.PROJECT_SLUG}}' }}" \ | ||
| --build-arg DESCRIPTION="{{ '{{.DESCRIPTION}}' }}" \ | ||
| --build-arg TIMESTAMP="{{ '{{.TIMESTAMP}}' }}" \ | ||
| --build-arg COMMIT_HASH="{{ '{{.COMMIT_HASH}}' }}" \ | ||
| -t {{ '{{.IMAGE_NAME}}' }}-dev:latest \ | ||
| . | ||
| # Start the container in detached mode | ||
| - | | ||
| docker run -d \ | ||
| --name {{ '{{.PROJECT_SLUG}}' }}-dev \ | ||
| -v "$(pwd):/workspace:cached" \ | ||
| -v "{{ '{{.PROJECT_SLUG}}' }}-uv-cache:/root/.cache/uv" \ | ||
| -e DEV_MODE=true \ | ||
| -e PYTHONPATH=/workspace/src \ | ||
| --network host \ | ||
| --cap-add SYS_PTRACE \ | ||
| --security-opt seccomp=unconfined \ | ||
|
Comment on lines
+222
to
+223
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The combination of |
||
| {{ '{{.IMAGE_NAME}}' }}-dev:latest \ | ||
| sleep infinity | ||
| - | | ||
| echo "✅ Development container '{{ '{{.PROJECT_SLUG}}' }}-dev' is running!" | ||
| echo "" | ||
| echo "To use it:" | ||
| echo " • VS Code: Use 'Dev Containers: Attach to Running Container' command" | ||
| echo " • Terminal: task dev-container-shell" | ||
| echo " • Check status: task dev-container-status" | ||
| echo " • Stop: task dev-container-stop" | ||
|
|
||
| dev-container-stop: | ||
| desc: Stop and remove development container | ||
| cmds: | ||
| - docker stop {{ '{{.PROJECT_SLUG}}' }}-dev 2>/dev/null || true | ||
| - docker rm {{ '{{.PROJECT_SLUG}}' }}-dev 2>/dev/null || true | ||
| - echo "Development container stopped and removed." | ||
|
|
||
| dev-container-exec: | ||
| desc: Execute a command in the development container (default: bash) | ||
| vars: | ||
| CMD: '{{ '{{.CMD | default "bash"}}' }}' | ||
| cmds: | ||
| - docker exec -it {{ '{{.PROJECT_SLUG}}' }}-dev {{ '{{.CMD}}' }} | ||
|
|
||
| dev-container-shell: | ||
| desc: Open a shell in the development container | ||
| cmds: | ||
| - task: dev-container-exec | ||
| vars: | ||
| CMD: bash | ||
|
|
||
| dev-container-status: | ||
| desc: Check status of the development container | ||
| cmds: | ||
| - | | ||
| if docker ps --format "table {{ '{{.Names}}' }}" | grep -q "^{{ '{{.PROJECT_SLUG}}' }}-dev$"; then | ||
| echo "✅ Development container '{{ '{{.PROJECT_SLUG}}' }}-dev' is running" | ||
| else | ||
| echo "❌ Development container '{{ '{{.PROJECT_SLUG}}' }}-dev' is not running" | ||
| echo "Run 'task dev-container' to start it" | ||
| fi | ||
|
|
||
| clean: | ||
| desc: Clean up build artifacts, cache files/directories, temp files, etc. | ||
| cmds: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running as root user in development containers poses security risks. Consider creating and using a non-privileged user instead.