Livebook on AWS User Guide
Overview
This image runs Livebook, the open source interactive and collaborative notebook for Elixir. A notebook mixes Elixir code cells, Markdown prose, live inputs, data tables and charts in one document, and that document is a plain text .livemd file, so a notebook can be committed to version control next to the code it describes and re-run unchanged by someone else.
The image ships a complete BEAM toolchain. Erlang/OTP 28.5.0.3 is compiled from the official pinned source tarball with its checksum verified during the build and installed into /usr/local, and Elixir 1.20.2 is the official pinned precompiled release, unpacked to /opt/elixir with elixir, elixirc, iex and mix symlinked onto the default PATH. Both stay on the instance at run time because Livebook's default notebook runtime spawns a fresh Elixir node for each notebook session.
Livebook itself is a self contained escript at /opt/livebook/livebook, run by livebook.service as a dedicated unprivileged livebook system user. The notebook server binds the loopback interface only, on 127.0.0.1:8080, with its iframe sandbox on 127.0.0.1:8081. It is never directly reachable from the network. nginx terminates TLS on port 443 and reverse proxies to the notebook server with WebSocket upgrade headers, which is what makes Livebook's LiveView interface and collaborative editing work through the proxy. Port 80 returns a redirect to HTTPS and serves an unauthenticated /healthz endpoint for load balancer probes.
Livebook evaluates arbitrary Elixir, so an unprotected instance would be remote code execution. This image never ships an open or default credential. On the first boot of every deployed instance a one-shot service generates a unique 28 character access password and a unique Erlang distribution cookie, writes them to /opt/livebook/livebook.env with mode 0640, regenerates a self signed TLS certificate carrying that instance's own address in its subject alternative names, and records the password in /root/livebook-credentials.txt with mode 0600 so only the root user can read it. Two instances launched from the same Amazon Machine Image never share a password.
Notebooks and Livebook's internal state live at /var/lib/livebook, which is a dedicated, independently resizable EBS data volume referenced in /etc/fstab by filesystem UUID.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and port 443 for the Livebook web interface
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Livebook. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network and port 443 for the Livebook web interface. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialisation takes a short time after the instance state becomes Running and the status checks pass, while the image generates the access password, regenerates the TLS certificate, and starts the notebook server.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Livebook Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22 and 443 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=livebook}]'
When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.
Step 3: Connect to Your Instance
Connect over SSH using your key pair and the login user for your operating system variant.
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 4: Retrieve the Access Password
The access password is generated on the first boot of this instance and written to a root-only file. Read it over SSH.
sudo cat /root/livebook-credentials.txt
The file records the password, the URL to open, and the Erlang distribution cookie:
# Livebook - this instance. Generated on first boot by livebook-firstboot.service.
#
# Livebook executes arbitrary Elixir, so it is PASSWORD PROTECTED out of the box.
# Open the Web UI below and sign in with LIVEBOOK_PASSWORD.
#
LIVEBOOK_PASSWORD=<generated on your instance>
LIVEBOOK_URL=https://<your-instance-address>/
LIVEBOOK_COOKIE=<generated on your instance>
Confirm the file is readable only by root:
sudo stat -c '%a %U:%G' /root/livebook-credentials.txt
This reports 600 root:root.
Step 5: Confirm the Services Are Running
Two units serve the product: livebook.service and nginx.service.
systemctl is-active livebook nginx
Both report active.
Confirm the installed versions:
cat /opt/livebook/VERSION
livebook_version=0.19.8
erlang_otp=28.5.0.3
elixir=1.20.2
The Elixir and Erlang runtimes are on the default PATH:
elixir --version | grep -E '^Elixir '
erl -noshell -eval 'io:format("OTP ~s~n",[erlang:system_info(otp_release)]), halt().'
These report Elixir 1.20.2 (compiled with Erlang/OTP 28) and OTP 28.
Confirm that the notebook server is bound to the loopback interface only, and that nginx is the sole network facing listener:
ss -tln | grep -E ':(80|443|8080|8081) ' | awk '{print $1,$4}'
Ports 8080 and 8081 appear only as 127.0.0.1, while 80 and 443 are published.
Check the health endpoints. The /healthz endpoint on port 80 is unauthenticated and is intended for load balancer probes; /public/health is Livebook's own health endpoint served over HTTPS.
curl -s -o /dev/null -w 'http :80/healthz: %{http_code}\n' http://127.0.0.1/healthz
curl -s -o /dev/null -w 'http :80/: %{http_code}\n' http://127.0.0.1/
curl -ks -o /dev/null -w 'https :443/public/health: %{http_code}\n' https://127.0.0.1/public/health
curl -ks -o /dev/null -w 'https :443/ unauthenticated: %{http_code}\n' https://127.0.0.1/
These report 200, 301, 200 and 302 respectively. The 301 is the redirect from HTTP to HTTPS. The 302 on the last line is the authentication wall: an unauthenticated request for a notebook is redirected to the sign-in page, never served.
You can prove the whole authentication path end to end at any time. The image ships a self test that reads the per instance password, drives the sign-in form, and confirms that an authenticated request succeeds while an unauthenticated one does not.
sudo /opt/livebook/livebook-selftest.sh
round-trip OK: health=200, unauth GET /=302 (protected), authenticated GET /=200 - per-instance password proven over TLS
Step 6: Sign In to Livebook
Open https://<public-ip>/ in your browser. The certificate is self signed and generated for this instance, so your browser will warn on the first visit; accept it to continue, or follow Step 10 to install a certificate from a public authority.
Livebook presents its authentication wall. Enter the LIVEBOOK_PASSWORD from Step 4.

