diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index d5e108d..f5cff74 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -15,52 +15,22 @@ jobs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Detect changed Dockerfiles id: changes - uses: dorny/paths-filter@v3 + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 with: filters: | - ttyd: - - 'ttyd/**' - streamlit: - - 'streamlit/**' - cellxgene: - - 'cellxgene/**' - shiny: - - 'shiny-simple-example/**' - marimo: - - 'marimo/**' - napari: - - 'kasmVNC/napari/**' - qupath: - - 'kasmVNC/qupath/**' + kasmvnc_qupath: + - '.seqera/**' - name: Set matrix id: set-matrix run: | CONTAINERS="[]" - if [[ "${{ steps.changes.outputs.ttyd }}" == "true" ]]; then - CONTAINERS=$(echo "$CONTAINERS" | jq -c '. + [{"name":"ttyd","path":"./ttyd"}]') - fi - if [[ "${{ steps.changes.outputs.streamlit }}" == "true" ]]; then - CONTAINERS=$(echo "$CONTAINERS" | jq -c '. + [{"name":"streamlit","path":"./streamlit"}]') - fi - if [[ "${{ steps.changes.outputs.cellxgene }}" == "true" ]]; then - CONTAINERS=$(echo "$CONTAINERS" | jq -c '. + [{"name":"cellxgene","path":"./cellxgene"}]') - fi - if [[ "${{ steps.changes.outputs.shiny }}" == "true" ]]; then - CONTAINERS=$(echo "$CONTAINERS" | jq -c '. + [{"name":"shiny","path":"./shiny-simple-example"}]') - fi - if [[ "${{ steps.changes.outputs.marimo }}" == "true" ]]; then - CONTAINERS=$(echo "$CONTAINERS" | jq -c '. + [{"name":"marimo","path":"./marimo"}]') - fi - if [[ "${{ steps.changes.outputs.napari }}" == "true" ]]; then - CONTAINERS=$(echo "$CONTAINERS" | jq -c '. + [{"name":"napari","path":"./kasmVNC/napari"}]') - fi - if [[ "${{ steps.changes.outputs.qupath }}" == "true" ]]; then - CONTAINERS=$(echo "$CONTAINERS" | jq -c '. + [{"name":"qupath","path":"./kasmVNC/qupath"}]') + if [[ "${{ steps.changes.outputs.kasmvnc_qupath }}" == "true" ]]; then + CONTAINERS=$(echo "$CONTAINERS" | jq -c '. + [{"name":"kasmvnc-qupath","path":"./.seqera"}]') fi echo "matrix={\"container\":$CONTAINERS}" >> "$GITHUB_OUTPUT" @@ -79,36 +49,36 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Log in to the Container registry - uses: docker/login-action@v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GHCR_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 - name: Extract metadata id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 with: images: ${{ env.REGISTRY }}/${{ github.repository }}/development tags: | type=ref,event=pr,prefix=${{ matrix.container.name }}-pr - name: Build and push ${{ matrix.container.name }} - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 with: context: ${{ matrix.container.path }} push: true platforms: linux/amd64 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha,scope=${{ matrix.container.name }} - cache-to: type=gha,mode=max,scope=${{ matrix.container.name }} + cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ github.repository }}/development:${{ matrix.container.name }}-buildcache + cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ github.repository }}/development:${{ matrix.container.name }}-buildcache,mode=max - name: Get image reference for scan id: scanref @@ -116,7 +86,7 @@ jobs: echo "ref=${{ fromJSON(steps.meta.outputs.json).tags[0] }}" >> $GITHUB_OUTPUT - name: Run security scan - uses: aquasecurity/trivy-action@0.31.0 + uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37 with: image-ref: ${{ steps.scanref.outputs.ref }} format: "table" @@ -137,7 +107,7 @@ jobs: fi - name: Upload security scan results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 if: always() with: name: trivy-scan-${{ matrix.container.name }}-${{ github.run_id }} @@ -155,7 +125,7 @@ jobs: echo "- **Commit**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY - name: Comment on PR - uses: actions/github-script@v7 + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea with: script: | const fs = require('fs'); diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index ebce099..976fad5 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -8,13 +8,7 @@ on: required: true type: choice options: - - ttyd - - streamlit - - cellxgene - - shiny - - marimo - - napari - - qupath + - kasmvnc-qupath version: description: 'Version to release (e.g., 1.0.0)' required: true @@ -38,34 +32,28 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set container path id: container run: | case "${{ inputs.container }}" in - ttyd) echo "path=./ttyd" >> "$GITHUB_OUTPUT" ;; - streamlit) echo "path=./streamlit" >> "$GITHUB_OUTPUT" ;; - cellxgene) echo "path=./cellxgene" >> "$GITHUB_OUTPUT" ;; - shiny) echo "path=./shiny-simple-example" >> "$GITHUB_OUTPUT" ;; - marimo) echo "path=./marimo" >> "$GITHUB_OUTPUT" ;; - napari) echo "path=./kasmVNC/napari" >> "$GITHUB_OUTPUT" ;; - qupath) echo "path=./kasmVNC/qupath" >> "$GITHUB_OUTPUT" ;; + kasmvnc-qupath) echo "path=./.seqera" >> "$GITHUB_OUTPUT" ;; esac - name: Log in to the Container registry - uses: docker/login-action@v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GHCR_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 - name: Extract metadata id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 with: images: ${{ env.REGISTRY }}/${{ github.repository }}/${{ inputs.container }} tags: | @@ -76,7 +64,7 @@ jobs: org.opencontainers.image.licenses=MIT - name: Build and push ${{ inputs.container }} - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 with: context: ${{ steps.container.outputs.path }} push: true @@ -85,11 +73,11 @@ jobs: CONNECT_CLIENT_VERSION=${{ inputs.connect_client_version || '0.9' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha,scope=${{ inputs.container }} - cache-to: type=gha,mode=max,scope=${{ inputs.container }} + cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ github.repository }}/${{ inputs.container }}:buildcache + cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ github.repository }}/${{ inputs.container }}:buildcache,mode=max - name: Create GitHub Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 with: tag_name: ${{ inputs.container }}/${{ inputs.version }} name: ${{ inputs.container }} ${{ inputs.version }} diff --git a/kasmVNC/qupath/Dockerfile b/.seqera/Dockerfile similarity index 75% rename from kasmVNC/qupath/Dockerfile rename to .seqera/Dockerfile index c769d68..d078661 100644 --- a/kasmVNC/qupath/Dockerfile +++ b/.seqera/Dockerfile @@ -14,14 +14,16 @@ LABEL org.opencontainers.image.source="https://github.com/seqeralabs/custom-stud ENV TITLE="QuPath" -# KasmVNC Performance Optimizations +# KasmVNC performance tuning for interactive desktop streaming ENV KASM_VNC_ENABLE_WEBP=1 ENV KASM_VNC_JPEG_QUALITY=5 ENV KASM_VNC_MAX_FRAME_RATE=30 ENV KASM_VNC_THREADS=4 -# Install dependencies for QuPath -RUN apt-get update && apt-get install -y --no-install-recommends \ +# Install dependencies for QuPath. The base image can carry stale third-party apt +# sources, so drop NodeSource before refreshing Ubuntu package indexes. +RUN rm -f /etc/apt/sources.list.d/nodesource*.list \ + && apt-get update && apt-get install -y --no-install-recommends \ wget \ xz-utils \ libgl1 \ @@ -39,6 +41,10 @@ RUN wget -q https://github.com/qupath/qupath/releases/download/v${QUPATH_VERSION && chmod +x /opt/qupath/bin/QuPath \ && rm /tmp/qupath.tar.xz + +# Create the X socket directory before KasmVNC drops privileges to the abc user. +RUN sed -i '/^exec s6-setuidgid/i mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix' /etc/s6-overlay/s6-rc.d/svc-kasmvnc/run + # Single-app mode: application launches directly, no desktop RUN echo "/opt/qupath/bin/QuPath" > /defaults/autostart @@ -56,8 +62,8 @@ COPY --from=connect /usr/bin/connect-client /usr/bin/connect-client # Install connect-client RUN /usr/bin/connect-client --install -# Seqera Studios entrypoint (connect-client handles fusion filesystem) +# Seqera Studios entrypoint (connect-client handles Fusion filesystem) ENTRYPOINT ["/usr/bin/connect-client", "--entrypoint"] -# CMD bridges CONNECT_TOOL_PORT to KasmVNC's CUSTOM_PORT and launches the init +# Bridge CONNECT_TOOL_PORT to KasmVNC's CUSTOM_PORT and launch the init system CMD ["/bin/bash", "-c", "export CUSTOM_PORT=${CONNECT_TOOL_PORT:-6901} && exec /init"] diff --git a/.seqera/studio-config.yaml b/.seqera/studio-config.yaml new file mode 100644 index 0000000..f106d81 --- /dev/null +++ b/.seqera/studio-config.yaml @@ -0,0 +1,6 @@ +schemaVersion: "0.0.1" +kind: "studio-config" +session: + template: + kind: "dockerfile" + dockerfile: "Dockerfile" diff --git a/README.md b/README.md index f6297df..0afa102 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,70 @@ -# Custom Studios Examples +# QuPath KasmVNC Studio Environment -This repository contains example Dockerfiles and configurations for custom Seqera Studio applications. Each example demonstrates how to create and deploy different types of interactive applications in Seqera Studios. +This branch contains the Seqera Studios configuration for running [QuPath](https://qupath.github.io/) with [KasmVNC](https://kasmweb.com/kasmvnc), making the QuPath desktop available through a browser in Seqera Platform. -## Available Examples +> This is a branch of the [custom-studios-examples](https://github.com/seqeralabs/custom-studios-examples) repository. Each branch contains a different custom Studio configuration. See the `master` branch for an overview of all available Studios. -- [Marimo](marimo/README.md) - A reactive Python notebook environment -- [CellxGene](cellxgene/README.md) - Interactive single-cell data visualization -- [Streamlit](streamlit/README.md) - MultiQC visualization using Streamlit -- [Shiny](shiny-simple-example/README.md) - Interactive data visualization with R Shiny -- [TTYD](ttyd/README.md) - Interactive web-based terminal with bioinformatics tools +## Quick Start -## Prerequisites +### Add from Git Repository -All examples in this repository require: -- [Docker](https://www.docker.com/) installed -- [Wave](https://docs.seqera.io/platform-cloud/wave/) configured in your Seqera Platform workspace -- Access to a container registry (public or Amazon ECR) for pushing your images +1. Navigate to **Studios** > **Add Studio** in your Seqera Platform workspace +2. Select **Git repository** as the source +3. Enter the repository URL: `https://github.com/seqeralabs/custom-studios-examples` +4. Select branch: `kasmvnc-qupath` +5. Select your compute environment +6. Click **Add** then **Start** -## Common Features +### Alternative: Use Pre-built Image -All examples in this repository: -- Are compatible with both local Docker testing and Seqera Studios -- Use the required Seqera base image and connect-client -- Include detailed setup and usage instructions -- Support data mounting via datalinks in Studios -- Are built for linux/amd64 platform compatibility -- Use multi-stage builds to include the connect-client -- Follow consistent container best practices +``` +ghcr.io/seqeralabs/custom-studios-examples/kasmvnc-qupath:latest +``` -## Deploying to Seqera Studios +### Alternative: Build with Wave CLI -All examples follow the same deployment process: +```bash +wave -f .seqera/Dockerfile --context .seqera --platform linux/amd64 --await --tower-token "$TOWER_ACCESS_TOKEN" +``` -1. Select the **Studios** tab in your workspace -2. Click **Add Studio** -3. In the **General config** section: - - Select **Prebuilt container image** as the container template - - Enter your container image URI (e.g., `cr.seqera.io/scidev/your-example`) - - Set a **Studio name** and optional **Description** -4. Configure compute resources in the **Compute and Data** section: - - Select your compute environment - - Adjust CPU, GPU, and memory allocations as needed - - Mount any required data using the **Mount data** option - - Configure environment variables if the example supports them (see [Environment Variables](#environment-variables) section) -5. Review the configuration in the **Summary** section -6. Click **Add and start** to create and launch the Studio +## Features -## Environment Variables +- QuPath 0.6.0 bioimage analysis desktop +- Browser access through LinuxServer.io KasmVNC +- Single-app mode that launches QuPath directly +- KasmVNC WebP, quality, frame-rate, and thread tuning for interactive use +- Compatible with Seqera Studios custom environments and Data Link mounts -Some examples support environment variable configuration to customize data paths and application settings without modifying the container image. This makes those examples more flexible and reusable across different datasets and configurations. +> **Note:** QuPath is x86_64 only. Build and run this Studio as `linux/amd64`. -### Examples with Environment Variables +## Docker Image -Only the following examples support environment variable configuration: -- **CellxGene**: `DATASET_FILE`, `DATASET_TITLE` - Configure dataset path and display title -- **Shiny**: `DATA_PATH` - Configure data file path with automatic cloud storage path conversion +The container image is available at: -### Examples without Environment Variables +``` +ghcr.io/seqeralabs/custom-studios-examples/kasmvnc-qupath:latest +``` -These examples work with their default configurations and don't require environment variable setup: -- **Marimo**: Interactive Python notebook environment -- **Streamlit**: MultiQC visualization with web-based data loading interface -- **TTYD**: Web-based terminal with pre-installed bioinformatics tools +## Local Testing -### Using Environment Variables in Seqera Studios +```bash +cd .seqera +docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.9 -t kasmvnc-qupath . +docker run --rm --platform linux/amd64 --shm-size=2g -p 6901:6901 --entrypoint /init kasmvnc-qupath +``` -When deploying to Seqera Studios, you can configure environment variables in the **Compute and Data** section: -1. Expand the **Environment variables** section -2. Add key-value pairs for the variables you want to customize -3. The application will use these values instead of the defaults +QuPath will be available at http://localhost:6901. -## Documentation +## Configuration -- [Official documentation on building custom studio environments](https://docs.seqera.io/platform-cloud/studios/custom-envs#custom-containers) -- Each example's README contains specific instructions for: - - Building and testing locally - - Required dependencies and configurations - - Example-specific features and usage - - Data format requirements - - Customization options +| Variable | Default | Description | +|----------|---------|-------------| +| `CONNECT_TOOL_PORT` | Set by platform | KasmVNC web port in Seqera Studios | +| `CUSTOM_PORT` | `CONNECT_TOOL_PORT` or `6901` | KasmVNC web port used by the base image | -## Contributing +## References -Feel free to contribute new examples or improvements to existing ones. Each example should: -- Follow the established README structure -- Include comprehensive documentation -- Maintain consistency with common features -- Provide clear prerequisites and deployment instructions -- Include example data or clear data requirements - - +- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) +- [Seqera Studios: Add from Git Repository](https://docs.seqera.io/platform-cloud/studios/add-studio-git-repo) +- [QuPath Documentation](https://qupath.readthedocs.io/) +- [KasmVNC Documentation](https://kasmweb.com/kasmvnc) diff --git a/cellxgene/Dockerfile b/cellxgene/Dockerfile deleted file mode 100644 index 98cf9e7..0000000 --- a/cellxgene/Dockerfile +++ /dev/null @@ -1,85 +0,0 @@ -# --------------------------------------------------------------- -# 1) Multi-stage build: Pull the connect-client binary -# --------------------------------------------------------------- -ARG CONNECT_CLIENT_VERSION=0.9 -FROM public.cr.seqera.io/platform/connect-client:${CONNECT_CLIENT_VERSION} AS connect - -# --------------------------------------------------------------- -# 2) Additional base image for CellxGene -# --------------------------------------------------------------- -FROM python:3.10-slim - -# Just for the automation at Seqera -LABEL org.opencontainers.image.source="https://github.com/seqeralabs/custom-studios-examples" - -# Avoid interactive prompts during package install -ENV DEBIAN_FRONTEND=noninteractive - -# Add backports repository and install specific btrfs-progs version -RUN echo "deb http://deb.debian.org/debian bookworm-backports main contrib non-free-firmware" | tee -a /etc/apt/sources.list && \ - apt-get update && \ - apt-get install -y btrfs-progs=6.14-1~bpo12+1 - -# Update packages and install minimal tools -RUN apt-get update && apt-get install -y \ - build-essential \ - wget \ - && rm -rf /var/lib/apt/lists/* - -# Install CellxGene and its dependencies -RUN pip install cellxgene==1.3.0 - -# Define CellxGene dataset path and title with defaults -ENV DATASET_FILE=s3://cellxgene_datasets/pbmc3k.h5ad -ENV DATASET_TITLE="PBMCs 3k test dataset" -ENV USER_DATA_DIR=/user-data/cellxgene -ENV ANNOTATIONS_DIR=/user-data/cellxgene - -# Create user-data directory -RUN mkdir -p /user-data/cellxgene - -# Add connect-client version label to image for supported capabilties tracking -ARG CONNECT_CLIENT_VERSION -LABEL io.seqera.connect.version="${CONNECT_CLIENT_VERSION}" - -# Copy connect-client from the first stage -COPY --from=connect /usr/bin/connect-client /usr/bin/connect-client - -# "Install" connect-client (sets up any needed config) -RUN /usr/bin/connect-client --install - -# --------------------------------------------------------------- -# 3) Launch with connect-client --entrypoint (for Tower) -# --------------------------------------------------------------- -ENTRYPOINT ["/usr/bin/connect-client", "--entrypoint"] - -# --------------------------------------------------------------- -# 4) Command: Run CellxGene with cloud storage path translation -# --------------------------------------------------------------- -# The port is set by CONNECT_TOOL_PORT environment variable -# Convert cloud storage paths to local Studio paths -CMD ["/bin/bash", "-c", "bash <<'EOF'\n\ -# Function to convert cloud storage path to local Studio path\n\ -convert_path() {\n\ - local input_path=\"$1\"\n\ - if [[ \"$input_path\" =~ ^(s3|gs|az):// ]]; then\n\ - local cloud_path=${input_path#*://}\n\ - local bucket_name=${cloud_path%%/*}\n\ - local object_path=${cloud_path#*/}\n\ - echo \"/workspace/data/$bucket_name/$object_path\"\n\ - else\n\ - echo \"$input_path\"\n\ - fi\n\ -}\n\ -\n\ -DATASET_LOCAL=$(convert_path \"${DATASET_FILE}\")\n\ -USERDATA_LOCAL=$(convert_path \"${USER_DATA_DIR}\")\n\ -ANNOTATIONS_LOCAL=$(convert_path \"${ANNOTATIONS_DIR}\")\n\ -\n\ -mkdir -p \"${USERDATA_LOCAL}\" \"${ANNOTATIONS_LOCAL}\"\n\ -\n\ -/usr/local/bin/cellxgene launch --host 0.0.0.0 --port ${CONNECT_TOOL_PORT} \\\n\ - --user-generated-data-dir \"${USERDATA_LOCAL}\" \\\n\ - --annotations-dir \"${ANNOTATIONS_LOCAL}\" \\\n\ - --title \"${DATASET_TITLE}\" \"${DATASET_LOCAL}\"\n\ -EOF"] \ No newline at end of file diff --git a/cellxgene/README.md b/cellxgene/README.md deleted file mode 100644 index 73f1f9f..0000000 --- a/cellxgene/README.md +++ /dev/null @@ -1,158 +0,0 @@ -# CellxGene Studio Environment - -This example provides a custom container image for running [CellxGene](https://chanzuckerberg.github.io/cellxgene/), an interactive single-cell data visualization platform, as a Studio environment in Seqera Platform. - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Files](#files) -- [Prerequisites](#prerequisites) -- [Building the Container](#building-the-container) -- [Local Testing](#local-testing) -- [Using in Seqera Studios](#using-in-seqera-studios) -- [Notes](#notes) -- [References](#references) - -## Overview - -This container is designed for use as a [custom Studio environment](https://docs.seqera.io/platform-cloud/studios/custom-envs) in Seqera Platform. It provides an interactive interface for exploring single-cell data using the CellxGene visualization platform. - -![Screenshot of CellxGene](screenshot.png) - -## Docker Image - -The container image is available at: -``` -ghcr.io/seqeralabs/custom-studios-examples/cellxgene:latest -``` - -For specific versions, use the release tag (e.g., `ghcr.io/seqeralabs/custom-studios-examples/cellxgene:v1.0.0`). - -## Features - -- CellxGene 1.3.0 visualization platform -- Support for .h5ad datasets -- Interactive single-cell data exploration -- Automatic data mounting via datalinks -- Configurable dataset path, title, and storage directories via environment variables -- Cloud storage path support with automatic translation to local Studio paths - -> [!NOTE] -> For common features shared across all examples, see the [main README](../README.md#common-features). - -## Files - -- `Dockerfile`: Container definition using multi-stage build -- `README.md`: This documentation file -- `screenshot.png`: Example screenshot of the CellxGene interface - -## Prerequisites - -> [!NOTE] -> For common prerequisites, see the [main README](../README.md#prerequisites). - -Additional requirements specific to this example: -- .h5ad format single-cell datasets - -## Building the Container - -> [!IMPORTANT] -> You must provide the `CONNECT_CLIENT_VERSION` build argument when building the container. - -To build the container locally: - -```bash -docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.8 -t cellxgene-example . -``` - -## Local Testing - -To test the app locally, you need to override the entrypoint: - -```bash -docker run -p 3000:3000 --entrypoint /usr/local/bin/cellxgene cellxgene-example launch \ - --host 0.0.0.0 \ - --port 3000 \ - --user-generated-data-dir /user-data/cellxgene \ - --annotations-dir /user-data/cellxgene \ - --title "PBMCs 3k test dataset" \ - /path/to/your/dataset.h5ad -``` - -To use a specific data file, make it available at /workspace/data/cellxgene_datasets/ in the container: - -```bash -docker run -p 3000:3000 --entrypoint /usr/local/bin/cellxgene -v $(pwd)/data:/workspace/data/cellxgene_datasets cellxgene-example launch \ - --host 0.0.0.0 \ - --port 3000 \ - --user-generated-data-dir /user-data/cellxgene \ - --annotations-dir /user-data/cellxgene \ - --title "Your Dataset" \ - /workspace/data/cellxgene_datasets/your_dataset.h5ad -``` - -The app will be available at http://localhost:3000 - -## Cloud Storage Path Translation - -The container automatically converts cloud storage paths to local Studio paths. Supported providers include: - -- **Amazon S3**: `s3://bucket/path/to/dataset.h5ad` -- **Google Cloud Storage**: `gs://bucket/path/to/dataset.h5ad` -- **Azure Blob Storage**: `az://container/path/to/dataset.h5ad` - -**Examples:** -- S3: `s3://my-genomics-data/single-cell/experiment1.h5ad` → `/workspace/data/my-genomics-data/single-cell/experiment1.h5ad` -- GCS: `gs://research-bucket/datasets/pbmc3k.h5ad` → `/workspace/data/research-bucket/datasets/pbmc3k.h5ad` -- Azure: `az://data-container/studies/cellxgene.h5ad` → `/workspace/data/data-container/studies/cellxgene.h5ad` - -**Requirements:** -- Mount the cloud storage bucket/container from Data Explorer in Seqera Studios -- Provide cloud storage paths in the `DATASET_FILE` environment variable - -> [!WARNING] -> **Bucket Mounting Required**: When using cloud storage paths (`s3://`, `gs://`, `az://`), ensure the corresponding buckets are mounted in your Studio via the **Mount data** option. Unmounted buckets will cause the Studio to fail when trying to access the converted paths. - -## Using in Seqera Studios - -> [!NOTE] -> For the common deployment process, see the [main README](../README.md#deploying-to-seqera-studios). - -Additional steps specific to this example: -1. In the **Compute and Data** tab, click the **Mount data** button to mount your cloud storage bucket/container -2. Follow the common deployment process -3. Configure environment variables: - - `DATASET_FILE`: Cloud storage path to your .h5ad file - - Supports S3 (`s3://`), Google Cloud Storage (`gs://`), and Azure Blob Storage (`az://`) paths - - Example: `s3://my-genomics-data/single-cell/experiment1.h5ad` - - `DATASET_TITLE`: Title to display in the CellxGene interface - - Example: `"My Single-Cell Analysis"` - - `USER_DATA_DIR`: Path for user-generated data storage - - Default: `/user-data/cellxgene` (local directory) - - Supports cloud storage paths (automatically converted to local Studio paths) - - Example: `s3://my-bucket/user-data/cellxgene` - - `ANNOTATIONS_DIR`: Path for annotations storage - - Default: `/user-data/cellxgene` (local directory) - - Supports cloud storage paths (automatically converted to local Studio paths) - - Example: `s3://my-bucket/annotations/cellxgene` - -> [!WARNING] -> **Bucket Mounting**: If using cloud storage paths for `USER_DATA_DIR` or `ANNOTATIONS_DIR`, ensure the corresponding buckets are mounted in your Studio. Unmounted buckets will cause the Studio to fail when trying to access the converted paths. - -## Notes - -- The app uses CellxGene 1.3.0 for interactive single-cell data visualization -- User data and annotations directories can be configured via environment variables -- Default storage locations: `/user-data/cellxgene` (can be overridden with cloud storage paths) -- Specify your dataset via the DATASET_FILE environment variable -- Customize the display title via the DATASET_TITLE environment variable - -> [!NOTE] -> For common technical notes, see the [main README](../README.md#common-features). - -## References - -- [CellxGene Documentation](https://chanzuckerberg.github.io/cellxgene/) -- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) -- [Wave Documentation](https://docs.seqera.io/platform-cloud/wave/) \ No newline at end of file diff --git a/cellxgene/screenshot.png b/cellxgene/screenshot.png deleted file mode 100644 index 301cfeb..0000000 Binary files a/cellxgene/screenshot.png and /dev/null differ diff --git a/kasmVNC/README.md b/kasmVNC/README.md deleted file mode 100644 index c79d603..0000000 --- a/kasmVNC/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# KasmVNC Studio Environments - -This folder contains custom container images for running GUI desktop applications in Seqera Studios using [KasmVNC](https://kasmweb.com/kasmvnc). All images are based on the [LinuxServer.io KasmVNC base image](https://docs.linuxserver.io/images/docker-baseimage-kasmvnc/) and run in single-app mode (no desktop environment). - -## Available Applications - -| Application | Description | Platform | -|-------------|-------------|----------| -| [QuPath](./qupath/) | Bioimage analysis for pathology | x86_64 only | -| [napari](./napari/) | Python-based multi-dimensional image viewer | x86_64, arm64 | - -## Common Architecture - -All KasmVNC images share the same architecture: - -``` -┌─────────────────────────────────────────────┐ -│ LinuxServer.io KasmVNC Base Image │ -│ (Ubuntu Jammy + KasmVNC server) │ -├─────────────────────────────────────────────┤ -│ Application Layer │ -│ (QuPath / napari) │ -├─────────────────────────────────────────────┤ -│ Seqera Studios Integration │ -│ (connect-client + Fusion filesystem) │ -└─────────────────────────────────────────────┘ -``` - -## Performance Optimizations - -All images include KasmVNC performance optimizations for better streaming responsiveness: - -```dockerfile -ENV KASM_VNC_ENABLE_WEBP=1 # WebP compression (better than JPEG) -ENV KASM_VNC_JPEG_QUALITY=5 # 1-9, lower = faster/smaller -ENV KASM_VNC_MAX_FRAME_RATE=30 # Limit FPS -ENV KASM_VNC_THREADS=4 # Match vCPU count -``` - -**Runtime recommendations:** -- Use `--shm-size=2g` or higher for Java/GUI apps when testing locally -- Use compute-optimized EC2 instances (c6i, c7i) for better responsiveness in Studios -- Deploy in regions close to users to minimize latency - -## Building Images - -All images require the `CONNECT_CLIENT_VERSION` build argument: - -```bash -# QuPath -cd qupath && docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.9 -t kasmvnc-qupath . - -# napari -cd napari && docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.9 -t kasmvnc-napari . -``` - -## Local Testing - -To test locally, override the entrypoint to bypass connect-client: - -```bash -docker run --rm -it --platform linux/amd64 --shm-size=2g -p 6901:6901 \ - --entrypoint /init -``` - -Access the application at http://localhost:6901 - -## References - -- [KasmVNC Documentation](https://kasmweb.com/kasmvnc) -- [LinuxServer.io KasmVNC Base Image](https://docs.linuxserver.io/images/docker-baseimage-kasmvnc/) -- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) diff --git a/kasmVNC/napari/Dockerfile b/kasmVNC/napari/Dockerfile deleted file mode 100644 index 21d096a..0000000 --- a/kasmVNC/napari/Dockerfile +++ /dev/null @@ -1,69 +0,0 @@ -# --------------------------------------------------------------- -# 1) Multi-stage build: Pull the connect-client binary -# --------------------------------------------------------------- -ARG CONNECT_CLIENT_VERSION=0.9 -FROM public.cr.seqera.io/platform/connect-client:${CONNECT_CLIENT_VERSION} AS connect - -# --------------------------------------------------------------- -# 2) KasmVNC base image with napari -# --------------------------------------------------------------- -FROM lscr.io/linuxserver/baseimage-kasmvnc:ubuntujammy - -# Just for the automation at Seqera -LABEL org.opencontainers.image.source="https://github.com/seqeralabs/custom-studios-examples" - -ENV TITLE="napari" - -# KasmVNC Performance Optimizations -ENV KASM_VNC_ENABLE_WEBP=1 -ENV KASM_VNC_JPEG_QUALITY=5 -ENV KASM_VNC_MAX_FRAME_RATE=30 -ENV KASM_VNC_THREADS=4 - -# Install Python and system dependencies for napari -RUN apt-get update && apt-get install -y --no-install-recommends \ - python3.10 \ - python3.10-venv \ - python3-pip \ - libgl1 \ - libglib2.0-0 \ - libfontconfig1 \ - libxcb-icccm4 \ - libxcb-image0 \ - libxcb-keysyms1 \ - libxcb-randr0 \ - libxcb-render-util0 \ - libxcb-shape0 \ - libxcb-xinerama0 \ - libxcb-xkb1 \ - libxkbcommon-x11-0 \ - libdbus-1-3 \ - libegl1 \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Install napari with PyQt5 backend -RUN pip3 install --no-cache-dir "napari[all]" pyqt5 - -# Single-app mode: application launches directly, no desktop -RUN echo "napari" > /defaults/autostart - -# --------------------------------------------------------------- -# 3) Seqera Studios integration -# --------------------------------------------------------------- - -# Add connect-client version label to image for supported capabilities tracking -ARG CONNECT_CLIENT_VERSION -LABEL io.seqera.connect.version="${CONNECT_CLIENT_VERSION}" - -# Copy connect-client from the first stage -COPY --from=connect /usr/bin/connect-client /usr/bin/connect-client - -# Install connect-client -RUN /usr/bin/connect-client --install - -# Seqera Studios entrypoint (connect-client handles fusion filesystem) -ENTRYPOINT ["/usr/bin/connect-client", "--entrypoint"] - -# CMD bridges CONNECT_TOOL_PORT to KasmVNC's CUSTOM_PORT and launches the init -CMD ["/bin/bash", "-c", "export CUSTOM_PORT=${CONNECT_TOOL_PORT:-6901} && exec /init"] diff --git a/kasmVNC/napari/README.md b/kasmVNC/napari/README.md deleted file mode 100644 index fbf9793..0000000 --- a/kasmVNC/napari/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# napari KasmVNC Studio Environment - -This example provides a custom container image for running [napari](https://napari.org/) in Seqera Studios using [KasmVNC](https://kasmweb.com/kasmvnc). It demonstrates how to run Python-based GUI applications in Studios via a web-based VNC interface. - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Files](#files) -- [Prerequisites](#prerequisites) -- [Building the Container](#building-the-container) -- [Local Testing](#local-testing) -- [Using in Seqera Studios](#using-in-seqera-studios) -- [Notes](#notes) -- [References](#references) - -## Overview - -This container is designed for use as a [custom Studio environment](https://docs.seqera.io/platform-cloud/studios/custom-envs) in Seqera Platform. It provides napari, a fast, interactive viewer for multi-dimensional images, accessible through a web browser via KasmVNC. - -## Docker Image - -The container image is available at: -``` -ghcr.io/seqeralabs/custom-studios-examples/kasmvnc-napari:latest -``` - -For specific versions, use the release tag (e.g., `ghcr.io/seqeralabs/custom-studios-examples/kasmvnc-napari:v1.0.0`). - -## Features - -- Full napari GUI application via web browser -- Based on [LinuxServer.io KasmVNC base image](https://docs.linuxserver.io/images/docker-baseimage-kasmvnc/) -- Single-app mode (no desktop environment, napari launches directly) -- KasmVNC performance optimizations for better streaming -- Python 3.10 with PyQt5 backend -- Supports mounting data via Seqera Data Links - -> [!NOTE] -> For common features shared across all KasmVNC examples, see the [KasmVNC README](../README.md). - -## Files - -- `Dockerfile`: Container definition using multi-stage build with connect-client - -## Prerequisites - -> [!NOTE] -> For common prerequisites, see the [main README](../../README.md#prerequisites). - -No additional prerequisites specific to this example. - -## Building the Container - -> [!IMPORTANT] -> You must provide the `CONNECT_CLIENT_VERSION` build argument when building the container. - -To build the container locally: - -```bash -docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.9 -t kasmvnc-napari . -``` - -## Local Testing - -To test napari locally, override the entrypoint to bypass connect-client: - -```bash -docker run --rm -it --platform linux/amd64 --shm-size=2g -p 6901:6901 \ - --entrypoint /init kasmvnc-napari -``` - -napari will be available at http://localhost:6901 - -> [!NOTE] -> The `--shm-size=2g` flag is recommended for KasmVNC to prevent shared memory issues and improve performance. - -## Using in Seqera Studios - -> [!NOTE] -> For the common deployment process, see the [main README](../../README.md#deploying-to-seqera-studios). - -Additional steps specific to this example: -1. Follow the common deployment process -2. The KasmVNC server will automatically use the `CONNECT_TOOL_PORT` environment variable in Studios -3. Mount your image data via Data Links - files will be available at `/workspace/data//` - -## Notes - -- napari supports both x86_64 and arm64 architectures -- The CMD bridges `CONNECT_TOOL_PORT` (Seqera Studios) to `CUSTOM_PORT` (KasmVNC) -- Uses `connect-client --entrypoint` for Fusion filesystem support in Studios -- Uses LinuxServer.io's single-app mode (napari launches directly without a desktop environment) -- The port is automatically configured via the `CONNECT_TOOL_PORT` environment variable in Studios -- Additional napari plugins can be installed by adding `pip install` commands to the Dockerfile - -> [!NOTE] -> For common technical notes, see the [KasmVNC README](../README.md). - -## References - -- [napari Documentation](https://napari.org/stable/) -- [napari GitHub](https://github.com/napari/napari) -- [KasmVNC Documentation](https://kasmweb.com/kasmvnc) -- [LinuxServer.io KasmVNC Base Image](https://docs.linuxserver.io/images/docker-baseimage-kasmvnc/) -- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) diff --git a/kasmVNC/qupath/README.md b/kasmVNC/qupath/README.md deleted file mode 100644 index 9da121c..0000000 --- a/kasmVNC/qupath/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# QuPath KasmVNC Studio Environment - -This example provides a custom container image for running [QuPath](https://qupath.github.io/) in Seqera Studios using [KasmVNC](https://kasmweb.com/kasmvnc). It demonstrates how to run full GUI desktop applications in Studios via a web-based VNC interface. - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Files](#files) -- [Prerequisites](#prerequisites) -- [Building the Container](#building-the-container) -- [Local Testing](#local-testing) -- [Using in Seqera Studios](#using-in-seqera-studios) -- [Notes](#notes) -- [References](#references) - -## Overview - -This container is designed for use as a [custom Studio environment](https://docs.seqera.io/platform-cloud/studios/custom-envs) in Seqera Platform. It provides QuPath, an open-source bioimage analysis application, accessible through a web browser via KasmVNC. - -## Docker Image - -The container image is available at: -``` -ghcr.io/seqeralabs/custom-studios-examples/kasmvnc-qupath:latest -``` - -For specific versions, use the release tag (e.g., `ghcr.io/seqeralabs/custom-studios-examples/kasmvnc-qupath:v1.0.0`). - -## Features - -- Full QuPath 0.6.0 GUI application via web browser -- Based on [LinuxServer.io KasmVNC base image](https://docs.linuxserver.io/images/docker-baseimage-kasmvnc/) -- Single-app mode (no desktop environment, QuPath launches directly) -- KasmVNC performance optimizations for better streaming -- Supports mounting data via Seqera Data Links - -> [!NOTE] -> For common features shared across all KasmVNC examples, see the [KasmVNC README](../README.md). - -## Files - -- `Dockerfile`: Container definition using multi-stage build with connect-client - -## Prerequisites - -> [!NOTE] -> For common prerequisites, see the [main README](../../README.md#prerequisites). - -No additional prerequisites specific to this example. - -## Building the Container - -> [!IMPORTANT] -> You must provide the `CONNECT_CLIENT_VERSION` build argument when building the container. - -To build the container locally: - -```bash -docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.9 -t kasmvnc-qupath . -``` - -## Local Testing - -To test QuPath locally, override the entrypoint to bypass connect-client: - -```bash -docker run --rm -it --platform linux/amd64 --shm-size=2g -p 6901:6901 \ - --entrypoint /init kasmvnc-qupath -``` - -QuPath will be available at http://localhost:6901 - -> [!NOTE] -> The `--shm-size=2g` flag is recommended for KasmVNC and Java applications to prevent shared memory issues and improve performance. - -## Using in Seqera Studios - -> [!NOTE] -> For the common deployment process, see the [main README](../../README.md#deploying-to-seqera-studios). - -Additional steps specific to this example: -1. Follow the common deployment process -2. The KasmVNC server will automatically use the `CONNECT_TOOL_PORT` environment variable in Studios -3. Mount your image data via Data Links - files will be available at `/workspace/data//` - -## Notes - -- QuPath is x86_64 only - the container must be built for `linux/amd64` platform -- The CMD bridges `CONNECT_TOOL_PORT` (Seqera Studios) to `CUSTOM_PORT` (KasmVNC) -- Uses `connect-client --entrypoint` for Fusion filesystem support in Studios -- Uses LinuxServer.io's single-app mode (QuPath launches directly without a desktop environment) -- The port is automatically configured via the `CONNECT_TOOL_PORT` environment variable in Studios - -> [!NOTE] -> For common technical notes, see the [KasmVNC README](../README.md). - -## References - -- [QuPath Documentation](https://qupath.readthedocs.io/) -- [QuPath GitHub](https://qupath.github.io/) -- [KasmVNC Documentation](https://kasmweb.com/kasmvnc) -- [LinuxServer.io KasmVNC Base Image](https://docs.linuxserver.io/images/docker-baseimage-kasmvnc/) -- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) diff --git a/marimo/Dockerfile b/marimo/Dockerfile deleted file mode 100644 index 2f86114..0000000 --- a/marimo/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# --------------------------------------------------------------- -# 1) Multi-stage build: Pull the connect-client binary -# --------------------------------------------------------------- -# Test Build -ARG CONNECT_CLIENT_VERSION=0.9 -FROM public.cr.seqera.io/platform/connect-client:${CONNECT_CLIENT_VERSION} AS connect - -# Choose a python version that you know works with your application -FROM python:3.11-slim - -# Just for the automation at Seqera -LABEL org.opencontainers.image.source="https://github.com/seqeralabs/custom-studios-examples" - -# Install uv for fast package management -COPY --from=ghcr.io/astral-sh/uv:0.4.20 /uv /bin/uv - -ENV UV_SYSTEM_PYTHON=1 - -WORKDIR /app - -# Install the requirements using uv -RUN uv pip install scikit-learn pandas altair micropip marimo==0.11.13 - -# Define the port for the marimo server -EXPOSE $CONNECT_TOOL_PORT - -ARG CONNECT_CLIENT_VERSION -LABEL io.seqera.connect.version="${CONNECT_CLIENT_VERSION}" -COPY --from=connect /usr/bin/connect-client /usr/bin/connect-client -RUN /bin/sh -c "/usr/bin/connect-client --install" -RUN echo "deb http://deb.debian.org/debian bookworm-backports main contrib non-free-firmware" | tee -a /etc/apt/sources.list -RUN apt update && apt install -y --allow-downgrades btrfs-progs=6.14-1~bpo12+1 -ENTRYPOINT ["/usr/bin/connect-client", "--entrypoint"] - -CMD marimo edit -p $CONNECT_TOOL_PORT --no-token diff --git a/marimo/README.md b/marimo/README.md deleted file mode 100644 index 8bd9a6d..0000000 --- a/marimo/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Marimo Studio Environment - -This repository provides a custom container image for running [marimo](https://marimo.io), an open-source reactive Python notebook, as a Studio environment in Seqera Platform. - -## Docker Image - -The container image is available at: -``` -ghcr.io/seqeralabs/custom-studios-examples/marimo:latest -``` - -For specific versions, use the release tag (e.g., `ghcr.io/seqeralabs/custom-studios-examples/marimo:v1.0.0`). - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Prerequisites](#prerequisites) -- [Building the Container](#building-the-container) -- [Using in Seqera Studios](#using-in-seqera-studios) -- [Customizing the Environment](#customizing-the-environment) -- [Notes](#notes) -- [References](#references) - -## Overview - -This container is designed for use as a [custom Studio environment](https://docs.seqera.io/platform-cloud/studios/custom-envs) in Seqera Platform. It is based on the required Seqera base image and includes the necessary `connect-client` for compatibility. - -## Features - -- Open-source, reactive Python notebook (marimo) -- Reproducible and git-friendly -- SQL built-in, script execution, and app sharing -- Compatible with Seqera Studios custom environments - -> [!WARNING] -> Marimo does not support opening the same notebook in multiple tabs to avoid state conflicts. They have recently added a feature to allow this, but it has not been tested in Seqera Studios. - -## Prerequisites - -- [Docker](https://www.docker.com/) installed -- [Wave](https://docs.seqera.io/platform-cloud/wave/) configured in your Seqera Platform workspace (required for custom environments) -- Access to a container registry (public or Amazon ECR) if you wish to push your image - -## Building the Container - -> [!IMPORTANT] -> You must provide the `CONNECT_CLIENT_VERSION` build argument when building the container. - -To build the container locally: - -```sh -docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.8 -t marimo-studio . -``` - -> [!NOTE] -> The container must use the value of the `CONNECT_TOOL_PORT` environment variable as the listening port for marimo. The Dockerfile is already configured for this. - -## Using in Seqera Studios - -1. **Push your image** to a container registry accessible by Seqera Platform. -2. In Seqera Platform, go to the **Studios** tab and click **Add Studio**. -3. Select **Prebuilt container image** as the template. -4. Enter your container image URI (e.g., `cr.your-registry.io/your-org/marimo-studio:latest`). -5. Configure compute resources and data mounts as needed. -6. Launch the Studio. - -For more details, see the [official documentation](https://docs.seqera.io/platform-cloud/studios/custom-envs). - -## Customizing the Environment - -You can further customize this environment by: - -- Adding Conda or pip packages (see [Conda package syntax](https://docs.seqera.io/platform-cloud/studios/custom-envs#conda-package-syntax)) -- Modifying the Dockerfile to include additional dependencies - -## References - -- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) -- [marimo Documentation](https://marimo.io) -- [Wave Documentation](https://docs.seqera.io/platform-cloud/wave/) diff --git a/shiny-simple-example/Dockerfile b/shiny-simple-example/Dockerfile deleted file mode 100644 index 05d2fe5..0000000 --- a/shiny-simple-example/Dockerfile +++ /dev/null @@ -1,73 +0,0 @@ -# --------------------------------------------------------------- -# 1) Multi-stage build: Pull the connect-client binary -# --------------------------------------------------------------- -ARG CONNECT_CLIENT_VERSION=0.9 -FROM public.cr.seqera.io/platform/connect-client:${CONNECT_CLIENT_VERSION} AS connect - -# --------------------------------------------------------------- -# 2) Final stage: Ubuntu + micromamba + r-shiny -# --------------------------------------------------------------- -FROM ubuntu:22.04 - -# Just for the automation at Seqera -LABEL org.opencontainers.image.source="https://github.com/seqeralabs/custom-studios-examples" - -# Avoid interactive prompts during package install -ENV DEBIAN_FRONTEND=noninteractive - -# Update packages and install minimal tools -RUN apt-get update --yes && apt-get install --yes --no-install-recommends \ - wget \ - ca-certificates \ - bzip2 \ - && rm -rf /var/lib/apt/lists/* - -# --------------------------------------------------------------- -# Install micromamba -# --------------------------------------------------------------- -ENV MAMBA_ROOT_PREFIX=/opt/conda -RUN wget -qO- https://micromamba.snakepit.net/api/micromamba/linux-64/latest \ - | tar -xvj --strip-components=1 bin/micromamba \ - && mv micromamba /usr/local/bin/micromamba \ - && mkdir -p /opt/conda \ - && chmod -R 777 /opt/conda - -# Create a conda env with shiny and additional R packages -RUN rm -rf /opt/conda/pkgs/*.lock && \ - micromamba create -y -n shiny -c conda-forge \ - r-shiny \ - r-ggplot2 \ - r-dplyr \ - && micromamba clean --all --yes \ - && rm -rf /opt/conda/pkgs/*.lock - -# Add connect-client version label to image for supported capabilties tracking -ARG CONNECT_CLIENT_VERSION -LABEL io.seqera.connect.version="${CONNECT_CLIENT_VERSION}" - -# Copy connect-client from the first stage -COPY --from=connect /usr/bin/connect-client /usr/bin/connect-client - -# "Install" connect-client (sets up any needed config) -RUN /usr/bin/connect-client --install - -# Set a working directory for your app -WORKDIR /app - -# Define data path with default -ENV DATA_PATH=s3://shiny-inputs/data.csv - -# Copy your Shiny code and data -COPY app_plot_demo.R /app/ -COPY data.csv /app/ - -# --------------------------------------------------------------- -# 3) Launch with connect-client --entrypoint (for Tower) -# --------------------------------------------------------------- -ENTRYPOINT ["/usr/bin/connect-client", "--entrypoint"] - -# --------------------------------------------------------------- -# 4) Command: Run your Shiny app via micromamba -# --------------------------------------------------------------- -# The port is set by CONNECT_TOOL_PORT environment variable -CMD ["micromamba", "run", "-n", "shiny", "R", "-e", "shiny::runApp('/app/app_plot_demo.R', host='0.0.0.0', port=as.integer(Sys.getenv('CONNECT_TOOL_PORT')))"] \ No newline at end of file diff --git a/shiny-simple-example/README.md b/shiny-simple-example/README.md deleted file mode 100644 index 1d5488c..0000000 --- a/shiny-simple-example/README.md +++ /dev/null @@ -1,126 +0,0 @@ -# Shiny Studio Environment - -This example provides a custom container image for running a [R Shiny](https://shiny.rstudio.com/) application in Seqera Platform, demonstrating interactive data visualization capabilities. - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Files](#files) -- [Prerequisites](#prerequisites) -- [Building the Container](#building-the-container) -- [Local Testing](#local-testing) -- [Using in Seqera Studios](#using-in-seqera-studios) -- [Notes](#notes) -- [References](#references) - -## Overview - -This container is designed for use as a [custom Studio environment](https://docs.seqera.io/platform-cloud/studios/custom-envs) in Seqera Platform. It provides a simple but powerful example of interactive data visualization using R Shiny. - -![Screenshot of the Shiny app](screenshot.png) - -## Docker Image - -The container image is available at: -``` -ghcr.io/seqeralabs/custom-studios-examples/shiny:latest -``` - -For specific versions, use the release tag (e.g., `ghcr.io/seqeralabs/custom-studios-examples/shiny:v1.0.0`). - -## Features - -- Advanced data visualization with multiple plot types (scatter, line, bar, box, density) -- Interactive controls and color themes -- Compatible with both local Docker testing and Seqera Studios -- Efficient package management with micromamba -- Easy data mounting via datalinks -- Configurable data path via environment variables -- Cloud storage path support with automatic translation to local Studio paths - -## Files - -- `app_plot_demo.R`: The main Shiny application -- `example_data.csv`: Sample data for the visualization -- `Dockerfile`: Container definition - -## Prerequisites - -- [Docker](https://www.docker.com/) installed -- [Wave](https://docs.seqera.io/platform-cloud/wave/) configured in your Seqera Platform workspace -- Access to a container registry (public or Amazon ECR) if you wish to push your image -- R data files in CSV format - -## Building the Container - -> [!IMPORTANT] -> You must provide the `CONNECT_CLIENT_VERSION` build argument when building the container. - -To build the container locally: - -```bash -docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.8 -t shiny-simple-example . -``` - -## Local Testing - -To test the app locally, you need to override the entrypoint: - -```bash -docker run -p 3000:3000 --entrypoint micromamba shiny-simple-example run -n shiny R -e "shiny::runApp('/app/app_plot_demo.R', host='0.0.0.0', port=3000)" -``` - -To use a specific data file, make it available at /workspace/data/shiny-inputs/data.csv in the container: - -```bash -docker run -p 3000:3000 --entrypoint micromamba -v $(pwd)/../data/shiny-inputs:/workspace/data/shiny-inputs shiny-simple-example run -n shiny R -e "shiny::runApp('/app/app_plot_demo.R', host='0.0.0.0', port=3000)" -``` - -The app will be available at http://localhost:3000 - -## Cloud Storage Path Translation - -The application automatically converts cloud storage paths to local Studio paths. Supported providers include: - -- **Amazon S3**: `s3://bucket/path/to/data.csv` -- **Google Cloud Storage**: `gs://bucket/path/to/data.csv` -- **Azure Blob Storage**: `az://container/path/to/data.csv` - -**Examples:** -- S3: `s3://my-data-bucket/datasets/experiment.csv` → `/workspace/data/my-data-bucket/datasets/experiment.csv` -- GCS: `gs://research-data/analysis/results.csv` → `/workspace/data/research-data/analysis/results.csv` -- Azure: `az://data-container/studies/sample.csv` → `/workspace/data/data-container/studies/sample.csv` - -**Requirements:** -- Mount the cloud storage bucket/container from Data Explorer in Seqera Studios -- Provide cloud storage paths in the `DATA_PATH` environment variable - -## Using in Seqera Studios - -> [!NOTE] -> For the common deployment process, see the [main README](../README.md#deploying-to-seqera-studios). - -Additional steps specific to this example: -1. In the **Compute and Data** tab, click the **Mount data** button to mount your cloud storage bucket/container -2. Follow the common deployment process -3. Configure environment variables: - - `DATA_PATH`: Cloud storage path to your CSV file - - Supports S3 (`s3://`), Google Cloud Storage (`gs://`), and Azure Blob Storage (`az://`) paths - - Example: `s3://my-data-bucket/datasets/experiment.csv` - -## Notes - -- The app provides advanced data visualization with multiple plot types and interactive controls -- The Dockerfile uses micromamba for efficient package management -- The container is built for linux/amd64 platform compatibility -- Data files should be in CSV format -- Specify your data file via the DATA_PATH environment variable -- Cloud storage paths are automatically converted to local Studio paths - -## References - -- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) -- [R Shiny Documentation](https://shiny.rstudio.com/) -- [Micromamba Documentation](https://mamba.readthedocs.io/) -- [Wave Documentation](https://docs.seqera.io/platform-cloud/wave/) diff --git a/shiny-simple-example/app_plot_demo.R b/shiny-simple-example/app_plot_demo.R deleted file mode 100644 index b5073e1..0000000 --- a/shiny-simple-example/app_plot_demo.R +++ /dev/null @@ -1,227 +0,0 @@ -library(shiny) -library(ggplot2) -library(dplyr) - -# Define UI -ui <- fluidPage( - # Custom CSS for better styling - tags$head( - tags$style(HTML(" - body { background-color: #f5f5f5; } - .well { background-color: white; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } - .panel { border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } - .panel-heading { border-radius: 10px 10px 0 0; } - .btn-primary { background-color: #4a90e2; border-color: #4a90e2; } - .btn-primary:hover { background-color: #357abd; border-color: #357abd; } - ")) - ), - - # Title panel - titlePanel("Advanced Data Visualization"), - - # Sidebar layout - sidebarLayout( - sidebarPanel( - # Data source message at the top - div(style = "margin-bottom: 20px; padding: 10px; background-color: #e8f4f8; border-radius: 5px;", - textOutput("data_source") - ), - - # Plot type selection - selectInput("plot_type", "Select Plot Type:", - choices = c("Scatter Plot" = "scatter", - "Line Plot" = "line", - "Bar Plot" = "bar", - "Box Plot" = "box", - "Density Plot" = "density"), - selected = "scatter"), - - # Color theme selection - selectInput("color_theme", "Select Color Theme:", - choices = c("Default" = "default", - "Viridis" = "viridis", - "Brewer Blues" = "blues", - "Brewer Reds" = "reds"), - selected = "default"), - - # Additional controls based on plot type - conditionalPanel( - condition = "input.plot_type == 'scatter'", - sliderInput("point_size", "Point Size:", min = 1, max = 10, value = 3), - checkboxInput("add_trend", "Add Trend Line", value = TRUE) - ), - - conditionalPanel( - condition = "input.plot_type == 'line'", - sliderInput("line_width", "Line Width:", min = 0.5, max = 3, value = 1), - checkboxInput("add_points", "Add Points", value = TRUE) - ), - - conditionalPanel( - condition = "input.plot_type == 'bar'", - sliderInput("bar_width", "Bar Width:", min = 0.1, max = 1, value = 0.7), - checkboxInput("add_error_bars", "Add Error Bars", value = TRUE) - ), - - conditionalPanel( - condition = "input.plot_type == 'box'", - checkboxInput("add_points", "Add Points", value = TRUE), - checkboxInput("add_violin", "Add Violin Plot", value = FALSE) - ), - - conditionalPanel( - condition = "input.plot_type == 'density'", - sliderInput("bandwidth", "Bandwidth:", min = 0.1, max = 2, value = 0.5), - checkboxInput("add_rug", "Add Rug Plot", value = TRUE) - ), - - # Summary statistics panel - div(style = "margin-top: 20px;", - h4("Summary Statistics"), - verbatimTextOutput("summary_stats") - ) - ), - - # Main panel - mainPanel( - # Plot output - plotOutput("plot", height = "500px"), - - # Data table - div(style = "margin-top: 20px;", - h4("Data Table"), - dataTableOutput("data_table") - ) - ) - ) -) - -# Define server logic -server <- function(input, output, session) { - # Read data - data <- reactive({ - data_path <- Sys.getenv('DATA_PATH', 's3://shiny-inputs/data.csv') - - # Convert cloud storage path to local Studio path - if (grepl('^s3://|^gs://|^az://', data_path)) { - # Remove any cloud storage prefix and convert to local path - cloud_path <- sub('^[^:]+://', '', data_path) - bucket_name <- strsplit(cloud_path, '/')[[1]][1] - object_path <- sub(paste0('^', bucket_name, '/'), '', cloud_path) - file_path <- paste0('/workspace/data/', bucket_name, '/', object_path) - } else { - # Use path as-is for local paths - file_path <- data_path - } - - if (file.exists(file_path)) { - read.csv(file_path) - } else { - # Fallback to built-in data - data.frame( - x = 1:50, - y = rnorm(50, mean = 50, sd = 10) - ) - } - }) - - # Data source message - output$data_source <- renderText({ - data_path <- Sys.getenv('DATA_PATH', 's3://shiny-inputs/data.csv') - - # Convert cloud storage path to local Studio path (same logic as data reading) - if (grepl('^s3://|^gs://|^az://', data_path)) { - cloud_path <- sub('^[^:]+://', '', data_path) - bucket_name <- strsplit(cloud_path, '/')[[1]][1] - object_path <- sub(paste0('^', bucket_name, '/'), '', cloud_path) - file_path <- paste0('/workspace/data/', bucket_name, '/', object_path) - } else { - file_path <- data_path - } - - if (file.exists(file_path)) { - paste("Using external data file:", data_path) - } else { - "Using built-in random data" - } - }) - - # Summary statistics - output$summary_stats <- renderPrint({ - summary(data()$y) - }) - - # Create plot - output$plot <- renderPlot({ - df <- data() - - # Base plot - p <- ggplot(df, aes(x = x, y = y)) - - # Add plot elements based on selection - if (input$plot_type == "scatter") { - p <- p + geom_point(size = input$point_size, aes(color = "Data Points")) - if (input$add_trend) { - p <- p + geom_smooth(method = "lm", se = TRUE, aes(color = "Trend Line")) - } - } else if (input$plot_type == "line") { - p <- p + geom_line(size = input$line_width, aes(color = "Line")) - if (input$add_points) { - p <- p + geom_point(aes(color = "Points")) - } - } else if (input$plot_type == "bar") { - p <- p + geom_bar(stat = "identity", width = input$bar_width, aes(fill = "Bars")) - if (input$add_error_bars) { - p <- p + stat_summary(fun.data = mean_se, geom = "errorbar", width = 0.2, aes(color = "Error Bars")) - } - } else if (input$plot_type == "box") { - p <- p + geom_boxplot(aes(fill = "Box Plot")) - if (input$add_points) { - p <- p + geom_jitter(width = 0.2, aes(color = "Points")) - } - if (input$add_violin) { - p <- p + geom_violin(alpha = 0.3, aes(fill = "Violin")) - } - } else if (input$plot_type == "density") { - p <- p + geom_density(adjust = input$bandwidth, aes(fill = "Density")) - if (input$add_rug) { - p <- p + geom_rug(aes(color = "Rug")) - } - } - - # Apply color theme - if (input$color_theme == "viridis") { - p <- p + scale_color_viridis_d() + scale_fill_viridis_d() - } else if (input$color_theme == "blues") { - p <- p + scale_color_brewer(palette = "Blues") + scale_fill_brewer(palette = "Blues") - } else if (input$color_theme == "reds") { - p <- p + scale_color_brewer(palette = "Reds") + scale_fill_brewer(palette = "Reds") - } else { - # Default theme - p <- p + scale_color_brewer(palette = "Set1") + scale_fill_brewer(palette = "Set1") - } - - # Add labels and theme - p <- p + - labs(title = paste("Data Visualization:", input$plot_type), - x = "X", y = "Y") + - theme_minimal() + - theme( - plot.title = element_text(size = 16, face = "bold"), - axis.title = element_text(size = 12), - axis.text = element_text(size = 10), - panel.grid.major = element_line(color = "gray90"), - panel.grid.minor = element_line(color = "gray95") - ) - - p - }) - - # Data table - output$data_table <- renderDataTable({ - data() - }) -} - -# Run the app -shinyApp(ui = ui, server = server) \ No newline at end of file diff --git a/shiny-simple-example/data.csv b/shiny-simple-example/data.csv deleted file mode 100644 index 41295f1..0000000 --- a/shiny-simple-example/data.csv +++ /dev/null @@ -1,21 +0,0 @@ -x,y -1,45 -2,52 -3,48 -4,55 -5,51 -6,58 -7,54 -8,61 -9,57 -10,64 -11,60 -12,67 -13,63 -14,70 -15,66 -16,73 -17,69 -18,76 -19,72 -20,79 \ No newline at end of file diff --git a/shiny-simple-example/example_data.csv b/shiny-simple-example/example_data.csv deleted file mode 100644 index b0c7e1b..0000000 --- a/shiny-simple-example/example_data.csv +++ /dev/null @@ -1,11 +0,0 @@ -x,y -1,45.2 -2,52.8 -3,48.9 -4,55.1 -5,51.3 -6,53.7 -7,49.8 -8,54.2 -9,50.5 -10,52.1 \ No newline at end of file diff --git a/shiny-simple-example/screenshot.png b/shiny-simple-example/screenshot.png deleted file mode 100644 index 217a583..0000000 Binary files a/shiny-simple-example/screenshot.png and /dev/null differ diff --git a/streamlit/Dockerfile b/streamlit/Dockerfile deleted file mode 100644 index 8601b99..0000000 --- a/streamlit/Dockerfile +++ /dev/null @@ -1,60 +0,0 @@ -# --------------------------------------------------------------- -# 1) Multi-stage build: Pull the connect-client binary -# --------------------------------------------------------------- -ARG CONNECT_CLIENT_VERSION=0.9 -FROM public.cr.seqera.io/platform/connect-client:${CONNECT_CLIENT_VERSION} AS connect - -# --------------------------------------------------------------- -# 2) Additional base image for Streamlit -# --------------------------------------------------------------- -FROM python:3.11-slim - -# Just for the automation at Seqera -LABEL org.opencontainers.image.source="https://github.com/seqeralabs/custom-studios-examples" - -WORKDIR /app - -RUN apt-get update && apt-get install -y \ - build-essential \ - curl \ - git \ - && rm -rf /var/lib/apt/lists/* - -# Remove any existing directory and clone fresh -RUN rm -rf /app/* && git clone https://github.com/MultiQC/example-streamlit . - -RUN pip3 install -r requirements.txt - -EXPOSE $CONNECT_TOOL_PORT - -# Add connect-client version label to image for supported capabilties tracking -ARG CONNECT_CLIENT_VERSION -LABEL io.seqera.connect.version="${CONNECT_CLIENT_VERSION}" - -# Copy connect-client from the first stage -COPY --from=connect /usr/bin/connect-client /usr/bin/connect-client - -# "Install" connect-client (sets up any needed config) -RUN /usr/bin/connect-client --install - -# --------------------------------------------------------------- -# 3) Launch with connect-client --entrypoint (for Tower) -# --------------------------------------------------------------- -ENTRYPOINT ["/usr/bin/connect-client", "--entrypoint"] - -# Add backports repository and install specific btrfs-progs version -RUN echo "deb http://deb.debian.org/debian bookworm-backports main contrib non-free-firmware" | tee -a /etc/apt/sources.list && \ - apt-get update && \ - apt-get install -y --allow-downgrades btrfs-progs=6.14-1~bpo12+1 - -# --------------------------------------------------------------- -# 4) Command: Run Streamlit MultiQC application -# --------------------------------------------------------------- -# The port is set by CONNECT_TOOL_PORT environment variable -CMD streamlit run /app/multiqc_app.py \ - --server.port=$CONNECT_TOOL_PORT \ - --server.address=0.0.0.0 \ - --server.enableCORS=false \ - --server.enableXsrfProtection=false \ - --server.enableWebsocketCompression=false \ - --browser.gatherUsageStats=false \ No newline at end of file diff --git a/streamlit/README.md b/streamlit/README.md deleted file mode 100644 index 0496720..0000000 --- a/streamlit/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# Streamlit Studio Environment - -This example provides a custom container image for running a [Streamlit](https://streamlit.io/) application with MultiQC visualization in Seqera Platform. - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Files](#files) -- [Prerequisites](#prerequisites) -- [Building the Container](#building-the-container) -- [Local Testing](#local-testing) -- [Using in Seqera Studios](#using-in-seqera-studios) -- [Notes](#notes) -- [References](#references) - -## Overview - -This container is designed for use as a [custom Studio environment](https://docs.seqera.io/platform-cloud/studios/custom-envs) in Seqera Platform. It provides an interactive interface for visualizing MultiQC data using Streamlit. - -![Screenshot of the Streamlit app](screenshot.png) - -## Docker Image - -The container image is available at: -``` -ghcr.io/seqeralabs/custom-studios-examples/streamlit:latest -``` - -For specific versions, use the release tag (e.g., `ghcr.io/seqeralabs/custom-studios-examples/streamlit:v1.0.0`). - -## Features - -- Streamlit-based MultiQC visualization platform -- Interactive data analysis and visualization -- Compatible with both local Docker testing and Seqera Studios -- Automatic data mounting via datalinks -- Python 3.11-based environment - -## Files - -- `Dockerfile`: Container definition using multi-stage build that clones the MultiQC example repository and its dependencies - -## Prerequisites - -- [Docker](https://www.docker.com/) installed -- [Wave](https://docs.seqera.io/platform-cloud/wave/) configured in your Seqera Platform workspace -- Access to a container registry (public or Amazon ECR) if you wish to push your image -- MultiQC data files for visualization - -## Building the Container - -> [!IMPORTANT] -> You must provide the `CONNECT_CLIENT_VERSION` build argument when building the container. - -To build the container locally: - -```bash -docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.8 -t streamlit-example . -``` - -## Local Testing - -To test the app locally, you need to override the entrypoint: - -```bash -docker run -p 3000:3000 --entrypoint streamlit streamlit-example run /app/multiqc_app.py \ - --server.port=3000 \ - --server.address=0.0.0.0 \ - --server.enableCORS=false \ - --server.enableXsrfProtection=false \ - --server.enableWebsocketCompression=false \ - --browser.gatherUsageStats=false -``` - -The app will be available at http://localhost:3000 - -## Using in Seqera Studios - -> [!NOTE] -> For the common deployment process, see the [main README](../README.md#deploying-to-seqera-studios). - -Additional steps specific to this example: -1. Follow the common deployment process -2. When mounting data, ensure to mount the directories containing any required MultiQC data files using the **Mount data** option - -### Data Loading Options - -The MultiQC Streamlit app supports three data loading methods: -- **URL**: Load data directly from a web URL -- **Local Files**: Access files from your local machine -- **Server Paths**: Load files from S3 via Fusion - -When using Server Paths with data links: -1. Upload your MultiQC data (e.g., `data.zip`) to your S3 bucket -2. Create a data link (e.g., `my_multiqc_files`) pointing to that S3 path -3. The data will be available at `/workspace/data/my_multiqc_files/data.zip` -4. Use this path in the app's "Server Path" input field - -## Notes - -- The app uses Streamlit for interactive data visualization -- The Dockerfile uses a multi-stage build to include the connect-client -- The container is built for linux/amd64 platform compatibility -- The example is based on the MultiQC Streamlit application -- The container uses Python 3.11 as the base image - -## References - -- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) -- [Streamlit Documentation](https://docs.streamlit.io/) -- [MultiQC Documentation](https://multiqc.info/) -- [Wave Documentation](https://docs.seqera.io/platform-cloud/wave/) \ No newline at end of file diff --git a/streamlit/screenshot.png b/streamlit/screenshot.png deleted file mode 100644 index f2842a9..0000000 Binary files a/streamlit/screenshot.png and /dev/null differ diff --git a/ttyd/Dockerfile b/ttyd/Dockerfile deleted file mode 100644 index 2674505..0000000 --- a/ttyd/Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -# --------------------------------------------------------------- -# 1) Multi-stage build: Pull the connect-client binary -# --------------------------------------------------------------- -ARG CONNECT_CLIENT_VERSION=0.9 -FROM public.cr.seqera.io/platform/connect-client:${CONNECT_CLIENT_VERSION} AS connect - -# Final image: Start from an arbitrary container -FROM community.wave.seqera.io/library/samtools:1.21--0d76da7c3cf7751c - -# Just for the automation at Seqera -LABEL org.opencontainers.image.source="https://github.com/seqeralabs/custom-studios-examples" - -# Set environment variables to prevent interactive prompts -ENV DEBIAN_FRONTEND=noninteractive -ENV TERM=xterm - -# Install extra dependencies and tools -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - wget \ - ca-certificates && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -# Install TTYD binary -RUN wget https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.x86_64 \ - && mv ttyd.x86_64 /usr/local/bin/ttyd \ - && chmod +x /usr/local/bin/ttyd - -# Add connect-client version label to image for supported capabilties tracking -ARG CONNECT_CLIENT_VERSION -LABEL io.seqera.connect.version="${CONNECT_CLIENT_VERSION}" - -# Copy Connect binary and install dependencies -COPY --from=connect /usr/bin/connect-client /usr/bin/connect-client -RUN /usr/bin/connect-client --install - -# Set connect as the entrypoint -ENTRYPOINT ["/usr/bin/connect-client", "--entrypoint"] - -# Default command to run TTYD with writable mode -CMD ["/usr/bin/bash", "-c", "ttyd -W -p $CONNECT_TOOL_PORT bash"] \ No newline at end of file diff --git a/ttyd/README.md b/ttyd/README.md deleted file mode 100644 index 438bbb6..0000000 --- a/ttyd/README.md +++ /dev/null @@ -1,100 +0,0 @@ -# TTYD Studio Environment - -This example provides a custom container image for running an interactive terminal session in Seqera Studios using [TTYD](https://github.com/tsl0922/ttyd). It uses a commodity [SAMtools](https://www.htslib.org/) image from [Seqera containers](https://github.com/seqeralabs/containers) (built using the [Bioconda](https://bioconda.github.io/) SAMtools recipe) as the base, demonstrating how Studios can run arbitrary container images. - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Files](#files) -- [Prerequisites](#prerequisites) -- [Building the Container](#building-the-container) -- [Local Testing](#local-testing) -- [Using in Seqera Studios](#using-in-seqera-studios) -- [Notes](#notes) -- [References](#references) - -## Overview - -This container is designed for use as a [custom Studio environment](https://docs.seqera.io/platform-cloud/studios/custom-envs) in Seqera Platform. It provides a web-based terminal interface with full write permissions and access to bioinformatics tools. - -![Screenshot of TTYD terminal](screenshot.png) - -## Docker Image - -The container image is available at: -``` -ghcr.io/seqeralabs/custom-studios-examples/ttyd:latest -``` - -For specific versions, use the release tag (e.g., `ghcr.io/seqeralabs/custom-studios-examples/ttyd:v1.0.0`). - -## Features - -- Interactive web-based terminal using TTYD 1.7.7 -- Based on [SAMtools](https://www.htslib.org/) 1.21 container from [Seqera containers](https://github.com/seqeralabs/containers) -- Full terminal access with write permissions -- Includes basic bioinformatics tools from [SAMtools](https://www.htslib.org/) via [Bioconda](https://bioconda.github.io/) - -> [!NOTE] -> For common features shared across all examples, see the [main README](../README.md#common-features). - -## Files - -- `Dockerfile`: Container definition using multi-stage build - -## Prerequisites - -> [!NOTE] -> For common prerequisites, see the [main README](../README.md#prerequisites). - -No additional prerequisites specific to this example. - -## Building the Container - -> [!IMPORTANT] -> You must provide the `CONNECT_CLIENT_VERSION` build argument when building the container. - -To build the container locally: - -```bash -docker build --platform=linux/amd64 --build-arg CONNECT_CLIENT_VERSION=0.8 -t ttyd-example . -``` - -## Local Testing - -To test the terminal locally, you need to override the entrypoint: - -```bash -docker run -p 3000:3000 --entrypoint ttyd ttyd-example -W -p 3000 bash -``` - -The terminal will be available at http://localhost:3000 - -## Using in Seqera Studios - -> [!NOTE] -> For the common deployment process, see the [main README](../README.md#deploying-to-seqera-studios). - -Additional steps specific to this example: -1. Follow the common deployment process -2. The terminal will automatically use the `CONNECT_TOOL_PORT` environment variable in Studios - -## Notes - -- The terminal uses TTYD 1.7.7 for web-based terminal access -- The terminal runs with write permissions enabled (-W flag) -- The base image includes SAMtools 1.21 and other bioinformatics tools -- The port is automatically configured via the CONNECT_TOOL_PORT environment variable in Studios - -> [!NOTE] -> For common technical notes, see the [main README](../README.md#common-features). - -## References - -- [TTYD Documentation](https://github.com/tsl0922/ttyd) -- [SAMtools Documentation](https://www.htslib.org/) -- [Seqera Containers](https://github.com/seqeralabs/containers) -- [Bioconda Documentation](https://bioconda.github.io/) -- [Seqera Studios: Custom Environments](https://docs.seqera.io/platform-cloud/studios/custom-envs) -- [Wave Documentation](https://docs.seqera.io/platform-cloud/wave/) diff --git a/ttyd/screenshot.png b/ttyd/screenshot.png deleted file mode 100644 index 1382f3e..0000000 Binary files a/ttyd/screenshot.png and /dev/null differ