mirror of
				https://github.com/livebook-dev/livebook.git
				synced 2025-11-01 00:06:04 +08:00 
			
		
		
		
	Add Docker image to deploy guide, break use cases
This commit is contained in:
		
							parent
							
								
									f0a72e5636
								
							
						
					
					
						commit
						6d32eebbab
					
				
					 4 changed files with 161 additions and 103 deletions
				
			
		|  | @ -85,7 +85,7 @@ See [Livebook images](https://github.com/livebook-dev/livebook/pkgs/container/li | |||
| ### Embedded devices | ||||
| 
 | ||||
| If you want to run Livebook on embedded devices, such as Raspberry Pi, BeagleBone, etc., | ||||
| check out [our Livebook firmware](https://github.com/livebook-dev/nerves_livebook) built | ||||
| check out [the Livebook firmware](https://github.com/livebook-dev/nerves_livebook) built | ||||
| with [Nerves](https://www.nerves-project.org/). | ||||
| 
 | ||||
| ### Direct installation with Elixir | ||||
|  |  | |||
|  | @ -248,6 +248,36 @@ new features. | |||
| 
 | ||||
| Congratulations on shipping! | ||||
| 
 | ||||
| ## Docker deployment | ||||
| 
 | ||||
| Now that you have deployed your first notebook as an application | ||||
| locally, you may be wondering: can I actually ship this production? | ||||
| 
 | ||||
| The answer is yes! | ||||
| 
 | ||||
| You can do so in any platform that supports Docker containers. | ||||
| For example, imagine you have a folder called "public-apps" with | ||||
| all of your public notebooks you want to deploy. You can then | ||||
| run your own Livebook image which points to said directory: | ||||
| 
 | ||||
| ```dockerfile | ||||
| FROM ghcr.io/livebook-dev/livebook:latest | ||||
| 
 | ||||
| COPY /path/to/my/public-apps /apps | ||||
| ENV LIVEBOOK_APPS_PATH "/apps" | ||||
| ENV LIVEBOOK_APPS_PATH_WARMUP "manual" | ||||
| RUN /app/bin/warmup_apps.sh | ||||
| ``` | ||||
| 
 | ||||
| You may also set additional environment variables, [see the complete | ||||
| list](https://github.com/livebook-dev/livebook#environment-variables). | ||||
| Some of them, such as `LIVEBOOK_PASSWORD`, must be set directly on | ||||
| your deployment platform, with the value of your choice, if you want | ||||
| to access and debug your deployed notebooks in production. | ||||
| 
 | ||||
| If you want to develop and deploy notebooks as a team, check out | ||||
| [Livebook Teams](https://teams.livebook.dev/). | ||||
| 
 | ||||
| ## Where to go next | ||||
| 
 | ||||
| There are many types of applications one can build with | ||||
|  |  | |||
|  | @ -112,8 +112,8 @@ by pressing <kbd>?</kbd>. | |||
| 
 | ||||
| ## Autocompletion | ||||
| 
 | ||||
| Elixir code cells also support autocompletion. Autocompletion | ||||
| happens automatically as you type but you can explicitly trigger | ||||
| Code cells also support autocompletion. Autocompletion happens | ||||
| automatically as you type but you can explicitly trigger | ||||
| it with <kbd>ctrl</kbd> + <kbd>␣</kbd>. You must start the runtime, | ||||
| by executing any cell at least once, for the autocompletion engine | ||||
| to load. | ||||
|  | @ -132,40 +132,6 @@ return the Elixir version. | |||
| Note you can also press <kbd>tab</kbd> to cycle across the completion | ||||
| alternatives. | ||||
| 
 | ||||
| <!-- livebook:{"branch_parent_index":1} --> | ||||
| 
 | ||||
| ## Storing secrets in Hubs | ||||
| 
 | ||||
| Livebook is capable of managing all secrets that belong to a notebook. | ||||
| Secrets can be read by Elixir Code cells and also by Smart cells - | ||||
| a feature we will explore in future sections. | ||||
| 
 | ||||
| Secrets are environment variables starting with the `LB_` prefix. For | ||||
| example, let's try reading an environment variable: | ||||
| 
 | ||||
| ```elixir | ||||
| System.fetch_env!("LB_MY_SECRETZ") | ||||
| ``` | ||||
| 
 | ||||
| Execute the cell above. If the secret is not available, Livebook will | ||||
| automatically detect it and prompt you to add the missing secret. You | ||||
| can save a secret in two different locations: | ||||
| 
 | ||||
|   * in your notebook session: once you restart the session or your | ||||
|     Livebook, the secret will be gone and you must input it again | ||||
| 
 | ||||
|   * in a Hub: a Hub is a location where you can safely store secrets, | ||||
|     deploy notebooks, and more. Every Livebook application has a personal | ||||
|     Hub that can store secrets and stamp notebooks | ||||
| 
 | ||||
| Once the secret is saved, execute the cell again and it will evaluate | ||||
| successfully. | ||||
| 
 | ||||
| If you save secrets in your Hub, you will only need to input the secret | ||||
| once in notebooks authored by you. You can manage all of your secrets | ||||
| by clicking the lock icon (<i class="ri-livebook-secrets"></i>) on the | ||||
| sidebar. | ||||
| 
 | ||||
| ## Markdown extensions | ||||
| 
 | ||||
| Livebook also include supports for links, mathematical expressions, and Mermaid diagrams. | ||||
|  | @ -213,14 +179,17 @@ graph TD; | |||
|     C-->D; | ||||
| ``` | ||||
| 
 | ||||
| ## Elixir integration | ||||
| ## Elixir integration and use cases | ||||
| 
 | ||||
| Here are some tips on how to better integrate Livebook with Elixir. | ||||
| There are many ways Elixir developers and leverage Livebook today. | ||||
| 
 | ||||
| ### Mix projects | ||||
| <!-- livebook:{"break_markdown":true} --> | ||||
| 
 | ||||
| Sometimes you may want to run a notebook within the context of an existing | ||||
| Mix project. This is possible from Elixir v1.14 with the help of `Mix.install/2`. | ||||
| ### Documentation with `Mix.install` | ||||
| 
 | ||||
| Livebook is an excellent tool for documentation. Many Elixir packages use | ||||
| Livebook as tutorials but you can also directly run Livebook within the context | ||||
| of your existing application with the help of `Mix.install/2`. | ||||
| 
 | ||||
| As an example, imagine you have created a notebook inside your current project, | ||||
| at `notebooks/example.livemd`. In order to run within the root Mix project, using | ||||
|  | @ -241,19 +210,49 @@ Mix.install( | |||
| 
 | ||||
| <!-- livebook:{"break_markdown":true} --> | ||||
| 
 | ||||
| ### Runtimes | ||||
| ### Deploying custom apps and internal tooling | ||||
| 
 | ||||
| Livebook has a concept of **runtime**, which in practice is an Elixir node responsible | ||||
| for evaluating your code. You can choose the runtime by clicking the "Runtime" icon | ||||
| (<i class="ri-livebook-runtime"></i>) on the sidebar (or by using the <kbd>s</kbd> <kbd>r</kbd> | ||||
| keyboard shortcut). | ||||
| Your Livebook notebooks can be deployed as actual applications which | ||||
| you may then share within your team and company. We have a | ||||
| [whole guide dedicated to this topic](/learn/notebooks/deploy-apps), | ||||
| which is recommended reading for those who want to learn more. | ||||
| The next use caso also builds on top of notebook deployment, | ||||
| let's check it out. | ||||
| 
 | ||||
| By default, a new Elixir node is started (similarly to starting `iex`). You can click | ||||
| reconnect whenever you want to discard the current node and start a new one. | ||||
| <!-- livebook:{"break_markdown":true} --> | ||||
| 
 | ||||
| You can also manually *attach* to an existing distributed node by picking the | ||||
| "Attached Node" runtime. To do so, you will need the Erlang Name of the external node | ||||
| and its Erlang Cookie. For example, you can start a Phoenix application as follows: | ||||
| ### Communication and automation of Elixir systems | ||||
| 
 | ||||
| You may also deploy notebooks as applications that automate and monitor | ||||
| live Elixir systems. You will use the same techniques | ||||
| [as in the deploy guide](/learn/notebooks/deploy-apps) and from there | ||||
| directly connect to your cluster. | ||||
| 
 | ||||
| To do so, you need to ensure Livebook is deployed in the same network | ||||
| as your existing system. Then use [`Node.set_cookie/2`](https://hexdocs.pm/elixir/Node.html#set_cookie/2) | ||||
| with the node you want to connect to and its cookie, and finally | ||||
| explicitly call [`Node.connect/1`](https://hexdocs.pm/elixir/Node.html#connect/1) | ||||
| to confirm the connection can be established successfully. | ||||
| To execute code and retrieve data from the live node, use | ||||
| [the `:erpc` module](https://www.erlang.org/doc/man/erpc.html). | ||||
| 
 | ||||
| <!-- livebook:{"break_markdown":true} --> | ||||
| 
 | ||||
| ### Debugging live systems (with attached mode) | ||||
| 
 | ||||
| Livebook has a concept of **runtime**, which in practice is an Elixir node | ||||
| responsible for evaluating your code. You can choose the runtime by clicking | ||||
| the "Runtime" icon (<i class="ri-livebook-runtime"></i>) on the sidebar | ||||
| (or by using the <kbd>s</kbd> <kbd>r</kbd> keyboard shortcut). | ||||
| 
 | ||||
| By default, a new Elixir runtime is started (similarly to starting `iex`). | ||||
| You can click reconnect whenever you want to discard the current runtime and | ||||
| start a new one. | ||||
| 
 | ||||
| You can also manually *attach* to an existing distributed node by picking | ||||
| the "Attached Node" runtime. To do so, you will need the Erlang Name of | ||||
| the external node and its Erlang Cookie. For example, you can start a | ||||
| [Phoenix application](https://phoenixframework.org/) as follows: | ||||
| 
 | ||||
| ```shell | ||||
| $ iex --sname phoenix-app --cookie secret -S mix phx.server | ||||
|  | @ -262,31 +261,69 @@ $ iex --sname phoenix-app --cookie secret -S mix phx.server | |||
| Now open up a new notebook and click the "Runtime" icon on the sidebar. | ||||
| Click to "Configure" the runtime and choose "Attached node". Input the | ||||
| name and cookie as above and you should be ready to connect to it. | ||||
| Any code that you execute in the notebook now runs within the Phoenix | ||||
| application you connected to. | ||||
| 
 | ||||
| Note, however, that you can't install new dependencies on a attached runtime. | ||||
| We recommend the attached mode only for debugging an external system. | ||||
| If you want to install dependencies or use Livebook alongside an existing | ||||
| application, we suggest to either: | ||||
| You may also [connect your local Livebook instance to a node running in | ||||
| production depending on your platform](https://fly.io/docs/elixir/advanced-guides/connect-livebook-to-your-app/). | ||||
| Once connected, Livebook can run any code within your production nodes | ||||
| (similar to a remote shell) which can be useful to debug and run checks | ||||
| on live systems. | ||||
| 
 | ||||
|   * Use the Mix project approach outlined in the previous section; | ||||
| 
 | ||||
|   * Use a regular notebook and use | ||||
|     [`Node.connect/1`](https://hexdocs.pm/elixir/Node.html#connect/1) | ||||
|     to connect to your application. | ||||
|     Use [the `:erpc` module](https://www.erlang.org/doc/man/erpc.html) | ||||
|     to fetch data from the remote node and execute code. | ||||
| Attached nodes can't install new dependencies on a attached runtime | ||||
| and, in general, we recommend it only for debugging of external system. | ||||
| 
 | ||||
| <!-- livebook:{"break_markdown":true} --> | ||||
| 
 | ||||
| ### Evaluation vs compilation | ||||
| ### Scaffolding embedded systems with Nerves | ||||
| 
 | ||||
| If you want to run Livebook on embedded devices, such as Raspberry Pi, | ||||
| BeagleBone, etc., check out [the Livebook | ||||
| firmware](https://github.com/livebook-dev/nerves_livebook) built | ||||
| with [Nerves](https://www.nerves-project.org/). In such cases, Livebook | ||||
| uses a special runtime, called the Embedded Runtime, where all of your | ||||
| code runs within Livebook itself, without starting additional runtimes | ||||
| (which may be too expensive on limited devices). | ||||
| 
 | ||||
| ## Erlang support | ||||
| 
 | ||||
| Livebook also allows developers to write Erlang code. To do so, | ||||
| click on the submenu option on the right side of the "Elixir" cell | ||||
| button and choose Erlang. | ||||
| 
 | ||||
| Your Erlang code will run alongside your Elixir cells. This means | ||||
| you can leverage all of dependency management and smart cells features | ||||
| outlined in the previous sections. In particular, integration between | ||||
| Erlang and Elixir will happen as follows: | ||||
| 
 | ||||
|   * Variables in Elixir are available in Erlang cells in camel-case | ||||
|     fashion. `x` in Elixir becomes `X` in Erlang. `foo_bar` becomes | ||||
|     `FooBar`; | ||||
| 
 | ||||
|   * Variables in Erlang are available in Elixir cells in underscored | ||||
|     fashion. `X` in Erlang becomes `x` in Elixir. `FooBar` becomes | ||||
|     `foo_bar`; | ||||
| 
 | ||||
| For example, to print all of the cats defined at the top of the notebook, | ||||
| but in Erlang: | ||||
| 
 | ||||
| ```erlang | ||||
| [io:format("~ts", [Cat]) || Cat <- Cats]. | ||||
| ``` | ||||
| 
 | ||||
| We are just beginning the Erlang integration and contributions to | ||||
| enrich the support are welcome. | ||||
| 
 | ||||
| ## Evaluation vs compilation | ||||
| 
 | ||||
| Livebook automatically shows the execution time of each Code | ||||
| cell on the bottom-right of the cell. After evaluation, the total | ||||
| time can be seen by hovering the green dot. | ||||
| 
 | ||||
| However, it is important to remember that all code outside of | ||||
| a module in Elixir is *evaluated*, and therefore executes much | ||||
| slower than code defined inside modules, which are *compiled*. | ||||
| a module in Erlang or Elixir is *evaluated*, and therefore | ||||
| executes much slower than code defined inside modules, which | ||||
| are *compiled*. | ||||
| 
 | ||||
| Let's see an example. Run the cell below: | ||||
| 
 | ||||
|  | @ -324,35 +361,6 @@ happen inside a module, which is compiled. | |||
| If a notebook is performing slower than expected, consider moving | ||||
| the bulk of the execution to inside modules. | ||||
| 
 | ||||
| ## Erlang integration | ||||
| 
 | ||||
| Livebook also allows developers to write Erlang code. To do so, | ||||
| click on the submenu option on the right side of the "Elixir" cell | ||||
| button and choose Erlang. | ||||
| 
 | ||||
| Your Erlang code will run alongside your Elixir cells. This means | ||||
| you can leverage all of dependency management and smart cells features | ||||
| outlined in the previous sections. In particular, integration between | ||||
| Erlang and Elixir will happen as follows: | ||||
| 
 | ||||
|   * Variables in Elixir are available in Erlang cells in camel-case | ||||
|     fashion. `x` in Elixir becomes `X` in Erlang. `foo_bar` becomes | ||||
|     `FooBar`; | ||||
| 
 | ||||
|   * Variables in Erlang are available in Elixir cells in underscored | ||||
|     fashion. `X` in Erlang becomes `x` in Elixir. `FooBar` becomes | ||||
|     `foo_bar`; | ||||
| 
 | ||||
| For example, to print all of the cats defined at the top of the notebook, | ||||
| but in Erlang: | ||||
| 
 | ||||
| ```erlang | ||||
| [io:format("~ts", [Cat]) || Cat <- Cats]. | ||||
| ``` | ||||
| 
 | ||||
| We are just beginning the Erlang integration and contributions to | ||||
| enrich the support are welcome. | ||||
| 
 | ||||
| ## Running tests | ||||
| 
 | ||||
| There are two main ways of running tests inside Livebook. | ||||
|  | @ -421,6 +429,9 @@ That's our quick intro to Livebook! Where to go next? | |||
|   with Elixir](/learn/notebooks/distributed-portals-with-elixir) | ||||
|   notebook; | ||||
| 
 | ||||
| * [Write and deploy a chat application](/learn/notebooks/deploy-apps) | ||||
|   using Livebook; | ||||
| 
 | ||||
| * Go back [to the Learn page](/learn) and see how to use Livebook to | ||||
|   deploy apps, explore data, plot graphs, and much more; | ||||
| 
 | ||||
|  |  | |||
|  | @ -113,13 +113,14 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do | |||
| 
 | ||||
|           <div class="flex flex-col space-y-4"> | ||||
|             <h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200"> | ||||
|               Offline Deployment | ||||
|               Airgapped Deployment | ||||
|             </h2> | ||||
| 
 | ||||
|             <p class="text-gray-700"> | ||||
|               Deploy your stamped notebooks with your Hub | ||||
|               using an instance of the Hub using | ||||
|               environment variables. | ||||
|               It is possible to deploy notebooks that belong to this Hub in an airgapped | ||||
|               deployment, without connecting back to Livebook Teams server. This is done | ||||
|               using the Docker image template below, which encrypts all of your Hub metadata, | ||||
|               and taking some additional steps. | ||||
|             </p> | ||||
| 
 | ||||
|             <div id="env-code"> | ||||
|  | @ -156,6 +157,23 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do | |||
|                 source={@dockerfile} | ||||
|                 language="dockerfile" | ||||
|               /> | ||||
| 
 | ||||
|               <ol class="text-gray-700"> | ||||
|                 <li> | ||||
|                   You must change <code>/path/to/my/notebooks</code> in the template above | ||||
|                   to point to a directory with the `.livemd` files you want to deploy | ||||
|                 </li> | ||||
|                 <li> | ||||
|                   You must set the <code>LIVEBOOK_TEAMS_KEY</code> environment variable | ||||
|                   directly on your deployment platform, with the value you can find at the | ||||
|                   top of this page | ||||
|                 </li> | ||||
|                 <li> | ||||
|                   You may set the <code>LIVEBOOK_PASSWORD</code> environment variable to any | ||||
|                   value of your choice, if you want to access and debug your deployed notebooks | ||||
|                   in production | ||||
|                 </li> | ||||
|               </ol> | ||||
|             </div> | ||||
|           </div> | ||||
| 
 | ||||
|  | @ -347,16 +365,15 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do | |||
|     version = if version =~ "dev", do: "edge", else: version | ||||
| 
 | ||||
|     assign(socket, :dockerfile, """ | ||||
|     FROM livebook/livebook:#{version} | ||||
| 
 | ||||
|     COPY /path/to/my/notebooks /data | ||||
|     ENV LIVEBOOK_APPS_PATH "/data" | ||||
|     FROM ghcr.io/livebook-dev/livebook:#{version} | ||||
| 
 | ||||
|     ENV LIVEBOOK_APPS_PATH_HUB_ID "#{socket.assigns.hub.id}" | ||||
|     ENV LIVEBOOK_TEAMS_NAME "#{socket.assigns.hub.hub_name}" | ||||
|     ENV LIVEBOOK_TEAMS_OFFLINE_KEY "#{socket.assigns.hub.org_public_key}" | ||||
|     ENV LIVEBOOK_TEAMS_SECRETS "#{encrypt_secrets_to_dockerfile(socket)}" | ||||
| 
 | ||||
|     COPY /path/to/my/notebooks /apps | ||||
|     ENV LIVEBOOK_APPS_PATH "/apps" | ||||
|     ENV LIVEBOOK_APPS_PATH_WARMUP "manual" | ||||
|     RUN /app/bin/warmup_apps.sh\ | ||||
|     """) | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue