Skip to content

add terminal-based dev environment as alternative to devcontainers#361

Merged
arnaudbore merged 8 commits into
nf-neuro:mainfrom
CMonnin:feat/podman-dev-env
May 28, 2026
Merged

add terminal-based dev environment as alternative to devcontainers#361
arnaudbore merged 8 commits into
nf-neuro:mainfrom
CMonnin:feat/podman-dev-env

Conversation

@CMonnin
Copy link
Copy Markdown
Contributor

@CMonnin CMonnin commented May 6, 2026

Describe your improvement

Adds a podman + apptainer dev environment as an editor-agnostic alternative to the existing VSCode devcontainers. This lets contributors who don't use VSCode (e.g. nvim, Emacs, etc.) get the same reproducible tooling without needing Docker or the devcontainer CLI.

Existing .devcontainer/ configs are unchanged.

Two flavors matching the existing devcontainer structure:

  • prototyping: scilus/scilus:2.0.2 base with nextflow, nf-test, poetry 1.8.5, apptainer, and gh CLI
  • devops: python:3.13-slim base with nextflow, nf-test, poetry 2.0.1, apptainer, gh CLI, node 20, act, actionlint, shellcheck, prettier, and editorconfig-checker

Launcher script (.dev/dev) builds and runs the selected flavor with podman, bind-mounting the repo at /workspace. Named volumes persist .venv, .cache, and .nextflow across sessions. Supports extra bind mounts via -v flags for working with external dirs.

Usage

.dev/dev                          # prototyping (default)
.dev/dev devops                   # devops flavor
.dev/dev -v /path:/path bash      # mount extra directories

Note: The dev launcher script is podman-specific (uses --userns=keep-id and :U volume flags). The Dockerfiles are standard and can be built and run with any container runtime
(Docker, podman, etc.).

Note: When running nf-test inside the container, use --profile apptainer,devcontainer instead of the default docker profile (e.g. nf-test test --profile
apptainer,devcontainer).

Type of improvement

  • Development container
  • Development tools

Describe how to test your improvement

  1. Install podman on the host if not already present
  2. Run .dev/dev from the repo root — it should build the prototyping image and drop into a bash shell
  3. Inside the container, verify tools: nf-test version && nextflow -version && poetry --version && gh --version
  4. Run .dev/dev devops and verify: nf-test version && nextflow -version && poetry --version && act --version && actionlint --version && node --version && prettier --version
  5. Test apptainer execution: nf-test test <module_test_path> --profile apptainer,devcontainer
  6. Test extra volume mounts: .dev/dev -v /tmp:/tmp and verify /tmp is accessible inside the container
  7. Confirm .devcontainer/ is untouched and still works for VSCode users

Checklist before requesting a review

  • Ensure the syntax is correct (EditorConfig and Prettier must pass) — N/A, only Dockerfiles and shell script
  • Run the test suites if your changes affect any module — no module changes
  • Regenerate the Poetry lock file if you have updated the dependencies — no dependency changes
  • Ensure the documentation is up-to-date — usage documented in PR description

Tested and working on Void Linux (kernel 6.18 and kernel 7.03) with rootless podman. Other distros may need adjustments.

Editor-agnostic setup using rootless podman + apptainer, replacing
VSCode devcontainers + Docker-in-Docker. Existing .devcontainer/
configs are unchanged.

Two flavors matching the existing devcontainer structure:
- prototyping: scilus/scilus:2.0.2 base with nextflow, nf-test,
  poetry 1.8.5, apptainer, and gh CLI
- devops: python:3.13-slim base with nextflow, nf-test,
  poetry 2.0.1, apptainer, gh CLI, node 20, act, actionlint,
  shellcheck, prettier, and editorconfig-checker

Launcher script (.dev/dev) builds and runs the selected flavor
with podman, bind-mounting the repo at /workspace. Named volumes
persist .venv, .cache, and .nextflow across sessions. Supports
extra bind mounts via -v flags for working with external dirs.

