Getting Started on APPUiO Cloud with the Terminal using D
This tutorial explains how to run applications written in the D programming language on APPUiO Cloud using the command line.
If you aren’t familiar with issuing commands on a terminal session, you might want to try the Getting Started with D on the OpenShift Web Console guide instead.
Requirements
To follow this guide, please make sure that you have the following tools installed:
oc
-
You can download the OpenShift command directly from APPUiO Cloud, selecting the help menu (marked as a question mark) and selecting the "Command line tools" entry.
docker
orpodman
-
You can download them from www.docker.com and podman.io.
curl
-
Available from curl.se.
About the Application
To demo how to run applications written in the D programming language on APPUiO Cloud, we will use a small demo application using the vibe.d Framework, bundled as a container thanks to its corresponding Dockerfile
, and ready to be used on APPUiO Cloud.
You can browse the full source code of this application on GitLab.
The "Fortune in D" application does a few simple things:
-
When invoked on the browser, it returns a random number and a funny quote.
-
When invoked with an HTTP request including the
Accept: application/json
header, it returns the same information in JSON format. -
Finally, when invoked with an HTTP request including the
Accept: text/plain
header, it returns the same information in plain text format.
Learn more about the fortune-d
application, including how to edit and build it, on the project README.
The Application Router
The code below shows the main router of the application in the D programming language, located at source/app.d, courtesy of the vibe.d Framework.
void fortune(HTTPServerRequest req, HTTPServerResponse res)
{
int number = uniform(1,1000);
string message = execute("fortune");
auto accept = req.headers["Accept"];
if (accept == "application/json")
{
Json fortune = Json.emptyObject;
fortune["message"] = message;
fortune["number"] = number;
fortune["hostname"] = hostname;
fortune["version"] = appVersion;
res.writeJsonBody(fortune);
return;
}
if (accept == "text/plain")
{
string str = format("Fortune %s cookie of the day #%d:\n\n%s", appVersion, number, message);
res.writeBody(str, "text/plain");
return;
}
Mustache mustache;
auto context = new Mustache.Context;
context["message"] = message;
context["number"] = number;
context["version"] = appVersion;
context["hostname"] = hostname;
res.writeBody(mustache.render("views/fortune", context), "text/html");
}
Run the Container
This step is optional; you can easily test the application locally with Docker:
docker run --rm --publish 8080:8080 registry.gitlab.com/vshn/applications/fortune-d:latest
Or with Podman:
podman run --rm --publish 8080:8080 registry.gitlab.com/vshn/applications/fortune-d:latest
Now you can test the application with curl
, for example to get some JSON:
curl http://localhost:8080 --header "Accept: application/json"
Or to see a plain text version:
curl http://localhost:8080 --header "Accept: text/plain"
You can also open a browser and navigate to localhost:8080 to get your fortune cookie of the day.
Dockerfile
The application includes a Dockerfile ready to build a container fully compatible with OpenShift. The snippet below shows the instructions used to build the actual running image:
FROM alpine:3.14
RUN apk update && apk add --no-cache fortune llvm-libunwind
WORKDIR /app
COPY --from=build /app/fortune-d /app/
COPY views /app/views
EXPOSE 8080
(1)
USER 1001:0
CMD ["/app/fortune-d"]
1 | This explicitly prevents the container from running as root; this is a requirement of OpenShift, and a good practice for images in general. |
You can use the Dockerfile
above to build your own copy of the container, which you can then push to the registry of your choice. Clone the repo:
git clone https://gitlab.com/vshn/applications/fortune-d.git
cd
into it:
cd fortune-d
And build your image with Docker:
docker build -t fortune-d .
Or with Podman instead:
podman build -t fortune-d .
Step 1: Create a Project
Follow these steps to login to APPUiO Cloud on your terminal:
-
Login to the APPUiO Cloud console:
oc login --server=https://api.${zone}.appuio.cloud:6443
You can find the exact URL of your chosen zone in the APPUiO Cloud Portal.
This command displays a URL on your terminal:
You must obtain an API token by visiting https://oauth-openshift.apps.${zone}.appuio.cloud/oauth/token/request
-
Click on the link above and open it in your browser.
-
Click "Display token" and copy the login command shown as "Log in with this token"
-
Paste the
oc login
command on the terminal:oc login --token=sha256~_xxxxxx_xxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx-X \ --server=https://api.${zone}.appuio.cloud:6443
-
Create a new project called "[YOUR_USERNAME]-fortune-d"
oc new-project [YOUR_USERNAME]-fortune-d
-
To deploy the application we will use a standard Kubernetes
Deployment
object. Save the following YAML in a file calleddeployment.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: fortune-d spec: template: spec: containers: - image: registry.gitlab.com/vshn/applications/fortune-d:latest imagePullPolicy: Always name: fortune-container ports: - containerPort: 8080 metadata: labels: app: fortune-d selector: matchLabels: app: fortune-d strategy: type: Recreate --- apiVersion: v1 kind: Service metadata: name: fortune-d spec: ports: - port: 8080 targetPort: 8080 selector: app: fortune-d type: ClusterIP
-
Then apply the deployment to your APPUiO Cloud project:
oc apply -f deployment.yaml
And wait until your pod appears with the status "Running":
oc get pods --watch
Step 2: Publish your Application
At the moment your container is running but it’s not available from the Internet. To be able to access our application, we must create an Ingress
object.
-
Create another file called
ingress.yaml
with the following contents, customizing the parts marked as[YOUR_USERNAME]
and[YOUR_CHOSEN_ZONE]
to your liking (and according to the Zones documentation page):apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: cert-manager.io/cluster-issuer: letsencrypt-production name: fortune-d-ingress spec: rules: - host: [YOUR_USERNAME]-fortune-d.apps.[YOUR_CHOSEN_ZONE].appuio.cloud (1) http: paths: - pathType: Prefix path: / backend: service: name: fortune-d port: number: 8080 tls: - hosts: - [YOUR_USERNAME]-fortune-d.apps.[YOUR_CHOSEN_ZONE].appuio.cloud secretName: fortune-d-cert
1 Replace the placeholders YOUR_USERNAME
andYOUR_CHOSEN_ZONE
with valid values.
About URL lengths
Make sure that the total length of the prefix string
If your Ingress doesn’t generate a route after deploying your application, shorten the URL in your YAML and redeploy. |
-
Apply the ingress object to your APPUiO Cloud project and wait until you route shows as available.
oc apply -f ingress.yaml
And wait for your route to be ready:
oc get routes --watch
-
After a few seconds, you should be able to get your daily fortune message using
curl
in plain text!curl https://[YOUR_USERNAME]-fortune-d.apps.[YOUR_CHOSEN_ZONE].appuio.cloud --header "Accept: text/plain"
Or in JSON instead:
curl https://[YOUR_USERNAME]-fortune-d.apps.[YOUR_CHOSEN_ZONE].appuio.cloud --header "Accept: application/json"
Step 3: There’s no Step 3!
The "Fortune in D" application is now running on APPUiO Cloud. Congratulations! Hit the R key in your keyboard to see a new fortune message, or just wait 10 seconds to get a new one automatically.
What’s next? To run your own application written in D or using the vibe.d Framework on APPUiO Cloud, follow these steps:
-
Containerize the application making sure it’s compatible with APPUiO Cloud. The
Dockerfile
above can serve as a starting point. -
Enhance the deployment for your application with liveness and health probes, or better yet, create a Helm chart.
-
Configure your CI/CD system to automatically deploy your application to your preferred APPUiO Cloud zone.
Finally, when you’re done testing the fortune application, delete the fortune-d
project with the following command:
oc delete project [YOUR_USERNAME]-fortune-d