Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .devcontainer/vscode-init/extensions-to-install.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# These extensions will be enabled for all users of the devcontainer.
# One extension ID per line.
charliermarsh.ruff
Continue.continue
#Continue.continue
DavidAnson.vscode-markdownlint
eamodio.gitlens
# The marimo extension has been removed from the marketplace whilst it is being rewritten.
Expand All @@ -12,7 +12,7 @@ ms-ossdata.vscode-pgsql --pre-release
ms-python.black-formatter
ms-toolsai.datawrangler
ms-toolsai.jupyter
openai.chatgpt
#openai.chatgpt
REditorSupport.r
REditorSupport.r-syntax
yzhang.markdown-all-in-one
78 changes: 46 additions & 32 deletions .github/workflows/build-devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,42 +126,56 @@ jobs:

echo "=== Dev container validation completed! ==="

# Free up disk space before security scan to prevent "no space left on device" errors
- name: Free Disk Space
run: |
echo "=== Disk space before cleanup ==="
df -h
echo "=== Removing unnecessary files ==="
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache/CodeQL
sudo apt-get clean
echo "=== Disk space after cleanup ==="
df -h

# Using the custom Trivy Security Scan action from this repository
# - name: Security Scan
# id: security-scan
# uses: smartdatafoundry/trivy-security-scan@v1.0.0
# with:
# image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# registry: ${{ env.REGISTRY }}
# severity: 'CRITICAL,HIGH'
# detailed-severity: 'CRITICAL,HIGH,MEDIUM,LOW'
# ignore-unfixed: 'true'
# exit-code: '0'
# artifact-name: 'security-scan-results'
# artifact-retention-days: '30'
# github-token: ${{ secrets.GITHUB_TOKEN }}
# post-pr-comment: 'true'
- name: Security Scan
id: security-scan
uses: smartdatafoundry/trivy-security-scan@v1.0.0
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
registry: ${{ env.REGISTRY }}
severity: 'CRITICAL,HIGH'
detailed-severity: 'CRITICAL,HIGH,MEDIUM,LOW'
ignore-unfixed: 'true'
exit-code: '0'
artifact-name: 'security-scan-results'
artifact-retention-days: '30'
github-token: ${{ secrets.GITHUB_TOKEN }}
post-pr-comment: 'true'

# # Optional: Handle scan results programmatically
# - name: Process scan results
# run: |
# echo "Security scan status: ${{ steps.security-scan.outputs.scan-status }}"
# echo "Vulnerabilities found: ${{ steps.security-scan.outputs.vulnerability-count }}"
# echo "Artifact ID: ${{ steps.security-scan.outputs.artifact-id }}"
# Optional: Handle scan results programmatically
- name: Process scan results
run: |
echo "Security scan status: ${{ steps.security-scan.outputs.scan-status }}"
echo "Vulnerabilities found: ${{ steps.security-scan.outputs.vulnerability-count }}"
echo "Artifact ID: ${{ steps.security-scan.outputs.artifact-id }}"

# # You can add custom logic here based on the scan results
# if [ "${{ steps.security-scan.outputs.scan-status }}" = "vulnerabilities_found" ]; then
# echo "⚠️ Security vulnerabilities detected!"
# echo "Consider reviewing the security report before deploying."
# You can add custom logic here based on the scan results
if [ "${{ steps.security-scan.outputs.scan-status }}" = "vulnerabilities_found" ]; then
echo "⚠️ Security vulnerabilities detected!"
echo "Consider reviewing the security report before deploying."

# # Optionally, you could fail the build for critical vulnerabilities:
# # if [ "${{ steps.security-scan.outputs.vulnerability-count }}" -gt "10" ]; then
# # echo "❌ Too many vulnerabilities found (> 10), failing build"
# # exit 1
# # fi
# else
# echo "✅ No critical or high severity vulnerabilities found!"
# fi
# Optionally, you could fail the build for critical vulnerabilities:
# if [ "${{ steps.security-scan.outputs.vulnerability-count }}" -gt "10" ]; then
# echo "❌ Too many vulnerabilities found (> 10), failing build"
# exit 1
# fi
else
echo "✅ No critical or high severity vulnerabilities found!"
fi

