Deploying Your Prolog API with Docker
28 June 2024 2 Minutes History Languages DeploymentIt can be tough living on the bleeding edge of modern technology. If you've jumped on the hype train and developed your latest API with Prolog only to find there aren't any tutorials to Dockerize it - look no further!
Prolog is truly a leader at the forefront of modern technology, and if you're anything like me then you're convinced that this langauge is the way forward for our microservice APIs. Part of our evidence for this (as though it isn't inherently obvious) is how easy it is to containerize and deploy with Docker.
To demonstrate this, let's set up a simple Hello World API with SWI Prolog:
% Import SWI modules for HTTP servers:- use_module(library(http/thread_httpd)).:- use_module(library(http/http_dispatch)).:- use_module(library(http/html_write)).% Set handle_request as the handler for URL /:- http_handler('/', handle_request, []).% Respond "Hello, World!" to requestshandle_request(_Request) :- format('Content-type: text/plain~n~n'), format('Hello, World!').% Start the server listening to localhost:Portserver(Port) :- http_server(http_dispatch, [port(Port)]), % Spin while waiting for the next message thread_get_message(_).
There's a couple things to point out here. First, accepting a Port
variable for the server
predicate allows us to keep the port flexible as an environment variable, best to not hardcode that. Second, invoking the thread_get_message
predicate isn't necessary when we're debugging locally but it is going to be necessary when we run it in Docker to prevent the server from halting immediately.
The dockerfile isn't terribly difficult at all. We can base off of ubuntu:latest
, install SWI Prolog, and then run the command to start the prolog interpreter with the call to the server
predicate:
# Use an official Ubuntu runtime as a parent imageFROM ubuntu:latest# Set the working directoryWORKDIR /usr/src/app# Install SWI-PrologRUN apt-get update && \ apt-get install -y software-properties-common && \ apt-add-repository ppa:swi-prolog/stable && \ apt-get update && \ apt-get install -y swi-prolog# Copy the current directory contents into the container at /usr/src/appCOPY . .# Make port 5000 available to the world outside this containerEXPOSE 5000# Run swipl when the container launchesCMD ["swipl", "-g", "server(5000)", "-t", "halt", "server.pl"]
I'm hardcoding 5000
as the HTTP port here but it's just as easy to use an environment variable at this point. Note too I'm assuming the source is in server.pl
.
With this we can build the image:
docker build -t prolog-server .
And deploy:
docker run -p 5000:5000 prolog-server
And that's it, we're off to the races! With dev ex this smooth, Prolog will concur the world. Any day now. Surely.