Skip to content

Commit f673eaf

Browse files
authored
Merge pull request #1730 from jdkent/code_server
[ENH] Set up code-server docker recipe for interactive development
2 parents 3260f82 + 5cda88a commit f673eaf

File tree

6 files changed

+283
-6
lines changed

6 files changed

+283
-6
lines changed

.circleci/config.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ jobs:
6767
--build-arg VERSION="${CIRCLE_TAG:-$THISVERSION}" . \
6868
&& e=0 && break || sleep 15
6969
done && [ "$e" -eq "0" ]
70+
# test if development image should be built
71+
if [[ "$( git log --format=oneline -n 1 $CIRCLE_SHA1 | grep -i -E '\[build[ _]?devel\]' )" != "" ]]; then
72+
echo "building development container"
73+
docker tag poldracklab/fmriprep poldracklab/fmriprep:unstable
74+
docker build \
75+
--rm=false \
76+
-t poldracklab/fmriprep_devel \
77+
-f Dockerfile_devel .
78+
fi
7079
- run:
7180
name: Smoke test Docker image
7281
command: |

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,6 @@ target/
6969
# pycharm project settings
7070
.idea
7171

72-
# vscode project settings
73-
.vscode
74-
7572
# Spyder project settings
7673
.spyderproject
7774
.spyproject

.vscode/launch.json

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
8+
{
9+
"name": "ds005-anat",
10+
"type": "python",
11+
"request": "launch",
12+
"program": "/usr/local/miniconda/bin/fmriprep",
13+
"args": [
14+
"-w", "/tmp/ds005/work",
15+
"/tmp/data/ds005",
16+
"/tmp/ds005/derivatives",
17+
"participant",
18+
"--skull-strip-template", "OASIS30ANTs:res-1",
19+
"--output-spaces", "MNI152NLin2009cAsym", "MNI152NLin6Asym",
20+
"--sloppy", "--write-graph",
21+
"--anat-only", "-vv", "--notrack"
22+
],
23+
"console": "integratedTerminal",
24+
"justMyCode": false
25+
},
26+
{
27+
"name": "ds005-full",
28+
"type": "python",
29+
"request": "launch",
30+
"program": "/usr/local/miniconda/bin/fmriprep",
31+
"args": [
32+
"-w", "/tmp/ds005/work",
33+
"/tmp/data/ds005",
34+
"/tmp/ds005/derivatives",
35+
"participant",
36+
"--sloppy", "--write-graph",
37+
"--use-aroma",
38+
"--skull-strip-template", "OASIS30ANTs:res-1",
39+
"--output-space", "T1w", "template", "fsaverage5", "fsnative",
40+
"--template-resampling-grid", "native",
41+
"--use-plugin", "/src/fmriprep/.circleci/legacy.yml",
42+
"--cifti-output", "-vv", "--notrack"
43+
],
44+
"console": "integratedTerminal",
45+
"justMyCode": false
46+
},
47+
{
48+
"name": "ds054",
49+
"type": "python",
50+
"request": "launch",
51+
"program": "/usr/local/miniconda/bin/fmriprep",
52+
"args": [
53+
"-w", "/tmp/ds054/work",
54+
"/tmp/data/ds054",
55+
"/tmp/ds054/derivatives",
56+
"participant",
57+
"--fs-no-reconall", "--sloppy",
58+
"--output-spaces", "MNI152NLin2009cAsym:res-2", "anat", "func",
59+
"-vv",
60+
"--notrack"
61+
],
62+
"console": "integratedTerminal",
63+
"justMyCode": false
64+
},
65+
{
66+
"name": "ds210-anat",
67+
"type": "python",
68+
"request": "launch",
69+
"program": "/usr/local/miniconda/bin/fmriprep",
70+
"args": [
71+
"-w", "/tmp/ds210/work",
72+
"/tmp/data/ds210",
73+
"/tmp/ds210/derivatives",
74+
"participant",
75+
"--fs-no-reconall", "--sloppy", "--write-graph",
76+
"--anat-only", "-vv", "--notrack"
77+
],
78+
"console": "integratedTerminal",
79+
"justMyCode": false
80+
},
81+
{
82+
"name": "ds210-full",
83+
"type": "python",
84+
"request": "launch",
85+
"program": "/usr/local/miniconda/bin/fmriprep",
86+
"args": [
87+
"-w", "/tmp/ds210/work",
88+
"/tmp/data/ds210",
89+
"/tmp/ds210/derivatives",
90+
"participant",
91+
"--t2s-coreg", "--use-syn-sdc",
92+
"--template-resampling-grid", "native",
93+
"--dummy-scans", "1",
94+
"--fs-no-reconall", "--sloppy", "--write-graph",
95+
"--anat-only", "-vv", "--notrack"
96+
],
97+
"console": "integratedTerminal",
98+
"justMyCode": false
99+
}
100+
]
101+
}