Usage:
  .dev/dev                          # prototyping (default)
  .dev/dev devops                   # devops flavor
  .dev/dev -v /path:/path bash      # mount extra directories

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@CMonnin
Copy link
Copy Markdown
Contributor Author

CMonnin commented May 6, 2026

not sure if there's any interest in this but i don't use vscode or devcontainers so this is an alternative

@CMonnin CMonnin marked this pull request as ready for review May 7, 2026 16:50
@CMonnin CMonnin requested a review from a team May 7, 2026 16:50
@arnaudbore
Copy link
Copy Markdown
Contributor

@CMonnin

Please advise :)

$ ./.dev/dev
STEP 1/23: FROM scilus/scilus:2.0.2
Error: error creating build container: short-name "scilus/scilus:2.0.2" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

Is there a way to get as much common building info as possible at the same place instead of duplicating code ?

@CMonnin
Copy link
Copy Markdown
Contributor Author

CMonnin commented May 11, 2026

@CMonnin

Please advise :)

$ ./.dev/dev
STEP 1/23: FROM scilus/scilus:2.0.2
Error: error creating build container: short-name "scilus/scilus:2.0.2" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

Is there a way to get as much common building info as possible at the same place instead of duplicating code ?

do you mean between the devcontainers and these separate dockerfiles?

@CMonnin
Copy link
Copy Markdown
Contributor Author

CMonnin commented May 12, 2026

nf version needs to be moved to 25 to match CI

@arnaudbore arnaudbore requested a review from gdevenyi May 14, 2026 13:09
@gdevenyi
Copy link
Copy Markdown
Contributor

I think this PR should include some documentation updates on how this tool is intended to be used for development.

@AlexVCaron
Copy link
Copy Markdown
Contributor

I think this PR should include some documentation updates on how this tool is intended to be used for development.

Yes, once it works, some upgrades to the installation procedures on nf-neuro-documentation will need to be done.

@gdevenyi
Copy link
Copy Markdown
Contributor

nf-test test fails in the container on every step:

  Command error:
    .command.run: line 298: docker: command not found

@gdevenyi
Copy link
Copy Markdown
Contributor

Tests working with nf-test test --profile apptainer,devcontainer

Copy link
Copy Markdown
Contributor

@gdevenyi gdevenyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs docs on how to use.

Comment thread .dev/devops/Dockerfile Outdated
gnupg \
jq \
openjdk-17-jre \
pipx \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swap for uv?

Comment thread .dev/devops/Dockerfile Outdated
&& mv nf-test /home/${USERNAME}/.local/bin/nf-test \
&& chmod +x /home/${USERNAME}/.local/bin/nf-test

RUN pipx install poetry==${POETRY_VERSION}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uv tool install?

Comment thread .dev/prototyping/Dockerfile Outdated
&& chmod 0755 /usr/local/bin/nextflow

# pipx (system-wide) so the dev user can install poetry into ~/.local
RUN python3 -m pip install --no-cache-dir pipx
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uv?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to add pipx to apt-get install above in 2.2.2 for it to work, still prefer uv

