diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0c7331f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +# Documentation +README.rst +README.md +*.png + +# Python +setup.* +*.egg-info/ +build/ +jupyter_codeserver_proxy*/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b54a3d --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..13f4f67 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "spellright.language": [ + "fr", + "en" + ], + "spellright.documentTypes": [ + "markdown", + "latex", + "plaintext" + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..02edc97 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +# hadolint ignore=DL3007 +FROM jupyter/minimal-notebook:latest + +ARG code_server_proxy_wheel="jupyter_codeserver_proxy-1.0b3-py3-none-any.whl" + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +USER root + +# prerequisites ---- +# hadolint ignore=DL3008 +RUN apt-get update && apt-get install -yq --no-install-recommends \ + curl \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# code-server install ---- +#TODO: replace by wget already installed in the imag +RUN curl -fsSL https://code-server.dev/install.sh | sh && \ + rm -rf "${HOME}/.cache" + +USER $NB_UID + +# set the home directory +ENV CODE_WORKINGDIR="${HOME}/work" + +# code-server proxy copy package ---- +COPY ./dist/${code_server_proxy_wheel} /${HOME}/ + +# jupyter-server-proxy + code-server proxy install ---- +# hadolint ignore=DL3013 +RUN conda install --quiet --yes \ + 'jupyter-server-proxy' && \ + jupyter labextension install @jupyterlab/server-proxy && \ + pip install --quiet --no-cache-dir "${HOME}/${code_server_proxy_wheel}" && \ + rm "${HOME}/${code_server_proxy_wheel}" && \ + jupyter lab clean -y && \ + npm cache clean --force && \ + conda clean --all -f -y && \ + fix-permissions "${CONDA_DIR}" && \ + fix-permissions "/home/${NB_USER}" + +WORKDIR $HOME diff --git a/Makefile b/Makefile index 30df33c..913fa0a 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,45 @@ -all: +.PHONY: help + +IMAGE?=codeserver-notebook +SHELL:=bash +PACKAGE:=jupyter_codeserver_proxy + +help: +# http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html + @echo "code-server proxy" + @echo "=================" + @echo + @grep -E '^[a-zA-Z0-9_%/-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +build: build-package build-image ## build the package and the image + +build-package: ## build the python package python setup.py bdist_wheel -test: - twine upload --repository-url https://test.pypi.org/legacy/ dist/* +build-image: DARGS?= +build-image: ## build the latest image + docker build $(DARGS) --rm --force-rm -t $(IMAGE):latest . + @echo -n "Built image size: " + @docker images $(IMAGE):latest --format "{{.Size}}" + +clean: ## remove python package target dirs + rm -rf ./build + rm -rf ./dist + rm -rf "./$(PACKAGE).egg-info" + +dev: ARGS?= +dev: DARGS?= +dev: PORT?=8888 +dev: ## run a foreground container + docker run -it --rm -p $(PORT):8888 -e JUPYTER_ENABLE_LAB=yes $(DARGS) $(IMAGE) $(ARGS) + +run: DARGS?= +run: ## run a bash in interactive mode in the stack + docker run -it --rm $(DARGS) $(IMAGE) $(SHELL) + +run-sudo: DARGS?= +run-sudo: ## run a bash in interactive mode as root in the stack + docker run -it --rm -u root $(DARGS) $(IMAGE) $(SHELL) + +upload: ## upload the package + twine upload --repository-url https://test.pypi.org/legacy/ dist/* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9f320b3 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +Jupyter code-server proxy +========================= + +http://coder.com is a port of Microsoft Visual Studio Code to the browser. + +This package is a plugin for [jupyter-server-proxy](https://jupyter-server-proxy.readthedocs.io/) +that lets you run an instance of [code-server](https://github.com/cdr/code-server) alongside your Jupyter notebook, primarily +in a JupyterHub / Binder environment. + +A `Dockerfile` illustrates the way to integrate it in one of the [Jupyter Docker Stacks](https://github.com/jupyter/docker-stacks). + +How to +------ + +A `Makefile` gather the main commands. + +```bash +$ make + +# code-server proxy +# ================= +# +# build-image build the latest image +# build-package build the python package +# build build the package and the image +# clean remove python package target dirs +# dev run a foreground container +# run-sudo run a bash in interactive mode as root in the stack +# run run a bash in interactive mode in the stack +# upload upload the package +``` + +For example to build the package, integrate it in the image and launch it. + +```bash +$ make build +# ... +# Successfully tagged codeserver-notebook:latest +# Built image size: 2.08GB +$ make dev + +# ... +# [I 07:14:39.235 LabApp] Jupyter Notebook 6.1.4 is running at: +# [I 07:14:39.236 LabApp] http://d30367ff292a:8888/?token=048a06d6769cc34698365cfa427904d80b43498faaefb4e2 +# [I 07:14:39.237 LabApp] or http://127.0.0.1:8888/?token=048a06d6769cc34698365cfa427904d80b43498faaefb4e2 +# [I 07:14:39.238 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). +``` + +And that's it! + +![code-server in JupyterLab](code-server-ide.png) + +*Note: The code-server working directory (`CODE_WORKINGDIR` environment variable) is set to `"${HOME}/work"` which is the default home directory for Jupyter.* \ No newline at end of file diff --git a/README.rst b/README.rst deleted file mode 100644 index 558145c..0000000 --- a/README.rst +++ /dev/null @@ -1,21 +0,0 @@ -========= -Cloud9 IDE -========= - -http://coder.com is a port of microsoft VScode to the browser - -This package is a plugin for `jupyter-server-proxy `_ -that lets you run an instance of cloud9 alongside your notebook, primarily -in a JupyterHub / Binder environment. - -Installing code-server -================ -``` -RUN cd /opt && \ - mkdir /opt/code-server && \ - cd /opt/code-server && \ - wget -qO- https://github.com/codercom/code-server/releases/download/1.32.0-245/code-server-1.32.0-245-linux-x64.tar.gz | tar zxvf - --strip-components=1 - -ENV PATH=/opt/code-server:$PATH -``` - diff --git a/code-server-ide.png b/code-server-ide.png new file mode 100644 index 0000000..c0b68b9 Binary files /dev/null and b/code-server-ide.png differ diff --git a/jupyter_codeserver_proxy/__init__.py b/jupyter_codeserver_proxy/__init__.py index 36d0ea6..74c0c6f 100755 --- a/jupyter_codeserver_proxy/__init__.py +++ b/jupyter_codeserver_proxy/__init__.py @@ -17,7 +17,7 @@ def _codeserver_command(port): if working_dir is None: working_dir = os.getenv("JUPYTER_SERVER_ROOT", ".") - return [full_path, '--port=' + str(port), "--allow-http", "--auth", "none", working_dir ] + return [full_path, f'--port={port}', "--auth", "none", working_dir ] return { 'command': _codeserver_command,