.vscode/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"python.linting.flake8Enabled": true,
3+
"python.pythonPath": "/usr/local/miniconda/bin/python",
4+
"restructuredtext.confPath": "${workspaceFolder}/docs",
5+
"python.testing.pytestEnabled": true,
6+
"python.testing.unittestEnabled": false,
7+
"python.testing.nosetestsEnabled": false,
8+
"python.linting.enabled": true,
9+
"python.testing.pytestArgs": [],
10+
"python.linting.pylintEnabled": false
11+
}

Dockerfile_devel

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
FROM poldracklab/fmriprep:unstable
2+
3+
# net-tools needed for code-server
4+
# wget necessary for data downloads
5+
RUN apt-get update &&\
6+
apt-get install -y \
7+
net-tools \
8+
wget
9+
10+
# necessary to find fmriprep in /src/fmriprep
11+
ENV PYTHONNOUSERSITE=0
12+
13+
RUN cd /src/fmriprep &&\
14+
pip install --no-use-pep517 -e .[all] &&\
15+
cp -R /src/fmriprep/fmriprep.egg-info /src/
16+
17+
# create freesurfer license
18+
RUN cd /tmp &&\
19+
echo 'cHJpbnRmICJrcnp5c3p0b2YuZ29yZ29sZXdza2lAZ21haWwuY29tXG41MTcyXG4gKkN2dW12RVYzelRmZ1xuRlM1Si8yYzFhZ2c0RVxuIiA+IGxpY2Vuc2UudHh0Cg==' | base64 -d | sh
20+
21+
ENV FS_LICENSE=/tmp/license.txt
22+
23+
# set the fmriprep development variables
24+
ENV FMRIPREP_REGRESSION_SOURCE=/tmp/data/fmriprep_bold_truncated \
25+
FMRIPREP_REGRESSION_TARGETS=/tmp/data/fmriprep_bold_mask \
26+
FMRIPREP_REGRESSION_REPORTS=/tmp/data/reports \
27+
FMRIPREP_DEV=1
28+
29+
# use flake8 as linter
30+
RUN conda install -y flake8
31+
32+
RUN mkdir -p /tmp/data
33+
34+
# Download ds005
35+
RUN wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
36+
-O ds005_downsampled.tar.gz "https://files.osf.io/v1/resources/fvuh8/providers/osfstorage/57f32a429ad5a101f977eb75" &&\
37+
tar xvzf ds005_downsampled.tar.gz -C /tmp/data/ &&\
38+
rm ds005_downsampled.tar.gz
39+
40+
# Download ds210
41+
RUN wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
42+
-O ds210_downsampled.tar.gz "https://files.osf.io/v1/resources/fvuh8/providers/osfstorage/5ae9e37b9a64d7000ce66c21" &&\
43+
tar xvzf ds210_downsampled.tar.gz -C /tmp/data &&\
44+
rm ds210_downsampled.tar.gz
45+
46+
# Download ds054
47+
RUN wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
48+
-O ds054_downsampled.tar.gz "https://files.osf.io/v1/resources/fvuh8/providers/osfstorage/57f32c22594d9001ef91bf9e" &&\
49+
tar xvzf ds054_downsampled.tar.gz -C /tmp/data &&\
50+
rm ds054_downsampled.tar.gz
51+
52+
# Download freesurfer results for ds005
53+
RUN mkdir -p /tmp/ds005/derivatives &&\
54+
wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
55+
-O ds005_derivatives_freesurfer.tar.gz "https://files.osf.io/v1/resources/fvuh8/providers/osfstorage/58fe59eb594d900250960180" &&\
56+
tar xvzf ds005_derivatives_freesurfer.tar.gz -C /tmp/ds005/derivatives &&\
57+
rm ds005_derivatives_freesurfer.tar.gz
58+
59+
# Download truncated bold images
60+
RUN wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
61+
-O fmriprep_bold_truncated.tar.gz "https://osf.io/286yr/download" &&\
62+
tar xvzf fmriprep_bold_truncated.tar.gz -C /tmp/data &&\
63+
rm fmriprep_bold_truncated.tar.gz
64+
65+
# Download precomputed masks
66+
RUN wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
67+
-O fmriprep_bold_mask.tar.gz "https://osf.io/s4f7b/download" &&\
68+
tar xvzf fmriprep_bold_mask.tar.gz -C /tmp/data &&\
69+
rm fmriprep_bold_mask.tar.gz
70+
71+
# set up code-server (need net-tools for initialization)
72+
RUN curl -o /tmp/code-server.tar.gz -SL https://github.com/cdr/code-server/releases/download/2.preview.9-vsc1.37.0/code-server2.preview.9-vsc1.37.0-linux-x86_64.tar.gz
73+
74+
RUN mkdir /src/codeserver &&\
75+
tar -xvf /tmp/code-server.tar.gz -C /src/codeserver --strip-components=1
76+
77+
RUN /src/codeserver/code-server --install-extension eamodio.gitlens &&\
78+
/src/codeserver/code-server --install-extension ms-python.python
79+
80+
81+
ENTRYPOINT ["/src/codeserver/code-server", "/src/fmriprep"]
82+
83+
# usage example (assuming in local fmriprep directory):
84+
#
85+
# docker run -it \
86+
# -p 127.0.0.1:8445:8080 \
87+
# -v ${PWD}:/src/fmriprep \
88+
# fmriprep_devel:latest
89+
#
90+
# then type 127.0.0.1:8445 in your browser address bar

