Wiki Discussion: Use SWI-Prolog DockerHub image

This is a topic to discuss the Wiki

Use SWI-Prolog DockerHub image


Remote development using Docker, WSL 2, Visual Studio Code and X-windows server

This is a work in progress but since the proof of concept is working will post here.

Since I prefer to develop SWI-Prolog using Visual Studio Code, all the development has been done on a single Windows machine. Now all of that can change to doing development with multiple Docker containers including the machine where the SWI-Prolog code is hosted and run. The only things remaining on the Windows side is Visual Studio Code and an X11 server. While this will run the Docker containers using WSL on the Windows machine, it is just a simple exercise to move the Docker containers to other host and and all should still work. Also since the machines are Docker containers, they can easily be created with a Dockerfile, and since a Dockerfile is small in comparison to the footprint of a virtual machine and all in text, the Dockerfiles can easily be put in revision control such as Git and even made public on GitHub. So this means that now you can not only share the code but the entire tool chain and environment with a few added text files; however as noted somethings in this scenario are constants: Docker, Visual Studio Code, and for SWI-Prolog GUI tools the need for X-windows server.

What follows is essentially Remote development in WSL modified to demonstrated the same with SWI-Prolog.

Install Visual Studio Code

Install Windows Terminal

Install a Windows X-windows server (I use VcXsrv)

Start X11 server.

For VcXsrv configuration:

   Multiple windows
   Display number: -1
   Start no client
   Clipboard
      Primary Selection
   Native opengl
   Disable access control (TODO: This should not be used, use firewall rules etc.)

Follow the steps in Remote development in WSL until you get to Python development.

Add Ubuntu to Windows Terminal
Using Windows Terminal open settings

Th will need a new GUID.
Using Windows PowerShell

[guid]::NewGuid()

which will generate GUID

Guid
----
d23fb715-097c-4f16-89dd-98569e048fba

Do not use the one where demonstrated above as a GUID need to be a Globally Unique ID, (GUID).

For "list": add something like (Don’t ask me to much on this I barely understand the details)

{
	"guid": "{9e7de027-0fca-5811-94e7-9e6d96b5b97f}",
	"hidden": false,
	// Ubuntu 20.04
	// Based on Docker image
	"name": "SWI-Prolog",
	"source": "Windows.Terminal.Wsl",

	// start SWI-Prolog
	// "commandline": "wsl.exe -u eric -d Ubuntu_SWI-Prolog swipl",

	// defaults to starting bash
	"commandline": "wsl.exe -u <user> -d Ubuntu_SWI-Prolog",

	"startingDirectory" : "//wsl$/Ubuntu_SWI-Prolog/home/<user>",
	"icon": "C:\\Program Files\\swipl\\swipl.ico"
}

where you will need to change <user> to your user name.
Note: I duplicated then modified the WSL Ubuntu distro using the WSL import and export so that I could have a distro specifically for SWI-Prolog. (TODO: Create a Dockerfile for the distro.)

Install Visual Studio Code extension: Remote - WSL

Using Windows Terminal start WSL distro by clicking image and then selecting SWI-Prolog from drop down list.

Using WSL SWI-Prolog distro

Verify SWI-Prolog is installed and working

eric@WINDOWS-6F874NS:~$ swipl --version
SWI-Prolog version 8.3.10 for x86_64-linux

Verify current directory

eric@WINDOWS-6F874NS:~$ pwd
/home/eric

Make directory for development

eric@WINDOWS-6F874NS:~$ mkdir -p projects/SWI-Prolog/helloWord && cd projects/SWI-Prolog/helloWord
eric@WINDOWS-6F874NS:~/projects/SWI-Prolog/helloWord$

Make simple Hello World style predicate for demonstration purposes

eric@WINDOWS-6F874NS:~/projects/SWI-Prolog/helloWord$ echo ":- write('Hello from SWI-Prolog on Ubuntu on Windows\u0021\n')." > hello.pl

Demonstrate predicate

eric@WINDOWS-6F874NS:~/projects/SWI-Prolog/helloWord$ swipl --quiet -g halt hello.pl
Hello from SWI-Prolog on Ubuntu on Windows!

Startup Visual Studio Code set to this directory

eric@WINDOWS-6F874NS:~/projects/SWI-Prolog/helloWord$ code .
/mnt/c/Program Files/Microsoft VS Code/bin/code: 46: cannot create /tmp/remote-wsl-loc.txt: Permission denied
Installing VS Code Server for x64 (d2e414d9e4239a252d1ab117bd7067f125afd80a)
Downloading: 100%
Unpacking: 100%
Unpacked 2357 files and folders to /home/eric/.vscode-server/bin/d2e414d9e4239a252d1ab117bd7067f125afd80a.
eric@WINDOWS-6F874NS:~/projects/SWI-Prolog/helloWord$

