This chapter describes how and why the various items are built.
Item
build tool
Purpose
Stack
build a binary on MacOS or Windows
Docker
build a Docker image for the Ampersand compiler
Application
Docker
build a Docker image for an application generated by Ampersand.
RAP
Docker
build a Docker image for RAP
Docker Cloud
explains the automated build process that produces up-to-date images on docker cloud.
If you need an Ampersand compiler in a Docker image, use the one on Docker hub. It sits there ready for you to use. However, if you want to know how it is baked, carry on reading.
To get a docker container I took the file Dockerfile and built an image called "myampersand", using the following command:
It took 45 minutes to build, but I got an image called myampersand
in the docker repository on my laptop.
To see it work, I executed the newly created image on a little file in my working directory, hello.adl
from the command line with the following command:
The same command in the Windows command line is:
The Ampersand repository contains a file, Dockerfile, that contains a recipe for building an Ampersand compiler and put it in your Ampersand repository. You need the following ingredients to run it:
A machine to run docker, for building your docker image with. I ran it on my MacBook.
Docker, which you need installed on your machine.
Docker needs least 5G of memory to build Ampersand, which is more than the standard 2G. I used this instruction to increase Docker's memory on my Macbook.
To run it, I cloned the Ampersand repository, into ~/Ampersand/
, and built the image with:
It runs on my Mac for over half an hour, so some patience is required. If you don't have that patience, consider using the image ampersandtarski/ampersand from docker hub. It was built for your convenience.
The resulting docker image sits in the docker repository on you laptop (placed there when docker was installed).
If you want a slightly different image (for reasons of your own), you may want to repeat this process yourself. For that purpose, let us walk through the different steps described in Dockerfile.
Let us discuss the steps one-by-one. (Please check the Dockerfile, just in case it is inconsistent with this documentation.) All of these steps happen automatically, as they are in the docker file.
The first statement states that the compiler is built on a well-defined Haskell image.
This building stage is called buildstage because we want to use a 2-stage build to obtain a small Ampersand image without excess-software.
We decide to work in the build-container from a working directory called /Ampersand
.
Normally we want to generate Ampersand from the source code on GitHub. For this purpose we clone the Ampersand-repository into the (working directory in the) build environment.
In this case I wanted to build from a specific feature, so I checked it out.
Now everything is in place to compile Ampersand. Running stack install
results in a full-fledged Ampersand compiler in /root/.local/bin
. Mind you, this takes a while...
If we were to stop here, we get an image larger than 4GB. We can do better than that by starting over with a clean machine. So we introduce a second FROM
-line in the Dockerfile which starts with a clean slate. We use an empty ubuntu machine (form some reason yet unknown, the smaller alpine image doesn't work)
Now we must copy the ampersand executable to /bin
, from where we can run it as though it were a normal ubuntu-command. It is the only software we will copy into this image. (Haskell and the intermediate files are all absent). This results in an image that is slightly over 220MB.
When compiling, we will work in a directory called scripts. When using this container, we will volume-map this directory to the actual working directory that contains the ampersand-files we want to compile.
The program to be called when running the container is of course ampersand
(residing in /bin/
). If called without arguments it will use --verbose
.
To build your own Ampersand compiler is something to avoid as a user. As a developer, however, you may have reasons to do this yourself. For instance to verify what happens in older versions.
The Ampersand compiler is a Haskell program built with stack. Stack is a build tool for Haskell projects such as Ampersand. We have automated the building process (using stack) for the following purposes:
to prevent mistakes such as dependency conflicts inside and between Haskell packages, for an uninterrupted compilation process (robust building);
to generate ampersand compilers for different platforms (platform independence);
to provide a reproducible and reliable build process to developers with diverse development tools, operating systems, and working environments (uniform building);
to allow for generating images for docker containers (containerization);
to accellerate the build process to increase the release frequency of Ampersand.
Haskell comes as part of Stack, so there is no need to install Haskell separately.
The instructions to install Stack are pretty clear for the various platforms. Make sure you read the part about the STACK_ROOT environment variable.
To compile Ampersand you need a file package.yaml, which sits in the Ampersand repository. Fetch it and put it in you working directory. From the command-line, call command stack install
and after a while (go get coffee!) your ampersand compiler exists! NB: If you want to build Rieks' preprocessor as well, the magic spell is stack install --flag ampersand:buildAll
If you want to test your application on your own laptop, you need to configure localhost to let it behave like a regular top-level domain.
The proper use of Docker ensures that your application will run on any location on the internet. Yet, when testing your application on your laptop, you may discover that your laptop is not configured as a domain on the internet. To run any Ampersand application locally without changes, your laptop must behave like an ordinary top-level domain: localhost
. Your computer must believe that localhost
is like com
, or edu
, or nl
. All requests from your browser(s) to localhost
must be routed to IP-address 127.0.0.1
, which is your laptop.
When the following experiments are successful on your computer, you may consider this requirement to be fulfilled
First demonstrate that an arbitrary internet domain (here: nu.nl
) is visible.
> ping -c 1 nu.nl
PING nu.nl (99.86.122.115): 56 data bytes 64 bytes from 99.86.122.115: icmp_seq=0 ttl=232 time=24.367 ms
--- nu.nl ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 24.367/24.367/24.367/0.000 ms
Now demonstrate that localhost
is routed to IP-address 127.0.0.1
.
> ping -c 1 localhost
PING localhost (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.040 ms
--- localhost ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.040/0.040/0.040/0.000 ms
Then demonstrate that an arbitrary subdomain of localhost
is routed to IP-address 127.0.0.1
.
> ping -c 1 rap.localhost
PING rap.localhost (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.029 ms
--- rap.localhost ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.029/0.029/0.029/0.000 ms
Finally, show that this works recursively on an arbitrary sub-subdomain.
> ping -c 1 foo.rap.localhost
PING foo.rap.localhost (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.032 ms
--- foo.rap.localhost ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.032/0.032/0.032/0.000 ms
So why should this NOT work?
Your machine might not be connected to the internet. And if it is connected, it needs access to a domain name server to find locations on the internet. For most laptops this is the case, so you have no problems here. Some corporate laptops are connected only to the local corporate network. This means that you cannot let your application communicate with the outside world, or you have to organize that your laptop gains access (e.g. through a proxy).
You cannot run your application locally if localhost
is not configured. On some laptops there is a file called hosts
or .hosts
, which contains the redirection from localhost
to IP-address 127.0.0.1
. However, this redirection does not cater for subdomains. Consider this to partially fulfill the requirement, which is sufficient if your application works without subdomains.
If your application works with subdomains, localhost
must behave like a top-level domain. For this purpose you must install and configure a domain name server on your laptop (which is typically not there).
Turn to http://passingcuriosity.com/2013/dnsmasq-dev-osx/ to install a local DNS-server on your Macbook.
Turn to ??? to install a local DNS-server on your Windows laptop.
Turn to https://support.microsoft.com/nl-nl/help/972034/how-to-reset-the-hosts-file-back-to-the-default for setting the hosts-file on your Windows laptop. (Don't do this if you are installing a domain name server)
Turn to https://www.techjunkie.com/edit-hosts-file-mac-os-x/ for setting the hosts-file on your Macbook. (Don't do this if you are installing a domain name server)
If you cannot get your laptop configured, you might test your application on a separate test-server that runs Linux.
This page explains how Ampersand images are built automatically
We followed docker's instruction for automated builds, to automate the workflow from committing to the Ampersand repository on Github to the corresponding docker image on Docker hub.
If you must do things on your own, you might want to reproduce parts of the builds.
The Dockerfile for the Ampersand compiler resides in the root of the Ampersand repository. So from the command line, if you are at the root of the Ampersand repository, you can call docker build .
to create the image. See this page for more details.
The package.yaml file for the Ampersand compiler resides in the root of the Ampersand repository. So from the command line, if you are at the root of the Ampersand repository, you can call stack install
to create the image. See this page for more details.