docs/contributors.rst

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ update an existing environment, as necessary.
99

1010
Development in Docker is encouraged, for the sake of consistency and
1111
portability.
12-
By default, work should be built off of `poldracklab/fmriprep:latest
13-
<https://hub.docker.com/r/poldracklab/fmriprep/>`_ (see the
12+
By default, work should be built off of `poldracklab/fmriprep:unstable
13+
<https://hub.docker.com/r/poldracklab/fmriprep/>`_, which tracks the ``master`` branch,
14+
or ``poldracklab/fmriprep:latest``, which tracks the latest release version (see the
1415
installation_ guide for the basic procedure for running).
1516

1617
It will be assumed the developer has a working repository in
@@ -130,6 +131,74 @@ This image may be accessed by the `fmriprep-docker`_ wrapper via the
130131

131132
$ fmriprep-docker -i fmriprep --shell
132133

134+
Code-Server Development Environment (Experimental)
135+
==================================================
136+
To get the best of working with containers and having an interactive
137+
development environment, we have an experimental setup with `code-server
138+
<https://github.com/cdr/code-server>`_.
139+
140+
.. Note::
141+
We have `a video walking through the process
142+
<https://youtu.be/bkZ-NyUaTvg>`_ if you want a visual guide.
143+
144+
1. Build the Docker image
145+
~~~~~~~~~~~~~~~~~~~~~~~~~
146+
We will use the ``Dockerfile_devel`` file to build
147+
our development docker image::
148+
149+
$ cd $HOME/projects/fmriprep
150+
$ docker build -t fmriprep_devel -f Dockerfile_devel .
151+
152+
2. Run the Docker image
153+
~~~~~~~~~~~~~~~~~~~~~~~
154+
We can start a docker container using the image we built (``fmriprep_devel``)::
155+
156+
$ docker run -it -p 127.0.0.1:8445:8080 -v ${PWD}:/src/fmriprep fmriprep_devel:latest
157+
158+
.. Note::
159+
If you are using windows shell, ${PWD} may not be defined, instead use the absolute
160+
path to your fmriprep directory.
161+
162+
.. Note::
163+
If you are using Docker-Toolbox, you will need to change your virtualbox settings
164+
using `these steps as a guide
165+
<https://github.com/jdkent/tutDockerRstudio#additional-setup-for-docker-toolbox>`_.
166+
(For step ``6``, instead of ``Name = rstudio; Host Port = 8787; Guest Port = 8787``,
167+
have ``Name = code-server; Host Port = 8443; Guest Port = 8080``.)
168+
Then in the docker command above, change ``127.0.0.1:8445:8080``
169+
to ``192.168.99.100:8445:8080``.
170+
171+
If the container started correctly, you should see the following on your console::
172+
173+
INFO Server listening on http://localhost:8080
174+
INFO - No authentication
175+
INFO - Not serving HTTPS
176+
177+
Now you can switch to your favorite browser and go to: ``127.0.0.1:8445``
178+
(or ``192.168.99.100:8445`` for Docker Toolbox).
179+
180+
3. Copy fmriprep.egg-info into your fmriprep directory
181+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182+
``fmriprep.egg-info`` makes the fmriprep package exacutable inside the docker container.
183+
Open a terminal in vscode and type the following::
184+
185+
$ cp -R /src/fmriprep.egg-info /src/fmriprep/
186+
187+
188+
Code-Server Development Environment Features
189+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
190+
191+
- The editor is `vscode <https://code.visualstudio.com/docs>`_
192+
193+
- There are several preconfigured debugging tests under
194+
the debugging icon in the activity bar
195+
196+
- see `vscode debugging python <https://code.visualstudio.com/docs/python/debugging>`_
197+
for details.
198+
199+
- The ``gitlens`` and ``python`` extensions are preinstalled to improve
200+
the development experience in vscode.
201+
133202

134203
Adding new features to the citation boilerplate
135204
===============================================
@@ -163,4 +232,4 @@ An example of how this works is shown here: ::
163232
(transformation matrices, and six corresponding rotation and translation
164233
parameters) are estimated before any spatiotemporal filtering using
165234
`mcflirt` [FSL {fsl_ver}, @mcflirt].
166-
""".format(fsl_ver=fsl.Info().version() or '<ver>')
235+
""".format(fsl_ver=fsl.Info().version() or '<ver>')

0 commit comments

Comments
 (0)