Run an Erlang app
In this guide we create and deploy a simple Erlang-based HTTP web server. To run this example, follow these steps:
-
Install the
kraft
CLI tool and a container runtime engine, e.g. Docker. -
Clone the
examples
repository andcd
into theexamples/http-erlang26.2/
directory:
git clone https://github.com/kraftcloud/examplescd examples/http-erlang26.2/
Make sure to log into Unikraft Cloud by setting your token and a metro close to you.
We use fra0
(Frankfurt, 🇩🇪) in this guide:
# Set Unikraft Cloud access tokenexport UKC_TOKEN=token# Set metro to Frankfurt, DEexport UKC_METRO=fra0
When done, invoke the following command to deploy this application on Unikraft Cloud:
kraft cloud deploy -p 443:8080 -M 512 .
The output shows the instance URL and other details:
[●] Deployed successfully! │ ├────────── name: erlang-sw2bp ├────────── uuid: 1c4a8a51-fb61-45fc-87b8-26d192a7c2bc ├───────── state: starting ├──────── domain: https://patient-field-ck629j2u.fra0.kraft.host ├───────── image: erlang@sha256:d99feefa7973ba43f726356497f54c34a16421aa25a27fa547d2c1add418204e ├──────── memory: 512 MiB ├─────── service: patient-field-ck629j2u ├── private fqdn: erlang-sw2bp.internal ├──── private ip: 172.16.3.3 └────────── args: /usr/bin/wrapper.sh /usr/bin/erl -noshell -s http_server
In this case, the instance name is erlang-sw2bp
and the URL is https://patient-field-ck629j2u.fra0.kraft.host
.
They are different for each run.
Use curl
to query the Unikraft Cloud instance of the Erlang-based HTTP web server:
curl https://patient-field-ck629j2u.fra0.kraft.host
Hello, World!
At any point in time, you can list information about the instance:
kraft cloud instance list
NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIMEerlang-sw2bp patient-field-ck629jsu.fra0.kraft.host running since 35secs erlang@sha256:d99feefa7973ba43f72... 512 MiB /usr/bin/wrapper.sh /usr/bin/erl -noshell -s http_se... 404.04 ms
When done, you can remove the instance:
kraft cloud instance remove erlang-sw2bp
Customize your Application
To customize the application, update the files in the repository, listed below:
http_server.erl
: the actual Erlang HTTP serverKraftfile
: the Unikraft Cloud specificationDockerfile
: the Docker-specified application filesystem
-module(http_server).-export([start/0]).
start() ->spawn(fun () -> {ok, Sock} = gen_tcp:listen(8080, [{active, false}]), loop(Sock) end).
loop(Sock) ->{ok, Conn} = gen_tcp:accept(Sock),Handler = spawn(fun () -> handle(Conn) end),gen_tcp:controlling_process(Conn, Handler),loop(Sock).
handle(Conn) ->gen_tcp:send(Conn, response("Hello, World!\n")),gen_tcp:close(Conn).
response(Str) ->B = iolist_to_binary(Str),iolist_to_binary( io_lib:fwrite( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: ~p\r\n\r\n~s\r\n", [size(B), B])).
spec: v0.6
name: erlang
runtime: base-compat:latest
rootfs: ./Dockerfile
cmd: ["/usr/bin/wrapper.sh", "/usr/bin/erl", "-noshell", "-s", "http_server"]
FROM erlang:26.2.3.0-slim as build
WORKDIR /src
#COPY ./helloworld.erl .COPY ./http_server.erl .
RUN /usr/local/bin/erl -compile http_server
FROM alpine:3 AS sys
RUN set -xe; \mkdir -p /target/etc; \mkdir -p /blank; \apk --no-cache add \ ca-certificates \ tzdata \; \update-ca-certificates; \ln -sf /usr/share/zoneinfo/Etc/UTC /target/etc/localtime; \echo "Etc/UTC" > /target/etc/timezone;
FROM scratch
COPY --from=sys /target/etc /etcCOPY --from=sys /usr/share/zoneinfo/UTC /usr/share/zoneinfo/UTCCOPY --from=sys /usr/share/zoneinfo/Etc/UTC /usr/share/zoneinfo/Etc/UTCCOPY --from=sys /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crtCOPY --from=sys /blank /tmp
COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6COPY --from=build /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6COPY --from=build /lib/x86_64-linux-gnu/libsctp.so.1 /lib/x86_64-linux-gnu/libsctp.so.1COPY --from=build /lib/x86_64-linux-gnu/libstdc++.so.6 /lib/x86_64-linux-gnu/libstdc++.so.6COPY --from=build /lib/x86_64-linux-gnu/libtinfo.so.6 /lib/x86_64-linux-gnu/libtinfo.so.6COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
COPY --from=build /lib/x86_64-linux-gnu/libselinux.so.1 /lib/x86_64-linux-gnu/libselinux.so.1COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6COPY --from=build /lib/x86_64-linux-gnu/libpcre2-8.so.0 /lib/x86_64-linux-gnu/libpcre2-8.so.0COPY --from=build /bin/rm /bin/rmCOPY --from=build /bin/mknod /bin/mknod
COPY --from=build /usr/local/bin/erl /usr/bin/erlCOPY --from=build /usr/local/lib/erlang /usr/local/lib/erlang
COPY --from=build /usr/bin/dirname /usr/bin/dirnameCOPY --from=build /usr/bin/basename /usr/bin/basename
COPY --from=build /bin/bash /bin/bashCOPY --from=build /bin/sh /bin/sh
COPY --from=build /src/http_server.beam /usr/src/http_server.beam
COPY ./wrapper.sh /usr/bin/wrapper.sh
The following options are available for customizing the application:
-
If only updating the implementation in the
http_server.erl
source file, no other change is required. -
If new files are added, these have to be copied in the application filesystem, using the
COPY
command in theDockerfile
. -
If a new Erlang source files is added, update the
cmd
line in theKraftfile
and replacehttp_server.erl
to run that file when creating the instance. -
More extensive changes may require expanding the
Dockerfile
with additionalDockerfile
commands.
Learn More
Use the --help
option for detailed information on using Unikraft Cloud:
kraft cloud --help
Or visit the CLI Reference.