- name: Container info
if: success()
Expand Down
72 changes: 66 additions & 6 deletions DEVCONTAINER.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Dev Container for Python & R Development

This repository contains a development container configuration optimized for Python (and first-class R) development, along with automated workflows to build and publish the container image to GitHub Container Registry (GHCR). For high-level usage see `README.md`; this document focuses on implementation details.
This repository contains a development container configuration optimised for Python (and first-class R) development, along with automated workflows to build and publish the container image to GitHub Container Registry (GHCR). For high-level usage see [`README.md`](README.md); this document focuses on implementation details.

## 📦 Published Container

Expand Down Expand Up @@ -74,13 +74,69 @@ This dev container includes:
* **Quarto**: Latest (document publishing)
* **Marimo**: Alternative interactive notebook/presentation tool
* **VS Code Server**: Pre-installed (pin via tag families)
* **VS Code Extensions**: Curated list (see `.devcontainer/vscode-init/extensions-to-install.txt`)
* **VS Code Extensions**: Curated list (see [`.devcontainer/vscode-init/extensions-to-install.txt`](.devcontainer/vscode-init/extensions-to-install.txt))
* **User Setup Scripts**: Automated deployment and management tools

### User Setup Scripts

The container includes scripts in [`/workspace/scripts/`](scripts/) to simplify deployment and management:

#### [`scripts/devcontainerctl`](scripts/devcontainerctl)
A comprehensive container lifecycle management script that provides:

**Features:**
- Automatic image updates with VS Code tag alignment
- Container lifecycle management (start, stop, restart, remove)
- Status monitoring
- Automatic home directory and `/safedata` mounting
- Proxy configuration inheritance
- Background update notifications

**Commands:**
- `start` - Pull latest image matching your VS Code version and start container
- `stop` - Stop the running container
- `restart` - Restart the container
- `status` - Show current container status
- `sync` - Update to latest matching image (used by cron)
- `update` - Stop, update, and restart with new image
- `remove` - Stop and remove the container

**Usage:**
```bash
devcontainerctl start # Start with auto-detected VS Code version
devcontainerctl start vscode-abc123 # Start with specific tag
devcontainerctl status # Check status
devcontainerctl sync # Update image (used by daily cron)
```

#### [`scripts/setup.sh`](scripts/setup.sh)
One-time setup script that configures your environment:

**What it does:**
- Creates `~/bin` directory if needed
- Creates symlink to `devcontainerctl` in `~/bin`
- Adds `~/bin` to PATH in `~/.bashrc`
- Configures daily cron job (8:00 AM) to sync images

**Usage:**
```bash
# Extract scripts from container first
podman run --rm -v $HOME:$HOME -w $HOME \
ghcr.io/smartdatafoundry/devcontainer:latest \
cp -r /workspace/scripts $HOME/devcontainer-scripts

# Run setup
cd $HOME/devcontainer-scripts
./setup.sh
```

After setup, the `devcontainerctl` command will be available system-wide, and your devcontainer image will automatically stay up-to-date.

## 🔄 Automated Builds

The container is built using GitHub Actions with controlled publishing:

### Build Workflow (`build-devcontainer.yml`)
### Build Workflow ([`build-devcontainer.yml`](.github/workflows/build-devcontainer.yml))
- **PR Triggers**: Pull requests automatically build test images (`pr-<number>` tags) using default VS Code Server commit
- **Manual Dispatch**: Production builds require manual trigger with VS Code Server commit hash
- **Required Input**: VS Code Server commit hash for reproducible builds
Expand All @@ -105,7 +161,7 @@ export VSCODE_COMMIT=0f0d87fa9e96c856c5212fc86db137ac0d783365
devcontainer build --workspace-folder .
```

This keeps maintenance simple: update the default by editing a single line in `Dockerfile` with support for overrides when needed via workflow inputs.
This keeps maintenance simple: update the default by editing a single line in [`Dockerfile`](.devcontainer/Dockerfile) with support for overrides when needed via workflow inputs.

## 📁 Repository Structure

Expand All @@ -122,6 +178,9 @@ This keeps maintenance simple: update the default by editing a single line in `D
├── .github/workflows/
│ ├── build-devcontainer.yml # Build and publish workflow
│ └── build-publish-container.yml
├── scripts/ # User deployment scripts
│ ├── devcontainerctl # Container management script
│ └── setup.sh # One-time setup script
├── assets/ # Documentation assets
├── docs/ # Additional documentation
├── DEVCONTAINER.md # Detailed documentation
Expand All @@ -134,14 +193,15 @@ This keeps maintenance simple: update the default by editing a single line in `D
To customize this dev container for your needs:

1. Fork this repository
2. Modify `.devcontainer/devcontainer.json`:
2. Modify [`.devcontainer/devcontainer.json`](.devcontainer/devcontainer.json):
- Add/remove features
- Update VS Code extensions
- Change base image or configuration
3. Update the workflows to use your repository name
4. Push changes - the container will be built automatically

## 🏗️ Local Development

## 🔄 Automated Build Process

The container images are built and published automatically using GitHub Actions with intelligent tagging:
Expand Down Expand Up @@ -185,7 +245,7 @@ devcontainer exec --workspace-folder . bash

1. Fork the repository
2. Create a feature branch
3. Make your changes to `.devcontainer/devcontainer.json`
3. Make your changes to [`.devcontainer/devcontainer.json`](.devcontainer/devcontainer.json)
4. Test locally using the devcontainer CLI
5. Submit a pull request

Expand Down
65 changes: 50 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,44 @@ Add this to your `.devcontainer/devcontainer.json`:

### Using in SDF Trusted Research Environment

See the **[SDF TRE Setup Guide](SDF_TRE_SETUP.md)** for:
* Manual Dev Containers extension install & extraction
* Podman configuration
* Proxy / network specifics
* Troubleshooting in constrained environments
#### Quick Setup with Included Scripts (Recommended)

The devcontainer includes setup scripts for easy deployment in the SDF TRE:

```bash
# 1. Pull the container image
ces-pull a a ghcr.io/smartdatafoundry/devcontainer:latest

# 2. Extract the setup scripts
podman run --rm -v $HOME:$HOME -w $HOME \
ghcr.io/smartdatafoundry/devcontainer:latest \
cp -r /workspace/scripts $HOME/devcontainer-scripts

# 3. Run the setup script (one-time setup)
cd $HOME/devcontainer-scripts
./setup.sh

