Host Pluto server in the cloud, eg, Digital Ocean?

Does anyone have pointers for hosting Pluto on a cloud-based server, such as Digital Ocean? I’m interested in a regular Pluto server for developing notebooks, but not interested in PlutoSliderServer.

1 Like

Install julia on the server by ssh-ing into it and downloading the julia from the official website (with wget for instance). Start a new julia project, install Pluto in it, and run it with:;host="", port="1234"). Then point your browser to http://your_server_ip:1234.

Overriding the default listening address with host="" is important - otherwise only programs running on the same server can connect to Pluto. Saying “listen to” means “listen to all network interfaces, including those exposed to the dangerous internet”.

If you want a bit more security, you can tell Pluto to listen only to the local interface by deleting the host argument (so that there are no public ports open) and then make a port fowarding tunnel to it from your local machine with ssh -L.

Edit: Check ? for more information.

Edit2: Do not keep anything valuable on that server. Unless you set up https sertificates or ssh port forwarding, your connection is unencrypted and the password would be visible to anyone between you and the server.


Thank you, @Krastanov .

1 Like

I tried this on a Google Compute Engine instance and it timed out trying to access the server. I have ingress setup and checked that an apache2 server was accessible when I ran that. Do you know what the issue would be?

There is a ton of setup and precompilation happening, so I would not be surprised if it takes quite a few minutes before things are ready, especially on a small VPS. Could you check the console of your VM – that would tell you what is happening with the pluto server while precompilation is happening.

For completeness, here is a small docker file I am currently using for PlutoSliderServer (not Pluto itself, but it can be adapted):

# Containerfile
RUN julia -e "import Pkg; Pkg.add(\"PlutoSliderServer\");"
ENTRYPOINT julia -e "import PlutoSliderServer; PlutoSliderServer.run_directory(\"./notebooks\"; SliderServer_host=\"\", SliderServer_watch_dir=true)"
# compose yaml
# you probably need to add port forwarding here
      context: pluto
      containerfile: Containerfile
      - "/data/podman/pluto/app/notebooks/:/app/notebooks/"

I did run it before after the console said the notebook was loaded. I did turn off precompilation because that actually failed on the VM a lot but I still got Pluto running showing me the address I could access the notebook. So I don’t think the issue is the stuff not fully loading yet. I may just be missing some port thing that the apache server is already doing, because that seemed to work okay.

It should be feasible to use your Pluto server without a proxy like apache as long as you set it to listen to address (by default it listens to which is accessible only locally within the server). That might be an important debugging step, in order to see whether the issue is with pluto or with apache. Also, you can use a terminal browser like lynx to try to access the page directly from within the server without going through apache. Or you can use curl/wget to download the index page and then just read it to see whether it looks like a real pluto index page. All of these are suggestions for how to avoid using apache in order to provide some separation of concerns while debugging.

Thanks for your help. I did try just on my home network running the slider server with host I was able to access it on that computer just going to localhost and the port. I tried accessing on another computer on the network at the local IP address and it didn’t work. I tried pinging that IP address from the computer and it could reach it. I also ran an apache server on the same computer and could access it on the local network but that was listening on port 80. The Slider server default port is uses is 2345. I did make rules to open that port in the firewall on both computers. Not sure why I can’t access the page.

Setting listening address to (and double checking there are no blocked ports due to a firewall) should be all that is needed. It seems you already did all of this… so all I can say is that there is a bug or misconfiguration somewhere along the way. Maybe try with an even simpler server, like the built-in file server in python python3 -m http.server – you can change the port and interface with python3 -m http.server 2345 --bind or Julia’s LiveServer.jl

I do not know whether this would be helpful, but at least it will give some more detailed symptoms.

I got it to work. Issue was making the server running in WSL available to the host computer. I was testing the SliderServer in general for its limitations because I have a notebook that does a lot of computation after certain buttons are pressed and caches data. It seems like certain cells won’t run in that case. I’m not sure what the limits are in terms of how elaborate and long running the computations triggered by reactive elements can be. I was wondering though if it is possible to get realtime feedback on things running in the server. I tried using @info in the notebook which works well for updating me when a cell is running. But in the SliderServer that same cell waits until the end of the computation to print anything.

Another question related to how SliderServer functions is let’s say you have a notebook that loads a dictionary and then a notebook modifies the contents of that dictionary. When you reload the page or a different client connects to the server, does it have multiple distinct versions of that in memory or will it share anything cached from another user? This kind of thing might be outside the scope of what it is designed to do so I’d also like to know if I’m trying to do something that’s a bad idea.

Each connection to the SliderServer will see an independent version of the notebook (unless the notebook is talking to something external, like writing to a datafile or something like that). You can verify that by simply opening the same page twice in two separate tabs.

Okay thanks. Do you know about the behavior of @info in the SliderServer vs a normal notebook?

@jekyllstein there was a related discussion on visual cue of running status of notebooks in PlutoSliderServer on zulip.

I just opened an issue on github regarding that. The short answer is that for the moment you only get something back when the notebook computations are finished so there is no way at the moment to get partial updates while the computation is running.

For what instead concerns modification of the notebook, if I remember correctly there is only a single notebook that is hosted on the server and is not modified upon user requests.
Whenever the user of the sliderserver updates the value of a Bond, the sliderservers computes what the outcome of that change will be (in terms of affected cells outputs) and sends that new output to the client.
It does not update it’s internal notebook state to reflect that change though.

So everytime a new request to change the Dict via a bond is sent to the SliderServer, the starting point will always be the original value of the Dict when the server was created.

In general for things to work without breaking or having unexpected consequences, your notebook code should have outputs that only depend on the values of the binded variables, and not on some other internal notebook state that you’d want to change during the use of the SliderServer.

Regarding the last point, there is an additional point to keep in mind. If you have outputs that have some inherent randomization, you might face unexpected results.
Suppose you have a binded variables N that selects how many points you want to plot and you just then create a cell with:


Since PlutoSliderServer caches the first results it gets for any unique combination of the input bonds, if you perform the following changes in the value of the variable: N = 2 -> N = 4 -> N = 2 you will get the exact same plot when you change N back to 2 as you had on your first instance where N was 2.

This is evident for the simple example above but it can be tricky to realize in more complex setups.
You can avoid the caching that happens on the client side by adding a specific notebook metadata (added in this PR). Easiest way to disable this is opening your notebook file (on the server) and adding this line at the beginning of the notebook

#> sliderserver_force_post = true

So that your notebook file starts like this (for example):

### A Pluto.jl notebook ###
# v0.19.26

#> sliderserver_force_post = true