In Visual Studio Code

Install extension: VSC-Prolog

Using VS Code change to the extensions panel by clicking image in the left panel.
In the extensions search input image enter prolog

image

For VSC-Prolog click image

Switch the left panel back to the files view by clicking image

Create file: path.pl

% From: https://www.cpp.edu/~jrfisher/www/prolog_tutorial/2_15.html

edge(1,2).
edge(1,4).
edge(1,3).
edge(2,3).
edge(2,5).
edge(3,4).
edge(3,5).
edge(4,5).

connected(X,Y) :- edge(X,Y).
connected(X,Y) :- edge(Y,X).

path(A,B,Path) :-
       travel(A,B,[A],Q),
       reverse(Q,Path).

travel(A,B,P,[B|P]) :-
       connected(A,B).
travel(A,B,Visited,Path) :-
       connected(A,C),
       C \== B,
       \+member(C,Visited),
       travel(C,B,[C|Visited],Path).

Since there is invalid configuration for VSC-Prolog that is not allowing the linter to work, a output panel will open with the message:

`Cannot lint the prolog file. The Proog executable was not found. Use the ‘prolog.executablePath’ setting to configure

To fix this

From the menu select File > Preferences > Settings

image

For Search settings enter prolog

image

Select Remote [...]

image

For Prolog: Executable Path remove /usr/bin/siwpl so that value is empty.
image

Close the settings panel

Open terminal (Ctrl+`)

Start SWI-Prolog

root@WINDOWS-6F874NS:~/projects/SWI-Prolog/helloWord# swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.10)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

Consult file: path.pl

?- [path].
true.

List the predicate path

?- listing(path).
path(A, B, Path) :-
    travel(A, B, [A], Q),
    reverse(Q, Path).

Run the predicate path

?- path(1,5,P).
P = [1, 2, 5] ;
P = [1, 2, 3, 5] ;
P = [1, 2, 3, 4, 5]
...

Trace the predicate path

?- trace,path(1,5,P).
   Call: (11) path(1, 5, _30240) ? creep
   Call: (12) travel(1, 5, [1], _30780) ? creep
   Call: (13) connected(1, 5) ? creep
   Call: (14) edge(1, 5) ? creep
   Fail: (14) edge(1, 5) ? creep
   Redo: (13) connected(1, 5) ? creep
   Call: (14) edge(5, 1) ? creep
   Fail: (14) edge(5, 1) ? creep
   Fail: (13) connected(1, 5) ? creep
   Redo: (12) travel(1, 5, [1], _30780) ? creep
   Call: (13) connected(1, _31202) ? creep
   Call: (14) edge(1, _31202) ? creep
   Exit: (14) edge(1, 2) ? creep
   Exit: (13) connected(1, 2) ? creep
   Call: (13) 2\==5 ? creep
   Exit: (13) 2\==5 ? creep
   Call: (13) lists:member(2, [1]) ? creep
   Fail: (13) lists:member(2, [1]) ? creep
   Redo: (12) travel(1, 5, [1], _30780) ? creep
   Call: (13) travel(2, 5, [2, 1], _30780) ? creep
   Call: (14) connected(2, 5) ? creep
   Call: (15) edge(2, 5) ? creep
   Exit: (15) edge(2, 5) ? creep
   Exit: (14) connected(2, 5) ? creep
   Exit: (13) travel(2, 5, [2, 1], [5, 2, 1]) ? creep
   Exit: (12) travel(1, 5, [1], [5, 2, 1]) ? creep
   Call: (12) lists:reverse([5, 2, 1], _30240) ? creep
   Exit: (12) lists:reverse([5, 2, 1], [1, 2, 5]) ? creep
   Exit: (11) path(1, 5, [1, 2, 5]) ? creep
P = [1, 2, 5] ;
   Redo: (14) connected(2, 5) ? 
...

To use gtrace which uses X-windows a few system variables need to be configured.
Reference: How to set up working X11 forwarding on WSL2

Edit .bashrc

Check for existing export DISPLAY and export LIBGL_ALWAYS_INDIRECT, there should be none. If there are some and they are not like the following edit, I have not idea on how to make the change.

At the end of the file add

export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=1

In the terminal with swipl running
halt swipl

Switch user to <user>

root@WINDOWS-6F874NS:/home/eric# su eric
eric@WINDOWS-6F874NS:~$

Apply the changes to .bashrc

eric@WINDOWS-6F874NS:~$ . ~/.bashrc

Start swipl again

eric@WINDOWS-6F874NS:~/projects/SWI-Prolog/helloWord$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.10)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?-

Using SWI-Prolog verify predicate works

 [path].
true.

?- path(1,5,P).
P = [1, 2, 5] ;
P = [1, 2, 3, 5] ;
P = [1, 2, 3, 4, 5] 
...

Using SWI-Prolog use gtrace/0 with predicate which should automatically start up X-window with SWI-Prolog gtrace running in it.

?- gtrace,path(1,5,P).
% The graphical front-end will be used for subsequent tracing
P = [1, 2, 5] ;
...

Errors (Included here so that they can be indexed by search engines such as Google)

?- gtrace,path(1,5,P).
% The graphical front-end will be used for subsequent tracing
[PCE fatal: @display/display: Failed to connect to X-server at `': no DISPLAY environment variable
*********************************************************************
* You MUST be running the X11 Windowing environment.  If you are,   *
* check the setting of your DISPLAY environment variable as well    *
* the access rights to your X11 server.  See xauth(1) and xhost(1). *
*********************************************************************
        in:     <No exception goal>
]
Host stack:
 [15] pce_principal:send(@emacs_mark_list/emacs_bookmark_editor, append(new(_12646, dialog)))
 [14] Send-method on @emacs_mark_list/emacs_bookmark_editor: emacs_bookmark_editor->initialise
 [13] '$c_call_prolog'
 [12] pce_principal:new(@emacs_mark_list/emacs_bookmark_editor, emacs_bookmark_editor)
 [11] Send-method on @emacs/emacs: emacs->initialise(@emacs_buffers/dict)
% The following threads wouldn't die: [main]
Personal Notes

References:
Official Images on Docker Hub
Overview of Docker Compose
Develop with Docker
Guidelines for Linux package managers - Why are executables named what they are, e.g. swipl, what are the types of packages that should be created, e.g. swi-prolog-nox
Containers on Windows documentation
Open Container Initiative - Think Docker or VXD, this is open source.
Deploy a registry server - Think private DockerHub on PC
What you need to know about upcoming Docker Hub rate limiting
Checking Your Current Docker Pull Rate Limits and Status
The great Docker split
Docker Newsletter
Introduction to Containers
systemctl failed to connect to bus - docker
A Practical Introduction to Container Terminology
SO Docker tag info
GoogleContainerTools
GoogleContainerTools/container-diff
Docker Engine API (Using JSON data format)
How do I connect to the remote Docker Engine API? (Running on Windows OS)
Using Docker Engine API securely
Working with Docker APIs
PSA: Beware of Exposing Ports in Docker
How do you mount the docker socket on Windows?
Docker Tips : about /var/run/docker.sock
https://www.linuxserver.io/ - We are a group of like minded enthusiasts from across the world who build and maintain the largest collection of Docker images on the web.
linuxserver/code-server - Code-server is VS Code running on a remote server, accessible through the browser.
UNIX Domain Sockets
UNIX domain sockets
Unix domain sockets vs. internet sockets
Play with Docker Classroom
Capture the X11 protocol’s traffic
Gist using /var/run/docker.sock with socat and nc.
Docker Internals - a blog.
Docker Registry
GitHub Docker Registry
Implementing a Self-Hosted Docker Registry on Raspberry Pi
ubuntu running under WSL2 not seeing Docker daemon at unix:///var/run/docker.sock - Use docker context ls then docker ps
Installing various versions of PowerShell
Install .NET on Linux
Daemon socket option - The Docker daemon can listen for Docker Engine API requests via three different types of Socket: unix, tcp, and fd.
Update DISPLAY env for already running docker containers for X11 forwarding over SSH
Manage sensitive data with Docker secrets
Best Docker Support Resources for Troubleshooting
Kubernetes is dropping Docker support?!
Don’t Panic: Kubernetes and Docker
Dockershim Deprecation FAQ
Kubernetes Documentation
Introducing Container Runtime Interface (CRI) in Kubernetes
Start coding in seconds on GitHub with Codespaces


Running both Windows and Linux containers at the same time

Running Docker Windows and Linux Containers Simultaneously - As the blog is 2 years old this might have significantly changed, but this is the best article I have seen so far.
Win10+Docker: Hybrid swarm on the Desktop - This one has more details but you need to link to other blogs to get even more of the detail. Have not tried this example yet.


Docker Desktop for Windows user manual - resources

Configurations

  • Linux containers in WSL 2 mode
  • Linux containers in Hyper-V mode
  • Windows containers.

Windows base OS images - These are Docker images that use the Windows OS and not a Linux OS. These only run on a host with a Windows OS installed as you need a Windows OS license and the Docker images use the license of the host OS.
Windows container version compatibility
Windows 10 release information


Software to compare Windows system snapshots
8 Tools to Track Registry and File Changes by Comparing Before and After Snapshots
docker diff - Only does files names not contents of files such as log files or the registry.
SO Q&A Docker difference between two containers - Comment notes: export both containers, untar them and run a diff


Use Docker Compose

Also, for single-container scenarios, using Docker Compose provides tool-independent configuration in a way that a single Dockerfile does not. Configuration settings such as volume mounts for the container, port mappings, and environment variables can be declared in the docker-compose YML files.


Uses:
For teachers needing to help their students create their first tool-chain for a development environment. Also with Visual Studio Code in the mix and some associated extensions, the students can collaborate with each other or the teacher with the student(s), e.g. Introducing Visual Studio Live Share, Live Share Extension Pack, Development Containers in Education: A Guide for Instructors

A current question is if a teacher wants to review and comment on the current code of a student, then where should the code be stored and how? Since each student could have a separate directory on a common server then how does the teacher bring up each students work and then quickly switch to the next students work without leaving the development environment?

See:
Working with Containers
Adding another local file mount

The Remote - Containers extension supports two primary operating models:


VS Code Working with containers
VS Code Remote Development
microsoft/vscode-remote-try-java
Developing inside a Container
Remote development in Containers
VS Code extension: Remote - SSH
VS Code extension: Remote - WSL


LXD is not the same as Docker, but you can try LXD online
LXD vs Docker
List of Linux containers
OS-level virtualization
Microservices

Seems the docker is a bit outdated. I’m going to release 8.2.3 soon, after which docker needs to be updated to the current stable/devel versions. Is someone willing to take action to this and ensure the Docker images are kept up-to-date?

I would but I don’t know if that is necessary.

AFAIK if one uses a Dockerfile and just builds from the Dockerfile when the SWI-Prolog PPA is updated they would have a valid and up to date Docker container for SWI-Prolog. Still plan to check this out but also checking out LXC and LXD.

Yes, it is. To be an official Docker library we need to create a new directory in https://github.com/SWI-Prolog/docker-swipl, verify all builds and works nicely and complies to the Docker library policies and get it accepted by Docker.

Using the PPA as a basis is an interesting idea. It has a couple of issues though. First of all, the Dockers are based on Debian rather than Ubuntu and the content of the Docker file is geared towards using Prolog in server settings while the PPA is mostly for developers. As a result, the Docker version lacks xpce (graphics) and comes with additional database drivers (e.g. rocksdb).

1 Like

This is not to disagree that there should be an SWI-Prolog Docker image at DockerHub as I think there should be one.

These are just some rhetorical questions and thoughts I have with regards to the SWI-Prolog Docker image at DockerHub; these will give you some idea of what I am thinking.

  1. A Docker container is suppose to be stateless but how many users understand this?
  2. A Docker container is not an Virtual Machine but how many users understand this?
  3. Is anyone using the SWI-Prolog Docker image on DockerHub?
  4. Do people think the SWI-Prolog Docker image is a substitute for SWISH?
  5. Should there also be a slim version of the SWI-Prolog Docker image on DockerHub?
  6. There are other Docker images used with SWI-Prolog should these be on DockerHub?
  7. How are other providers of DockerHub images related to programming languages updating their Docker Image? Are they using continuous integration?
  8. It would be nice if there were a demonstration project using the SWI-Prolog DockerHub image; personally I like using DCGs and think that using them as Lint/format/pretify/etc. tools for multiple variations of structured syntax would make for a nice demo. You build a web site using Docker containers with one being the SWI-Prolog DockerHub image, then the web page accepts an input file and a selected syntax and that is passed to the SWI-Prolog Docker container that parses the input and returns the desired result, e.g. valid, formatted, version, etc. Something like JSONLint, HTML Formatter, Markup Validation Service, etc.
    Note: The SWISH Dockerfile uses the swipl DockerHub image.
  9. What does it take to update a Docker image at DockerHub? (ref)

Please do not respond to these as I am not looking to start a long discussion, these are just some questions and thoughts I have and will work through them while solving my problem.