Getting Started on APPUiO Cloud with the Terminal using C++
This tutorial explains how to run applications written in the C++ 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 C++ 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 C++ programming language on APPUiO Cloud, we will use a small demo application using the Drogon 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 C++" 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-cpp
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 C++ programming language, located at src/main.cpp, courtesy of the Drogon Framework.
int main()
{
std::string hostname = execute_command("hostname");
std::string version = std::string(VERSION);
auto router = [=](const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
std::string fortune = execute_command("fortune");
int number = random_number();
std::string accept = req->getHeader("Accept");
if (accept == "application/json")
{
Json::Value json;
json["hostname"] = hostname;
json["message"] = fortune;
json["number"] = number;
json["version"] = version;
auto resp = HttpResponse::newHttpJsonResponse(json);
callback(resp);
return;
}
if (accept == "text/plain")
{
std::string result = respond_text(fortune.c_str(), number);
auto resp = HttpResponse::newHttpResponse();
resp->setBody(result);
resp->setContentTypeString("text/plain");
callback(resp);
return;
}
HttpViewData data;
data.insert("fortune", fortune);
data.insert("number", std::to_string(number));
data.insert("version", version);
data.insert("hostname", hostname);
auto resp = HttpResponse::newHttpViewResponse("fortune", data);
callback(resp);
};
app().registerHandler("/", router).addListener("0.0.0.0", PORT).run();
return EXIT_SUCCESS;
}
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-cpp:latest
Or with Podman:
podman run --rm --publish 8080:8080 registry.gitlab.com/vshn/applications/fortune-cpp: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:
# Step 2: Production image
FROM busybox:glibc
COPY --from=builder /builder/build/cpp-fortune /usr/local/bin/cpp-fortune
COPY --from=builder /usr/games/fortune /usr/local/bin/fortune
COPY --from=builder /usr/share/games/fortunes /usr/share/games/fortunes
COPY --from=builder /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so.2
COPY --from=builder /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1
COPY --from=builder /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/lib/x86_64-linux-gnu/libstdc++.so.6
COPY --from=builder /usr/lib/x86_64-linux-gnu/librecode.so.0 /usr/lib/x86_64-linux-gnu/librecode.so.0
EXPOSE 8080
(1)
USER 1001:0
CMD ["/usr/local/bin/cpp-fortune"]
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-cpp.git
cd
into it:
cd fortune-cpp
And build your image with Docker:
docker build -t fortune-cpp .
Or with Podman instead:
podman build -t fortune-cpp .
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-cpp"
oc new-project [YOUR_USERNAME]-fortune-cpp
-
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-cpp spec: template: spec: containers: - image: registry.gitlab.com/vshn/applications/fortune-cpp:latest imagePullPolicy: Always name: fortune-container ports: - containerPort: 8080 metadata: labels: app: fortune-cpp selector: matchLabels: app: fortune-cpp strategy: type: Recreate --- apiVersion: v1 kind: Service metadata: name: fortune-cpp spec: ports: - port: 8080 targetPort: 8080 selector: app: fortune-cpp 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-cpp-ingress spec: rules: - host: [YOUR_USERNAME]-fortune-cpp.apps.[YOUR_CHOSEN_ZONE].appuio.cloud (1) http: paths: - pathType: Prefix path: / backend: service: name: fortune-cpp port: number: 8080 tls: - hosts: - [YOUR_USERNAME]-fortune-cpp.apps.[YOUR_CHOSEN_ZONE].appuio.cloud secretName: fortune-cpp-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-cpp.apps.[YOUR_CHOSEN_ZONE].appuio.cloud --header "Accept: text/plain"
Or in JSON instead:
curl https://[YOUR_USERNAME]-fortune-cpp.apps.[YOUR_CHOSEN_ZONE].appuio.cloud --header "Accept: application/json"
Step 3: There’s no Step 3!
The "Fortune in C++" 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 C++ or using the Drogon 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-cpp
project with the following command:
oc delete project [YOUR_USERNAME]-fortune-cpp