# 4. Start your devcontainer
devcontainerctl start
```

The setup script will:
- Create a symlink to `devcontainerctl` in `~/bin`
- Add `~/bin` to your PATH
- Configure a daily cron job to keep the image updated

Available `devcontainerctl` commands:
- `devcontainerctl start` - Pull latest image and start container
- `devcontainerctl stop` - Stop the container
- `devcontainerctl restart` - Restart the container
- `devcontainerctl status` - Check container status
- `devcontainerctl sync` - Update the container image
- `devcontainerctl update` - Update and restart with new image
- `devcontainerctl remove` - Stop and remove the container

#### Manual Setup

For detailed manual setup instructions, see the **[SDF TRE Setup Guide](SDF_TRE_SETUP.md)**.

### Using This Repository Directly

Expand All @@ -71,9 +104,10 @@ See the **[SDF TRE Setup Guide](SDF_TRE_SETUP.md)** for:

| Topic | Reference |
|-------|-----------|
| SDF TRE usage | `SDF_TRE_SETUP.md` |
| Full container internals | `DEVCONTAINER.md` |
| Reusable publish workflow | `docs/BUILD_PUBLISH_CONTAINER.md` |
| SDF TRE usage | [`SDF_TRE_SETUP.md`](SDF_TRE_SETUP.md) |
| Full container internals | [`DEVCONTAINER.md`](DEVCONTAINER.md) |
| Setup scripts | [`scripts/`](scripts/) directory |
| Reusable publish workflow | [`docs/BUILD_PUBLISH_CONTAINER.md`](docs/BUILD_PUBLISH_CONTAINER.md) |
| Dev Container Specification | https://containers.dev |

## 🛠️ What's Included
Expand All @@ -85,14 +119,15 @@ See the **[SDF TRE Setup Guide](SDF_TRE_SETUP.md)** for:
- **Shell**: Zsh with Oh My Zsh (via common-utils feature)
- **Quarto**: Document publishing platform (latest version)
- **Marimo**: Markdown presentation tool, alternative to Jupyter Notebooks
- **User Setup Scripts**: Automated deployment and management tools ([`scripts/`](scripts/))
- **VS Code Extensions (curated)**:
- Continue (AI assistant)
- Black (Python formatting)
- Jupyter
- Marimo
- Markdown All in One
- Rainbow CSV
- (See `.devcontainer/vscode-init/extensions-to-install.txt` for authoritative list)
- (See [`.devcontainer/vscode-init/extensions-to-install.txt`](.devcontainer/vscode-init/extensions-to-install.txt) for authoritative list)
- **VS Code Server**: Pre-installed for immediate development

## 📊 R Language Support
Expand All @@ -112,20 +147,20 @@ This dev container includes comprehensive R language support through the [Rocker

## ⚙️ VS Code Server

Pre-installed. Pin a version using the tag families described above or via build arg `VSCODE_COMMIT`. For environment-specific considerations (e.g. TRE) see `SDF_TRE_SETUP.md`.
Pre-installed. Pin a version using the tag families described above or via build arg `VSCODE_COMMIT`. For environment-specific considerations (e.g. TRE) see [`SDF_TRE_SETUP.md`](SDF_TRE_SETUP.md).

## Adding New Extensions
To add new VS Code extensions to the container, follow these steps:
1. Open the appropriate file in `.devcontainer/vscode-init/`:
- `extensions-to-install.txt` for extensions to install directly
- `extensions-to-download.txt` for extensions that need to be downloaded
1. Open the appropriate file in [`.devcontainer/vscode-init/`](.devcontainer/vscode-init/):
- [`extensions-to-install.txt`](.devcontainer/vscode-init/extensions-to-install.txt) for extensions to install directly
- [`extensions-to-download.txt`](.devcontainer/vscode-init/extensions-to-download.txt) for extensions that you want to be downloaded
2. Add the identifier of the desired extension in the format `publisher.extensionName` on a new line.
3. Save the changes to the extension file.
4. Commit and push the changes to your repository to trigger the build workflow with the updated extensions

## 🔄 Automated Builds & Tag Strategy

Workflow: `.github/workflows/build-devcontainer.yml`
Workflow: [`.github/workflows/build-devcontainer.yml`](.github/workflows/build-devcontainer.yml)

Triggers:
* Pull Requests touching devcontainer/workflow files → build + `pr-<number>` tag
Expand All @@ -149,7 +184,7 @@ Tag usage quick reference:
| Pin VS Code Server only | `vscode-<vscode-sha>` |
| Full reproducibility | `vscode-<vscode-sha>-<sha>` |

Reusable generic Docker workflow documentation: see `docs/BUILD_PUBLISH_CONTAINER.md`.
Reusable generic Docker workflow documentation: see [`docs/BUILD_PUBLISH_CONTAINER.md`](docs/BUILD_PUBLISH_CONTAINER.md).

---
## 🤝 Contributing & License
Expand Down
Loading