After signing in you land on the Livebook home screen, which lists your notebooks, the learning notebooks that ship with Livebook, and any running sessions.

Step 7: Open a Notebook and Evaluate a Cell
A sample notebook ships on the data volume at /var/lib/livebook/notebooks/welcome.livemd. Confirm it is present:
ls /var/lib/livebook/notebooks/
From the Livebook home screen choose Open, then browse to /var/lib/livebook/notebooks and select welcome.livemd. The notebook opens with its Markdown prose rendered and its Elixir code cells ready to run.

Select Evaluate on the first code cell, or press Ctrl (or Cmd) and Enter with the cursor in the cell. Livebook starts a notebook runtime, evaluates the cell on the BEAM, and renders the result inline beneath it.

Choose New notebook on the home screen to start your own. Save it into /var/lib/livebook/notebooks so that it lives on the dedicated data volume.
Step 8: The Data Volume
Notebooks and Livebook's internal state live on a dedicated EBS volume mounted at /var/lib/livebook, separate from the operating system disk so it can be resized, snapshotted and restored independently.
findmnt -no SOURCE,TARGET,FSTYPE,SIZE /var/lib/livebook
df -h /var/lib/livebook | tail -1
The mount is referenced in /etc/fstab by filesystem UUID rather than by device name, because NVMe device names are not stable across reboots.
grep livebook /etc/fstab
Two environment settings in livebook.service point Livebook at this volume: LIVEBOOK_HOME is /var/lib/livebook/notebooks, which is the directory the file browser opens in, and LIVEBOOK_DATA_PATH is /var/lib/livebook/data, where Livebook keeps its own state.
To grow the volume, expand it in the EC2 console or with aws ec2 modify-volume, then extend the filesystem in place with sudo resize2fs /dev/<device>.
Step 9: Rotate the Access Password
The password is read from /opt/livebook/livebook.env at service start. To rotate it, set a new value in that file, mirror it into your record at /root/livebook-credentials.txt, and restart the service. Existing browser sessions are invalidated.
The block below is shown for reference and is not run as part of this walkthrough, because it changes the credential on the instance you are reading this from. Substitute your own new password for <new-password>:
sudo sed -i 's/^LIVEBOOK_PASSWORD=.*/LIVEBOOK_PASSWORD=<new-password>/' /opt/livebook/livebook.env
sudo sed -i 's/^LIVEBOOK_PASSWORD=.*/LIVEBOOK_PASSWORD=<new-password>/' /root/livebook-credentials.txt
sudo systemctl restart livebook
Both files must carry the same value, because the self test reads the credentials file while the service reads the environment file. Confirm the new password authenticates:
sudo /opt/livebook/livebook-selftest.sh
The LIVEBOOK_COOKIE value in the same file is the Erlang distribution cookie. Change it only if you intend to cluster this node with other BEAM nodes, and keep it secret.
Step 10: Replace the Self Signed Certificate
The certificate generated at first boot is self signed, which is why browsers warn on the first visit. For anything beyond evaluation, point a DNS name at the instance and install a certificate from a public authority.
Install certbot and request a certificate, replacing <your-domain> with your DNS name and <your-email> with your contact address:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain> -m <your-email> --agree-tos --no-eff-email
Certbot edits the nginx server block in place and installs a renewal timer. The reverse proxy configuration, including the WebSocket upgrade headers Livebook needs, is at /etc/nginx/sites-available/cloudimg-livebook. If you edit it by hand, test before reloading:
sudo nginx -t
An equally good alternative is to terminate TLS on an Application Load Balancer in front of the instance and leave the instance certificate in place for the internal hop.
Step 11: Backup and Maintenance
Because notebooks are plain text .livemd files on a dedicated volume, backup is straightforward. Take EBS snapshots of the /var/lib/livebook volume on a schedule, or sync the notebook directory to Amazon S3:
sudo tar -czf /tmp/livebook-notebooks.tar.gz -C /var/lib/livebook notebooks
Copy the resulting archive off the instance, then remove it:
sudo rm -f /tmp/livebook-notebooks.tar.gz
The image ships with unattended security updates enabled, exactly as stock Ubuntu.
When troubleshooting, confirm that the notebook server logged a successful start:
sudo journalctl -u livebook --no-pager | grep -c 'Application running at'
A count of one or more means the server bound its port and came up. To read the full service log, including any evaluation errors reported by a notebook runtime, use:
sudo journalctl -u livebook --no-pager -n 200
To restart the product cleanly:
sudo systemctl restart livebook nginx
systemctl is-active livebook nginx
Support
cloudimg provides 24/7 technical support for this image by email and live chat at support@cloudimg.co.uk. Include your instance ID and AWS Region to speed up troubleshooting.
Livebook, Elixir and Erlang are trademarks of their respective owners. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.