{"id":814,"date":"2020-02-08T19:18:02","date_gmt":"2020-02-08T18:18:02","guid":{"rendered":"https:\/\/www.tiraquelibras.com\/blog\/?p=814"},"modified":"2021-02-02T10:43:33","modified_gmt":"2021-02-02T09:43:33","slug":"instalar-jupyter-html-notebook-en-docker","status":"publish","type":"post","link":"https:\/\/blog.tiraquelibras.com\/?p=814","title":{"rendered":"Instalar Jupyter HTML Notebook en Docker"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_76 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Tabla de contenidos<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a0cadd3c2b63\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a0cadd3c2b63\"  aria-label=\"Alternar\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=814\/#Introduccion\"  rel=\"nofollow\" target=\"_blank\">Introducci\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-2 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=814\/#Instalacion\"  rel=\"nofollow\" target=\"_blank\">Instalaci\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-3 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=814\/#Acceso\"  rel=\"nofollow\" target=\"_blank\">Acceso<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-4 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=814\/#Precauciones\"  rel=\"nofollow\" target=\"_blank\">Precauciones<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-5 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=814\/#Enlaces_de_interes\"  rel=\"nofollow\" target=\"_blank\">Enlaces de inter\u00e9s<\/a><\/li><\/ul><\/nav><\/div>\n<h1 id=\"introducci\u00f3n\"><span class=\"ez-toc-section\" id=\"Introduccion\"><\/span>Introducci\u00f3n<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Vamos a explicar como instalar la versi\u00f3n HTML de&nbsp;<strong>Jupyter Notebook<\/strong>&nbsp;en un contenedor de&nbsp;<strong>Docker<\/strong>. En nuestro caso lo usaremos para ejeuctar c\u00f3digo&nbsp;<strong>Python<\/strong>&nbsp;en la versi\u00f3n&nbsp;<strong>3.7<\/strong>.<\/p>\n<p><strong>Jupyter Notebook<\/strong>&nbsp;es un entorno de ejecuci\u00f3n inform\u00e1tico interactivo basado en la web para crear documentos de&nbsp;<em>Jupyter notebook<\/em>. Este editor se basa en documentos JSON, los cuales contienen una lista ordenada de celdas de entrada\/salida que pueden contener c\u00f3digo, texto (permitiendo&nbsp;<em><strong>Markdown<\/strong><\/em>), funciones matem\u00e1ticas, gr\u00e1ficos y texto enriquecido, generalmente terminado con la extensi\u00f3n&nbsp;<em>.ipynb<\/em>. Tambi\u00e9n permite archivos de Python&nbsp;<em>.py<\/em>, pero sin las funcinalidades de los Notebooks y sus caracter\u00edsticas nombradas.<\/p>\n<p>Tambi\u00e9n nos permite conectarnos a un <strong>Terminal<\/strong> o&nbsp;<strong><em>Shell<\/em><\/strong>&nbsp;del sistema en el que se encuentra instalado, y as\u00ed poder instalar paquetes, entre otras cosas.<\/p>\n<p>Para utilizar este entorno de ejecuci\u00f3n usaremos nuestro navegador Web preferido, y sin instalar ning\u00fan programa en nuestro PC, con la ventaja que nos ofrecen los contenedores de Docker.<\/p>\n<hr>\n<h1 id=\"instalaci\u00f3n\"><span class=\"ez-toc-section\" id=\"Instalacion\"><\/span>Instalaci\u00f3n<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Para poder tener a salvo los&nbsp;<em><strong>Notebooks<\/strong><\/em>&nbsp;o documentos de&nbsp;<strong>Jupyter<\/strong>&nbsp;ante cualquier problema con el contenedor de&nbsp;<strong>Docker<\/strong>&nbsp;vamos a crear un directorio local en el servidor, el cual podemos vincular con cualquier contenedor si alguna vez tenemos problemas con el actual:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">mkdir ~\/notebooks<\/pre>\n<p>Ahora le damos permisos al directorio para que el usuario del contenedor pueda gestionar el directorio de los documentos, ya que de lo contrario dar\u00e1 fallo al escribir en los archivos:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">chmod 757 notebooks\/<\/pre>\n<p>Ahora instalamos el contenedor indicando la redirecci\u00f3n de puertos y el v\u00ednculo con el directorio de&nbsp;<em><strong>Notebooks<\/strong><\/em>&nbsp;local y remoto (en el contenedor).<\/p>\n<p>Podemos ejecutarlo en <strong><span style=\"text-decoration: underline;\">modo interactivo<\/span><\/strong>, lo que significa que el contenedor funciona mientras tengamos la sesi\u00f3n abierta y finaliza cuando cancelamos esta (pulsando las teclas <strong><em>ctrl + c<\/em><\/strong>):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">docker run -p 8888:8888 -v ~\/notebooks:\/home\/jovyan jupyter\/minimal-notebook<\/pre>\n<p>O en <strong><span style=\"text-decoration: underline;\">modo demonio<\/span><\/strong>, para que se ejecute en segundo plano:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">docker run -d -p 8888:8888 -v ~\/notebooks:\/home\/jovyan jupyter\/minimal-notebook<\/pre>\n<p>Si queremos indicar una IP en concreto en nuestro servidor para que solo funcione en esta IP lo indicamos justo antes del puerto, tal y como aparece con el formato&nbsp;<strong>x.x.x.x<\/strong>&nbsp;en el siguiente comando, simulando ser una direcci\u00f3n IPv4:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">docker run -d -p x.x.x.x:8888:8888 -v ~\/notebooks:\/home\/jovyan jupyter\/minimal-notebook<\/pre>\n<hr>\n<h1 id=\"acceso\"><span class=\"ez-toc-section\" id=\"Acceso\"><\/span>Acceso<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Al ejecutar el <span style=\"text-decoration: underline;\"><strong>modo interactivo<\/strong><\/span> se indica la direcci\u00f3n URL a la que nos debemos de conectar para usar nuestro entorno de ejecuci\u00f3n de c\u00f3digo. Esta direcci\u00f3n contiene el&nbsp;<em>token<\/em> de sesi\u00f3n para poder acceder al entorno. Sin este <em>token<\/em> ser\u00e1 imposible acceder a este.<\/p>\n<p>Pero si hemos decidido usar el <span style=\"text-decoration: underline;\"><strong>modo demonio<\/strong><\/span> debemos de ejecutar el siguiente comando para obtener la URL completa junto al&nbsp;<em>token<\/em>&nbsp;de acceso.<\/p>\n<p>Primero obtenemos el&nbsp;<em>ID<\/em>&nbsp;del contenedor en el que corre nuestro entorno:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">docker ps<\/pre>\n<p>En nuestro caso este ser\u00eda el resultado:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">c0fc212515f0 jupyter\/minimal-notebook \"tini -g -- start-...\" 4 days ago Up 4 days 0.0.0.0:8888-&gt;8888\/tcp tender_hopper<\/pre>\n<p>Siendo el&nbsp;<em>ID<\/em>&nbsp;<code class=\"inline-code\">c0fc212515f0<\/code>.<\/p>\n<p>Ahora a partir de este podemos obtener la URL de acceso a&nbsp;<strong>Jupyter<\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">docker exec &lt;id_container&gt; jupyter notebook list<\/pre>\n<p>Ejemplo de respuesta<\/p>\n<blockquote><p>Currently running servers:<br \/>\n<a title=\"http:\/\/0.0.0.0:8888\/?token=924655e7b5cc2a5b7dcc0d888e71ef6b6d5e70d34d527ff3\" href=\"http:\/\/0.0.0.0:8888\/?token=924655e7b5cc2a5b7dcc0d888e71ef6b6d5e70d34d527ff3\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">http:\/\/0.0.0.0:8888\/?token=924655e7b5cc2a5b4dcc0d188e71ef6b6d5e70d34d527ff3<\/a>&nbsp;:: \/home\/jovyan<\/p><\/blockquote>\n<p>Esta es la URL de acceso a nuestro entorno. Es posible que si indicamos una IP distinta a la hora de arrancar el contenedor no aparezca en la URL, mostr\u00e1ndose como IP la&nbsp;<strong>0.0.0.0<\/strong>. De se as\u00ed solo tendremos que cambiarla por la IP que nosotros queramos.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-818 alignnone\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2020\/02\/jupyter-1.jpg\" alt=\"\" width=\"959\" height=\"420\"><\/p>\n<p>Tambi\u00e9n podemos ejecutar otros comandos, como instalar paquetes, crear entornos virtuales de <strong>Python<\/strong>, entre otros, a partir del&nbsp;<em>ID<\/em>&nbsp;del contenedor. Por ejemplo, ejecutar comandos&nbsp;<strong>PIP<\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">docker exec &lt;id_container&gt; pip list<\/pre>\n<p>Ejemplo de respuesta:<\/p>\n<blockquote><p>WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.<br \/>\nPlease see&nbsp;<a title=\"https:\/\/github.com\/pypa\/pip\/issues\/5599\" href=\"https:\/\/github.com\/pypa\/pip\/issues\/5599\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">https:\/\/github.com\/pypa\/pip\/issues\/5599<\/a>&nbsp;for advice on fixing the underlying issue.<br \/>\nTo avoid this problem you can invoke Python with \u2018-m pip\u2019 instead of running pip directly.<br \/>\nPackage Version<\/p>\n<hr>\n<p>alembic 1.3.3<br \/>\nasync-generator 1.10<br \/>\nattrs 19.3.0<br \/>\nbackcall 0.1.0<br \/>\nbleach 3.1.0<\/p>\n<p>\u2026<\/p><\/blockquote>\n<p>Aunque desde el propio entorno Web disponemos de una <strong>Terminal<\/strong> o&nbsp;<em><strong>Shell<\/strong><\/em> para interactuar con el Sistema.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-817\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2020\/02\/jupyter-2-terminal.jpg\" alt=\"\" width=\"285\" height=\"277\"> <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-816\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2020\/02\/jupyter-3-terminal.jpg\" alt=\"\" width=\"956\" height=\"349\"><\/p>\n<hr>\n<h1 id=\"precauciones\"><span class=\"ez-toc-section\" id=\"Precauciones\"><\/span>Precauciones<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Es necesario tener en cuenta que tanto los&nbsp;<strong>Notebooks<\/strong>&nbsp;como las <strong>Terminales<\/strong> abiertas consumen espacio en la memoria&nbsp;<strong>RAM<\/strong>, por lo que si tenemos muchos abiertos\/en ejecuci\u00f3n podemos afectar al rendimiento del Sistema.<\/p>\n<p>Desde la secci\u00f3n&nbsp;<strong>Running<\/strong> podemos ver qu\u00e9 procesos o archivos tenemos corriendo en el Sistema, pudiendo apagarlos pulsando en el bot\u00f3n <em><strong>Shutdown<\/strong><\/em>, y por tanto liberando espacio en memoria.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-815\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2020\/02\/jupyter-4-running.jpg\" alt=\"\" width=\"959\" height=\"368\"><\/p>\n<p>Tambi\u00e9n es recomendable, por no decir obligatorio, limitar el acceso a esta&nbsp;<strong>IP &#8211; puerto<\/strong>&nbsp;en el FW, para proteger el sistema completo de posibles ataques o accesos indevidos.<\/p>\n<hr>\n<h1 id=\"enlaces-de-inter\u00e9s\"><span class=\"ez-toc-section\" id=\"Enlaces_de_interes\"><\/span>Enlaces de inter\u00e9s<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Enlace con la info de como instalar el contenedor, m\u00f3dulos de&nbsp;<strong>Python<\/strong>&nbsp;y obtener la&nbsp;<em><strong>key<\/strong><\/em>&nbsp;para la URL de&nbsp;<strong>Jupyter<\/strong>&nbsp;aqu\u00ed -&gt;&nbsp;<a title=\"https:\/\/www.dataquest.io\/blog\/docker-data-science\/\" href=\"https:\/\/www.dataquest.io\/blog\/docker-data-science\/\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">https:\/\/www.dataquest.io\/blog\/docker-data-science\/<\/a><\/p>\n<p>Wikipedia Jupyter -&gt;&nbsp;<a title=\"https:\/\/es.wikipedia.org\/wiki\/Proyecto_Jupyter\" href=\"https:\/\/es.wikipedia.org\/wiki\/Proyecto_Jupyter\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">https:\/\/es.wikipedia.org\/wiki\/Proyecto_Jupyter<\/a><\/p>\n<p>Videotutorial de Jupyter (en ing\u00e9s) -&gt;&nbsp;<a title=\"https:\/\/www.youtube.com\/watch?v=HW29067qVWk\" href=\"https:\/\/www.youtube.com\/watch?v=HW29067qVWk\" type=\"\" data-from-md=\"\" class=\"external external_icon\" rel=\"nofollow\" target=\"_blank\">https:\/\/www.youtube.com\/watch?v=HW29067qVWk<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introducci\u00f3n Vamos a explicar como instalar la versi\u00f3n HTML de&nbsp;Jupyter Notebook&nbsp;en un contenedor de&nbsp;Docker. En nuestro caso lo usaremos para ejeuctar c\u00f3digo&nbsp;Python&nbsp;en la versi\u00f3n&nbsp;3.7. Jupyter<span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/blog.tiraquelibras.com\/?p=814\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":819,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,10],"tags":[102,100,101,27],"class_list":["post-814","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programacion","category-sistemas","tag-contenedor","tag-desarrollo","tag-docker","tag-python"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/814","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=814"}],"version-history":[{"count":0,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/814\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/media\/819"}],"wp:attachment":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=814"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=814"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=814"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}