Comment thread .dev/prototyping/Dockerfile Outdated
Comment on lines +42 to +47
RUN ARCH="$(dpkg --print-architecture)" \
&& curl -fsSL -o /tmp/apptainer.deb \
"https://github.com/apptainer/apptainer/releases/download/v${APPTAINER_VERSION}/apptainer_${APPTAINER_VERSION}_${ARCH}.deb" \
&& apt-get update \
&& apt-get install -y --no-install-recommends /tmp/apptainer.deb \
&& rm -rf /var/lib/apt/lists/* /tmp/apptainer.deb
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread .dev/devops/Dockerfile Outdated
Comment on lines +57 to +63
# Apptainer (replaces ghcr.io/devcontainers/features/docker-in-docker)
RUN ARCH="$(dpkg --print-architecture)" \
&& curl -fsSL -o /tmp/apptainer.deb \
"https://github.com/apptainer/apptainer/releases/download/v${APPTAINER_VERSION}/apptainer_${APPTAINER_VERSION}_${ARCH}.deb" \
&& apt-get update \
&& apt-get install -y --no-install-recommends /tmp/apptainer.deb \
&& rm -rf /var/lib/apt/lists/* /tmp/apptainer.deb
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apptainer has a ppa apptainer.org/docs/admin/latest/installation.html#install-ubuntu-packages

Comment thread .dev/devops/Dockerfile Outdated
@@ -0,0 +1,96 @@
FROM docker.io/python:3.13-slim-bookworm
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most likely user for nf-neuro is ubuntu, it probably makes more sense to base the test environments on it?

Comment thread .dev/prototyping/Dockerfile Outdated
&& mv nf-test /home/${USERNAME}/.local/bin/nf-test \
&& chmod +x /home/${USERNAME}/.local/bin/nf-test

RUN pipx install poetry==${POETRY_VERSION}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uv?

Comment thread .dev/prototyping/Dockerfile Outdated
@@ -0,0 +1,78 @@
FROM docker.io/scilus/scilus:2.0.2
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very out of date, should be 2.2.2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swapping to 2.2.2 causes this build error, good reason for uv

--> f33d5b5fdabb
STEP 14/23: RUN python3 -m pip install --no-cache-dir pipx
/opt/venvs/scilpy/bin/python3: No module named pip
Error: building at STEP "RUN python3 -m pip install --no-cache-dir pipx": while running runtime: exit status 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another bug on bump:

--> 65374466aed4
STEP 14/22: RUN groupadd --gid ${USER_GID} ${USERNAME}     && useradd --uid ${USER_UID} --gid ${USER_GID} -m -s /bin/bash ${USERNAME}     && echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME}     && chmod 0440 /etc/sudoers.d/${USERNAME}
groupadd: GID '1000' already exists
Error: building at STEP "RUN groupadd --gid ${USER_GID} ${USERNAME}     && useradd --uid ${USER_UID} --gid ${USER_GID} -m -s /bin/bash ${USERNAME}     && echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME}     && chmod 0440 /etc/sudoers.d/${USERNAME}": while running runtime: exit status 4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default user is ubuntu and already present in the container now

Comment thread .dev/prototyping/Dockerfile Outdated
sudo \
tmux \
vim \
wget \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for both wget and curl

Comment thread .dev/devops/Dockerfile Outdated
shellcheck \
sudo \
tmux \
wget \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for both wget and curl

Comment thread .dev/prototyping/Dockerfile Outdated
# Nextflow (was ghcr.io/robsyme/features/nextflow)
RUN curl -fsSL https://get.nextflow.io | NXF_VER=${NEXTFLOW_VERSION} bash \
&& mv nextflow /usr/local/bin/nextflow \
&& chmod 0755 /usr/local/bin/nextflow
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are modern people, chmod has symbolic permissions mode

Comment thread .dev/prototyping/Dockerfile Outdated
Comment on lines +57 to +61
# Non-root user matching host UID (used with --userns=keep-id at runtime)
RUN groupadd --gid ${USER_GID} ${USERNAME} \
&& useradd --uid ${USER_UID} --gid ${USER_GID} -m -s /bin/bash ${USERNAME} \
&& echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} \
&& chmod 0440 /etc/sudoers.d/${USERNAME}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed for 2.2.2, just switch user to ubuntu

Comment thread .dev/prototyping/Dockerfile Outdated
ARG NFTEST_VERSION=0.9.3
ARG APPTAINER_VERSION=1.4.1
ARG POETRY_VERSION=1.8.5
ARG USERNAME=dev
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switch to ubuntu for 2.2.2

- Base image scilus/scilus:2.0.2 → 2.2.2
- Use built-in ubuntu user (no more user creation)
- Replace pipx/poetry with uv (COPY --from ghcr.io/astral-sh/uv)
- Install apptainer via PPA instead of .deb download
- Remove wget, python3-pip, python3-venv
- Bump Nextflow 24.10.5 → 25.04.6 to match CI
- Use symbolic chmod

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CMonnin and others added 3 commits May 15, 2026 15:35
- Base image python:3.13-slim-bookworm → ubuntu:24.04
- Use built-in ubuntu user (usermod for groups only)
- Replace pipx/poetry with uv (COPY --from ghcr.io/astral-sh/uv)
- Install apptainer via PPA instead of .deb download
- Remove wget, use openjdk-17-jre-headless (smaller)
- Bump Nextflow 24.10.5 → 25.04.6 to match CI
- Use symbolic chmod

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@CMonnin CMonnin changed the title add podman-based dev environment as alternative to devcontainers add terminal-based dev environment as alternative to devcontainers May 15, 2026
@arnaudbore
Copy link
Copy Markdown
Contributor

It looks amazing. Great work !

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a terminal/editor-agnostic container dev environment under .dev/ as an alternative to the existing VS Code .devcontainer/ setup, aiming to provide reproducible tooling via Podman + Apptainer without requiring the devcontainer CLI.

Changes:

  • Added a Podman-based launcher script (.dev/dev) to build/run a selected dev “flavor” and persist caches/venvs via named volumes.
  • Added two new Dockerfile-based environments (.dev/prototyping/ and .dev/devops/) with Nextflow, nf-test, Apptainer, GitHub CLI, and additional CI tooling for devops.
  • Added .dev/README.md documenting usage and manual build steps.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
.dev/README.md Documents the new container-based dev environment and how to use it.
.dev/prototyping/Dockerfile Defines the “prototyping” container image with Nextflow/nf-test/Apptainer tooling.
.dev/devops/Dockerfile Defines the “devops” container image with additional CI/dev tooling (node/act/actionlint/etc.).
.dev/dev Podman launcher script to build/run the chosen flavor with persistent volumes and optional extra mounts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .dev/devops/Dockerfile
Comment on lines +61 to +73
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

RUN usermod -aG nodeusers ubuntu \
&& echo "ubuntu ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ubuntu \
&& chmod u=r,g=r /etc/sudoers.d/ubuntu \
&& echo "prefix=/usr/local" >> /home/ubuntu/.npmrc

ENV PATH="/home/ubuntu/.local/bin:${PATH}"
ENV NXF_APPTAINER_CACHEDIR=/home/ubuntu/.cache/apptainer

USER ubuntu
WORKDIR /home/ubuntu

Comment thread .dev/dev
Comment on lines +13 to +18
volumes=()
while [[ ${1:-} == -v ]]; do
shift
volumes+=(-v "$1")
shift
done
Comment thread .dev/README.md
## Installing Dependencies

```bash
uv sync --no-install-project
Comment on lines +41 to +42
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

Comment thread .dev/devops/Dockerfile
Comment on lines +60 to +62

COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

Comment thread .dev/devops/Dockerfile
Comment on lines +1 to +7
FROM docker.io/ubuntu:24.04

ARG NODE_MAJOR=20
ARG ACTIONLINT_VERSION=1.7.7
ARG NEXTFLOW_VERSION=25.04.6
ARG NFTEST_VERSION=0.9.3

@gdevenyi
Copy link
Copy Markdown
Contributor

None of these co-pilot reviews are relevant, updated model works for me.

@gdevenyi
Copy link
Copy Markdown
Contributor

Can this be merged? I'd like to use it to advance my registration too integration.

@arnaudbore arnaudbore enabled auto-merge May 28, 2026 14:34
@arnaudbore arnaudbore added this pull request to the merge queue May 28, 2026
Merged via the queue into nf-neuro:main with commit cc927b4 May 28, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants